14 for (TLoopStack::const_iterator
i = stack.begin();
i != stack.end(); ++
i) {
15 if (
i->index.id == symbol->
getId())
22 for (TLoopStack::iterator
i = stack.begin();
i != stack.end(); ++
i) {
23 if (
i->index.id == symbol->
getId()) {
25 i->loop->setUnrollFlag(
true);
43 ValidateConstIndexExpr(
const TLoopStack& stack)
44 : mValid(
true), mLoopStack(stack) {}
47 bool isValid()
const {
return mValid; }
54 IsLoopIndex(symbol, mLoopStack);
69 : mUsesFloatLoopIndex(
false),
70 mUsesIntLoopIndex(
false),
73 bool usesFloatLoopIndex()
const {
return mUsesFloatLoopIndex; }
74 bool usesIntLoopIndex()
const {
return mUsesIntLoopIndex; }
77 if (IsLoopIndex(symbol, mLoopStack)) {
80 mUsesFloatLoopIndex =
true;
83 mUsesIntLoopIndex =
true;
84 MarkLoopForUnroll(symbol, mLoopStack);
93 bool mUsesFloatLoopIndex;
94 bool mUsesIntLoopIndex;
101 : mShaderType(shaderType),
110 validateOperation(node, node->
getLeft());
113 switch (node->
getOp()) {
115 validateIndexing(node);
118 #if defined(__APPLE__)
127 ValidateLoopIndexExpr validate(mLoopStack);
129 if (validate.usesFloatLoopIndex()) {
131 "sampler array index is float loop index",
137 validateIndexing(node);
154 switch (node->
getOp()) {
156 validateFunctionCall(node);
166 if (!validateLoopType(node))
172 if (!validateForLoopHeader(node, &info))
177 mLoopStack.push_back(info);
179 mLoopStack.pop_back();
186 void ValidateLimitations::error(
TSourceLoc loc,
187 const char *reason,
const char* token)
191 mSink <<
"'" << token <<
"' : " << reason <<
"\n";
195 bool ValidateLimitations::withinLoopBody()
const
197 return !mLoopStack.empty();
200 bool ValidateLimitations::isLoopIndex(
const TIntermSymbol* symbol)
const
202 return IsLoopIndex(symbol, mLoopStack);
205 bool ValidateLimitations::validateLoopType(
TIntermLoop* node) {
212 "This type of loop is not allowed",
217 bool ValidateLimitations::validateForLoopHeader(
TIntermLoop* node,
226 if (!validateForLoopInit(node, info))
228 if (!validateForLoopCond(node, info))
230 if (!validateForLoopExpr(node, info))
236 bool ValidateLimitations::validateForLoopInit(
TIntermLoop* node,
241 error(node->
getLine(),
"Missing init declaration",
"for");
251 error(init->
getLine(),
"Invalid init declaration",
"for");
256 if (declSeq.size() != 1) {
257 error(decl->
getLine(),
"Invalid init declaration",
"for");
262 error(decl->
getLine(),
"Invalid init declaration",
"for");
266 if (symbol ==
NULL) {
267 error(declInit->
getLine(),
"Invalid init declaration",
"for");
278 if (!isConstExpr(declInit->
getRight())) {
280 "Loop index cannot be initialized with non-constant expression",
289 bool ValidateLimitations::validateForLoopCond(
TIntermLoop* node,
294 error(node->
getLine(),
"Missing condition",
"for");
303 error(node->
getLine(),
"Invalid condition",
"for");
308 if (symbol ==
NULL) {
309 error(binOp->
getLine(),
"Invalid condition",
"for");
314 "Expected loop index", symbol->
getSymbol().c_str());
318 switch (binOp->
getOp()) {
328 "Invalid relational operator",
333 if (!isConstExpr(binOp->
getRight())) {
335 "Loop index cannot be compared with non-constant expression",
343 bool ValidateLimitations::validateForLoopExpr(
TIntermLoop* node,
348 error(node->
getLine(),
"Missing expression",
"for");
369 }
else if (binOp !=
NULL) {
375 if (symbol ==
NULL) {
376 error(expr->
getLine(),
"Invalid expression",
"for");
381 "Expected loop index", symbol->
getSymbol().c_str());
404 if (!isConstExpr(binOp->
getRight())) {
406 "Loop index cannot be modified by non-constant expression",
420 if (!withinLoopBody())
424 typedef std::vector<size_t> ParamIndex;
429 if (symbol && isLoopIndex(symbol))
441 TFunction*
function =
static_cast<TFunction*
>(symbol);
442 for (ParamIndex::const_iterator
i = pIndex.begin();
443 i != pIndex.end(); ++
i) {
447 error(params[*
i]->getLine(),
448 "Loop index cannot be used as argument to a function out or inout parameter",
449 params[*
i]->getAsSymbolNode()->getSymbol().c_str());
464 if (symbol && isLoopIndex(symbol)) {
466 "Loop index cannot be statically assigned to within the body of the loop",
472 bool ValidateLimitations::isConstExpr(
TIntermNode* node)
478 bool ValidateLimitations::isConstIndexExpr(
TIntermNode* node)
482 ValidateConstIndexExpr validate(mLoopStack);
484 return validate.isValid();
487 bool ValidateLimitations::validateIndexing(
TIntermBinary* node)
497 "Index expression must have integral type",
506 if (!skip && !isConstIndexExpr(index)) {
507 error(index->
getLine(),
"Index expression must be constant",
"[]");
GLsizei GLenum GLboolean sink
TSymbolTable & symbolTable
TIntermSequence & getSequence()
TIntermTyped * getCondition()
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
TIntermTyped * getLeft() const
virtual bool visitUnary(Visit, TIntermUnary *)
virtual bool visitLoop(Visit, TIntermLoop *)
virtual TIntermAggregate * getAsAggregate()
bool IsSampler(TBasicType type)
TString getCompleteString() const
TIntermTyped * getRight() const
static void init(struct bs2b *bs2b)
TBasicType getBasicType() const
TParseContext * GetGlobalParseContext()
virtual TIntermBinary * getAsBinaryNode()
TQualifier getQualifier() const
virtual TIntermConstantUnion * getAsConstantUnion()
struct TLoopInfo::TIndex index
virtual bool visitBinary(Visit, TIntermBinary *)
#define ASSERT(expression)
TQualifier getQualifier() const
virtual void visitSymbol(TIntermSymbol *)
const char * getBasicString(TBasicType t)
virtual void traverse(TIntermTraverser *)=0
const TSourceLoc & getLine() const
virtual TIntermUnary * getAsUnaryNode()
const TString & getName() const
ValidateLimitations(ShShaderType shaderType, TInfoSinkBase &sink)
TIntermTyped * getOperand()
virtual bool isFunction() const
TIntermTyped * getExpression()
const TString & getSymbol() const
std::vector< TIntermNode *, pool_allocator< TIntermNode * > >::size_type size_type
bool modifiesState() const
virtual TIntermSymbol * getAsSymbolNode()
TSymbol * find(const TString &name, bool *builtIn=0, bool *sameScope=0)
void location(int file, int line)
void prefix(TPrefixType p)
virtual bool visitAggregate(Visit, TIntermAggregate *)
TLoopType getType() const