// // Initializers show up in several places in the grammar. Have one set of // code to handle them here. // bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable) { TType type = TType(pType); if (variable == 0) { if (reservedErrorCheck(line, identifier)) return true; if (voidErrorCheck(line, identifier, pType)) return true; // // add variable to symbol table // variable = new TVariable(&identifier, type); if (! symbolTable.insert(*variable)) { error(line, "redefinition", variable->getName().c_str(), ""); return true; // don't delete variable, it's used by error recovery, and the pool // pop will take care of the memory } } // // identifier must be of type constant, a global, or a temporary // TQualifier qualifier = variable->getType().getQualifier(); if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) { error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString(), ""); return true; } // // test for and propagate constant // if (qualifier == EvqConst) { if (qualifier != initializer->getType().getQualifier()) { error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str()); variable->getType().setQualifier(EvqTemporary); return true; } if (type != initializer->getType()) { error(line, " non-matching types for const initializer ", variable->getType().getQualifierString(), ""); variable->getType().setQualifier(EvqTemporary); return true; } if (initializer->getAsConstantUnion()) { ConstantUnion* unionArray = variable->getConstPointer(); if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) { *unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0]; } else { variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer()); } } else if (initializer->getAsSymbolNode()) { const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol()); const TVariable* tVar = static_cast<const TVariable*>(symbol); ConstantUnion* constArray = tVar->getConstPointer(); variable->shareConstPointer(constArray); } else { error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str()); variable->getType().setQualifier(EvqTemporary); return true; } } if (qualifier != EvqConst) { TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line); intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line); if (intermNode == 0) { assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); return true; } } else intermNode = 0; return false; }