MCPcopy Create free account
hub / github.com/KhronosGroup/glslang / inductiveLoopCheck

Method inductiveLoopCheck

glslang/MachineIndependent/ParseHelper.cpp:6511–6608  ·  view source on GitHub ↗

See if this loop satisfies the limitations for ES 2.0 (version 100) for loops in Appendex A: "The loop index has type int or float. "The for statement has the form: for ( init-declaration ; condition ; expression ) init-declaration has the form: type-specifier identifier = constant-expression condition has the form: loop-index relational_operator constant-expression where relational_operator is

Source from the content-addressed store, hash-verified

6509// The body is handled in an AST traversal.
6510//
6511void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, TIntermLoop* loop)
6512{
6513 // loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration
6514 bool badInit = false;
6515 if (! init || ! init->getAsAggregate() || init->getAsAggregate()->getSequence().size() != 1)
6516 badInit = true;
6517 TIntermBinary* binaryInit = nullptr;
6518 if (! badInit) {
6519 // get the declaration assignment
6520 binaryInit = init->getAsAggregate()->getSequence()[0]->getAsBinaryNode();
6521 if (! binaryInit)
6522 badInit = true;
6523 }
6524 if (badInit) {
6525 error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", "");
6526 return;
6527 }
6528
6529 // loop index must be type int or float
6530 if (! binaryInit->getType().isScalar() || (binaryInit->getBasicType() != EbtInt && binaryInit->getBasicType() != EbtFloat)) {
6531 error(loc, "inductive loop requires a scalar 'int' or 'float' loop index", "limitations", "");
6532 return;
6533 }
6534
6535 // init is the form "loop-index = constant"
6536 if (binaryInit->getOp() != EOpAssign || ! binaryInit->getLeft()->getAsSymbolNode() || ! binaryInit->getRight()->getAsConstantUnion()) {
6537 error(loc, "inductive-loop init-declaration requires the form \"type-specifier loop-index = constant-expression\"", "limitations", "");
6538 return;
6539 }
6540
6541 // get the unique id of the loop index
6542 long long loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId();
6543 inductiveLoopIds.insert(loopIndex);
6544
6545 // condition's form must be "loop-index relational-operator constant-expression"
6546 bool badCond = ! loop->getTestExpr();
6547 if (! badCond) {
6548 TIntermBinary* binaryCond = loop->getTestExpr()->getAsBinaryNode();
6549 badCond = ! binaryCond;
6550 if (! badCond) {
6551 switch (binaryCond->getOp()) {
6552 case EOpGreaterThan:
6553 case EOpGreaterThanEqual:
6554 case EOpLessThan:
6555 case EOpLessThanEqual:
6556 case EOpEqual:
6557 case EOpNotEqual:
6558 break;
6559 default:
6560 badCond = true;
6561 }
6562 }
6563 if (binaryCond && (! binaryCond->getLeft()->getAsSymbolNode() ||
6564 binaryCond->getLeft()->getAsSymbolNode()->getId() != loopIndex ||
6565 ! binaryCond->getRight()->getAsConstantUnion()))
6566 badCond = true;
6567 }
6568 if (badCond) {

Callers 1

yyparseFunction · 0.80

Calls 15

errorFunction · 0.85
getTypeMethod · 0.80
getOpMethod · 0.80
getLeftMethod · 0.80
getRightMethod · 0.80
getTestExprMethod · 0.80
getTerminalMethod · 0.80
getOperandMethod · 0.80
getAsAggregateMethod · 0.45
sizeMethod · 0.45
getAsBinaryNodeMethod · 0.45
isScalarMethod · 0.45

Tested by

no test coverage detected