bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line) { bool builtIn = false; TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn); if (symbol == 0) { error(line, " undeclared identifier", node->getSymbol().c_str(), ""); return true; } TVariable* variable = static_cast<TVariable*>(symbol); type->setArrayInformationType(variable->getArrayInformationType()); variable->updateArrayInformationType(type); // special casing to test index value of gl_FragData. If the accessed index is >= gl_MaxDrawBuffers // its an error if (node->getSymbol() == "gl_FragData") { TSymbol* fragData = symbolTable.find("gl_MaxDrawBuffers", &builtIn); if (fragData == 0) { infoSink.info.message(EPrefixInternalError, "gl_MaxDrawBuffers not defined", line); return true; } int fragDataValue = static_cast<TVariable*>(fragData)->getConstPointer()[0].getIConst(); if (fragDataValue <= size) { error(line, "", "[", "gl_FragData can only have a max array size of up to gl_MaxDrawBuffers", ""); return true; } } // we dont want to update the maxArraySize when this flag is not set, we just want to include this // node type in the chain of node types so that its updated when a higher maxArraySize comes in. if (!updateFlag) return false; size++; variable->getType().setMaxArraySize(size); type->setMaxArraySize(size); TType* tt = type; while(tt->getArrayInformationType() != 0) { tt = tt->getArrayInformationType(); tt->setMaxArraySize(size); } return false; }
// // Do all the semantic checking for declaring an array, with and // without a size, and make the right changes to the symbol table. // // size == 0 means no specified size. // // Returns true if there was an error. // bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable) { // // Don't check for reserved word use until after we know it's not in the symbol table, // because reserved arrays can be redeclared. // bool builtIn = false; bool sameScope = false; TSymbol* symbol = symbolTable.find(identifier, &builtIn, &sameScope); if (symbol == 0 || !sameScope) { if (reservedErrorCheck(line, identifier)) return true; variable = new TVariable(&identifier, TType(type)); if (type.arraySize) variable->getType().setArraySize(type.arraySize); if (! symbolTable.insert(*variable)) { delete variable; error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str(), ""); return true; } } else { if (! symbol->isVariable()) { error(line, "variable expected", identifier.c_str(), ""); return true; } variable = static_cast<TVariable*>(symbol); if (! variable->getType().isArray()) { error(line, "redeclaring non-array as array", identifier.c_str(), ""); return true; } if (variable->getType().getArraySize() > 0) { error(line, "redeclaration of array with size", identifier.c_str(), ""); return true; } if (! variable->getType().sameElementType(TType(type))) { error(line, "redeclaration of array with a different type", identifier.c_str(), ""); return true; } TType* t = variable->getArrayInformationType(); while (t != 0) { if (t->getMaxArraySize() > type.arraySize) { error(line, "higher index value already used for the array", identifier.c_str(), ""); return true; } t->setArraySize(type.arraySize); t = t->getArrayInformationType(); } if (type.arraySize) variable->getType().setArraySize(type.arraySize); } if (voidErrorCheck(line, identifier, type)) return true; return false; }