Unify the 8 grammar productions for declaring variables. This greatly simplifies making changes for this set of productions.
This change also naturally picks up redeclarations of built-in arrays and the addition of the remaining linker objects of const, arrays, etc. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23246 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
337dbc7d8c
commit
9839e2440e
45 changed files with 505 additions and 243 deletions
|
|
@ -644,7 +644,8 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
|
|||
TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc loc)
|
||||
{
|
||||
TIntermAggregate* aggNode = growAggregate(left, right);
|
||||
aggNode->setLoc(loc);
|
||||
if (aggNode)
|
||||
aggNode->setLoc(loc);
|
||||
|
||||
return aggNode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1325,13 +1325,13 @@ bool TParseContext::constructorError(TSourceLoc loc, TIntermNode* node, TFunctio
|
|||
return false;
|
||||
}
|
||||
|
||||
// This function checks to see if a void variable has been declared and raise an error message for such a case
|
||||
// Checks to see if a void variable has been declared and raise an error message for such a case
|
||||
//
|
||||
// returns true in case of an error
|
||||
//
|
||||
bool TParseContext::voidErrorCheck(TSourceLoc loc, const TString& identifier, const TPublicType& pubType)
|
||||
bool TParseContext::voidErrorCheck(TSourceLoc loc, const TString& identifier, const TBasicType basicType)
|
||||
{
|
||||
if (pubType.basicType == EbtVoid) {
|
||||
if (basicType == EbtVoid) {
|
||||
error(loc, "illegal use of type 'void'", identifier.c_str(), "");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1646,12 +1646,12 @@ void TParseContext::arraySizeCheck(TSourceLoc loc, TIntermTyped* expr, int& size
|
|||
//
|
||||
// Returns true if there is an error.
|
||||
//
|
||||
bool TParseContext::arrayQualifierError(TSourceLoc loc, const TPublicType& type)
|
||||
bool TParseContext::arrayQualifierError(TSourceLoc loc, const TQualifier& qualifier)
|
||||
{
|
||||
if (type.qualifier.storage == EvqConst)
|
||||
if (qualifier.storage == EvqConst)
|
||||
profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", "const array");
|
||||
|
||||
if (type.qualifier.storage == EvqVaryingIn && language == EShLangVertex) {
|
||||
if (qualifier.storage == EvqVaryingIn && language == EShLangVertex) {
|
||||
requireProfile(loc, (EProfileMask)~EEsProfileMask, "vertex input arrays");
|
||||
profileRequires(loc, ENoProfile, 150, 0, "vertex input arrays");
|
||||
}
|
||||
|
|
@ -1698,7 +1698,7 @@ void TParseContext::arrayDimCheck(TSourceLoc loc, const TType* type, TArraySizes
|
|||
//
|
||||
// size == 0 means no specified size.
|
||||
//
|
||||
void TParseContext::arrayCheck(TSourceLoc loc, TString& identifier, const TPublicType& type, TVariable*& variable)
|
||||
void TParseContext::declareArray(TSourceLoc loc, TString& identifier, const TType& type, TVariable*& variable, bool& newDeclaration)
|
||||
{
|
||||
//
|
||||
// Don't check for reserved word use until after we know it's not in the symbol table,
|
||||
|
|
@ -1710,46 +1710,39 @@ void TParseContext::arrayCheck(TSourceLoc loc, TString& identifier, const TPubli
|
|||
// Redeclarations have to take place at the same scope; otherwise they are hiding declarations
|
||||
//
|
||||
|
||||
bool currentScope;
|
||||
TSymbol* symbol = symbolTable.find(identifier, 0, ¤tScope);
|
||||
if (symbol == 0 || ! currentScope) {
|
||||
if (reservedErrorCheck(loc, identifier))
|
||||
return;
|
||||
if (! variable) {
|
||||
bool currentScope;
|
||||
TSymbol* symbol = symbolTable.find(identifier, 0, ¤tScope);
|
||||
if (symbol == 0 || ! currentScope) {
|
||||
variable = new TVariable(&identifier, type);
|
||||
symbolTable.insert(*variable);
|
||||
newDeclaration = true;
|
||||
|
||||
variable = new TVariable(&identifier, TType(type));
|
||||
symbolTable.insert(*variable);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
variable = symbol->getAsVariable();
|
||||
}
|
||||
|
||||
if (! variable) {
|
||||
error(loc, "array variable name expected", identifier.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (! variable) {
|
||||
error(loc, "array variable name expected", identifier.c_str(), "");
|
||||
return;
|
||||
}
|
||||
|
||||
if (! variable->getType().isArray()) {
|
||||
error(loc, "redeclaring non-array as array", identifier.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (variable->getType().getArraySize() > 0) {
|
||||
error(loc, "redeclaration of array with size", identifier.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (! variable->getType().isArray()) {
|
||||
error(loc, "redeclaring non-array as array", identifier.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (variable->getType().getArraySize() > 0) {
|
||||
error(loc, "redeclaration of array with size", identifier.c_str(), "");
|
||||
return;
|
||||
}
|
||||
|
||||
if (! variable->getType().sameElementType(TType(type))) {
|
||||
error(loc, "redeclaration of array with a different type", identifier.c_str(), "");
|
||||
return;
|
||||
}
|
||||
|
||||
// For read-only built-ins, add a new variable for holding the declared array size of an implicitly-sized shared array.
|
||||
if (variable->isReadOnly())
|
||||
variable = symbolTable.copyUp(variable);
|
||||
|
||||
// TODO: desktop unsized arrays: include modified built-in arrays (gl_TexCoord) in the linker objects subtree
|
||||
|
||||
variable->getWritableType().setArraySizes(type.arraySizes);
|
||||
}
|
||||
|
||||
voidErrorCheck(loc, identifier, type);
|
||||
if (! variable->getType().sameElementType(type)) {
|
||||
error(loc, "redeclaration of array with a different type", identifier.c_str(), "");
|
||||
return;
|
||||
}
|
||||
|
||||
variable->getWritableType().setArraySizes(type);
|
||||
}
|
||||
|
||||
bool TParseContext::arraySetMaxSize(TSourceLoc loc, TIntermSymbol *node, int size)
|
||||
|
|
@ -1793,55 +1786,31 @@ bool TParseContext::arraySetMaxSize(TSourceLoc loc, TIntermSymbol *node, int siz
|
|||
//
|
||||
// Enforce non-initializer type/qualifier rules.
|
||||
//
|
||||
void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TPublicType& type)
|
||||
void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TType& type)
|
||||
{
|
||||
//
|
||||
// Make the qualifier make sense.
|
||||
//
|
||||
if (type.qualifier.storage == EvqConst) {
|
||||
type.qualifier.storage = EvqTemporary;
|
||||
if (type.getQualifier().storage == EvqConst) {
|
||||
type.getQualifier().storage = EvqTemporary;
|
||||
error(loc, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Do semantic checking for a variable declaration that has no initializer,
|
||||
// and update the symbol table.
|
||||
// See if the identifier is a built-in symbol that can be redeclared, and if so,
|
||||
// copy the symbol table's read-only built-in variable to the current
|
||||
// global level, where it can be modified based on the passed in type.
|
||||
//
|
||||
void TParseContext::nonInitCheck(TSourceLoc loc, TString& identifier, TPublicType& publicType)
|
||||
// Returns 0 if no redeclaration took place; meaning a normal declaration still
|
||||
// needs to occur for it, not necessarily an error.
|
||||
//
|
||||
// Returns a redeclared and type-modified variable if a redeclarated occurred.
|
||||
//
|
||||
// Will emit
|
||||
//
|
||||
TVariable* TParseContext::redeclareBuiltin(TSourceLoc loc, const TString& identifier, const TType& type, bool& newDeclaration)
|
||||
{
|
||||
TType type(publicType);
|
||||
|
||||
bool newDeclaration; // true if a new entry gets added to the symbol table
|
||||
TVariable* variable = redeclare(loc, identifier, type, newDeclaration);
|
||||
|
||||
if (! variable) {
|
||||
reservedErrorCheck(loc, identifier);
|
||||
variable = new TVariable(&identifier, type);
|
||||
if (! symbolTable.insert(*variable))
|
||||
error(loc, "redefinition", variable->getName().c_str(), "");
|
||||
else
|
||||
newDeclaration = true;
|
||||
}
|
||||
|
||||
if (newDeclaration) {
|
||||
voidErrorCheck(loc, identifier, publicType);
|
||||
|
||||
// see if it's a linker-level object to track
|
||||
if (type.getQualifier().isUniform() || type.getQualifier().isPipeInput() || type.getQualifier().isPipeOutput() || type.getQualifier().storage == EvqGlobal)
|
||||
intermediate.addSymbolLinkageNode(linkage, *variable);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// See if the identifier is a built-in symbol that can be redeclared,
|
||||
// and if so, copy of the symbol table's read-only built-in to the current
|
||||
// global level, so it can be modified.
|
||||
//
|
||||
TVariable* TParseContext::redeclare(TSourceLoc loc, const TString& identifier, const TType& type, bool& newDeclaration)
|
||||
{
|
||||
newDeclaration = false; // true if a new entry gets added to the symbol table
|
||||
|
||||
if (profile == EEsProfile || identifier.substr(0, 3) != TString("gl_") || symbolTable.atBuiltInLevel())
|
||||
return 0;
|
||||
|
||||
|
|
@ -1864,24 +1833,28 @@ TVariable* TParseContext::redeclare(TSourceLoc loc, const TString& identifier, c
|
|||
bool builtIn;
|
||||
TSymbol* symbol = symbolTable.find(identifier, &builtIn);
|
||||
|
||||
// If the symbol was not found, this must be a version/profile/stage
|
||||
// If the symbol was not found, this must be a version/profile/stage
|
||||
// that doesn't have it.
|
||||
if (! symbol)
|
||||
return 0;
|
||||
|
||||
TVariable* variable = symbol->getAsVariable();
|
||||
|
||||
// If it wasn't at a built-in level, then it's already been redeclared
|
||||
if (! builtIn)
|
||||
return variable;
|
||||
// If it wasn't at a built-in level, then it's already been redeclared;
|
||||
// that is, this is a redeclaration of a redeclaration, reuse that initial
|
||||
// redeclaration. Otherwise, make the new one.
|
||||
if (builtIn) {
|
||||
// Copy the symbol up to make a writable version
|
||||
newDeclaration = true;
|
||||
variable = symbolTable.copyUp(variable);
|
||||
}
|
||||
|
||||
// Otherwise, time to copy the symbol up to make a writable version
|
||||
newDeclaration = true;
|
||||
variable = symbolTable.copyUp(variable);
|
||||
// Now, modify the type of the copy, as per the type of the current redeclaration.
|
||||
// TODO: functionality: verify type change is allowed and make the change in type
|
||||
|
||||
return variable;
|
||||
}
|
||||
|
||||
error(loc, "cannot redeclare this built-in variable", identifier.c_str(), "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2013,44 +1986,102 @@ const TFunction* TParseContext::findFunction(TSourceLoc loc, TFunction* call, bo
|
|||
}
|
||||
|
||||
//
|
||||
// Handle all types of initializers from the grammar.
|
||||
// Do everything necessary to handle a variable (non-block) declaration.
|
||||
// Either redeclaring a variable, or making a new one, updating the symbol
|
||||
// table, and all error checking.
|
||||
//
|
||||
bool TParseContext::executeInitializerError(TSourceLoc loc, TString& identifier, TPublicType& pType,
|
||||
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
|
||||
// Returns a subtree node that computes an initializer, if needed.
|
||||
// Returns 0 if there is no code to execute for initialization.
|
||||
//
|
||||
TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier, TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer)
|
||||
{
|
||||
TType type(pType);
|
||||
TType type(publicType);
|
||||
|
||||
if (variable == 0) {
|
||||
if (reservedErrorCheck(loc, identifier))
|
||||
return true;
|
||||
if (voidErrorCheck(loc, identifier, type.getBasicType()))
|
||||
return 0;
|
||||
|
||||
if (voidErrorCheck(loc, identifier, pType))
|
||||
return true;
|
||||
if (! initializer)
|
||||
nonInitConstCheck(loc, identifier, type);
|
||||
|
||||
//
|
||||
// add variable to symbol table
|
||||
//
|
||||
variable = new TVariable(&identifier, type);
|
||||
if (! symbolTable.insert(*variable)) {
|
||||
error(loc, "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
|
||||
// Check for redeclaration of built-ins and/or attempting to declare a reserved name
|
||||
bool newDeclaration = false; // true if a new entry gets added to the symbol table
|
||||
TVariable* variable = redeclareBuiltin(loc, identifier, type, newDeclaration);
|
||||
if (! variable)
|
||||
reservedErrorCheck(loc, identifier);
|
||||
|
||||
// Declare the variable
|
||||
if (arraySizes) {
|
||||
// for ES, since size isn't coming from an initializer, it has to be explicitly declared now
|
||||
if (profile == EEsProfile && ! initializer)
|
||||
arraySizeRequiredCheck(loc, arraySizes->getSize());
|
||||
|
||||
arrayDimCheck(loc, &type, arraySizes);
|
||||
if (! arrayQualifierError(loc, type.getQualifier())) {
|
||||
type.setArraySizes(arraySizes);
|
||||
declareArray(loc, identifier, type, variable, newDeclaration);
|
||||
}
|
||||
|
||||
if (initializer)
|
||||
profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", "initializer");
|
||||
} else {
|
||||
// non-array case
|
||||
if (! variable)
|
||||
variable = declareNonArray(loc, identifier, type, newDeclaration);
|
||||
}
|
||||
|
||||
// Deal with initializer
|
||||
TIntermNode* initNode = 0;
|
||||
if (variable && initializer)
|
||||
initNode = executeInitializer(loc, identifier, type, initializer, variable);
|
||||
|
||||
// see if it's a linker-level object to track
|
||||
if (newDeclaration && symbolTable.atGlobalLevel())
|
||||
intermediate.addSymbolLinkageNode(linkage, *variable);
|
||||
|
||||
return initNode;
|
||||
}
|
||||
|
||||
//
|
||||
// Declare a non-array variable, the main point being there is no redeclaration
|
||||
// for resizing allowed.
|
||||
//
|
||||
// Return the successfully declared variable.
|
||||
//
|
||||
TVariable* TParseContext::declareNonArray(TSourceLoc loc, TString& identifier, TType& type, bool& newDeclaration)
|
||||
{
|
||||
// make a new variable
|
||||
TVariable* variable = new TVariable(&identifier, type);
|
||||
|
||||
// add variable to symbol table
|
||||
if (! symbolTable.insert(*variable)) {
|
||||
error(loc, "redefinition", variable->getName().c_str(), "");
|
||||
return 0;
|
||||
} else {
|
||||
newDeclaration = true;
|
||||
return variable;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handle all types of initializers from the grammar.
|
||||
//
|
||||
TIntermNode* TParseContext::executeInitializer(TSourceLoc loc, TString& identifier, TType& type,
|
||||
TIntermTyped* initializer, TVariable* variable)
|
||||
{
|
||||
//
|
||||
// identifier must be of type constant, a global, or a temporary
|
||||
// Identifier must be of type constant, a global, or a temporary, and
|
||||
// starting at version 120, desktop allows uniforms to have initializers.
|
||||
//
|
||||
TStorageQualifier qualifier = variable->getType().getQualifier().storage;
|
||||
if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) {
|
||||
if (! (qualifier == EvqTemporary || qualifier == EvqGlobal || qualifier == EvqConst ||
|
||||
qualifier == EvqUniform && profile != EEsProfile && version >= 120)) {
|
||||
error(loc, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), "");
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Fix arrayness if variable is unsized, getting size for initializer
|
||||
if (initializer->getType().isArray() && initializer->getType().getArraySize() > 0 &&
|
||||
type.isArray() && type.getArraySize() == 0)
|
||||
type.isArray() && type.getArraySize() == 0)
|
||||
type.changeArraySize(initializer->getType().getArraySize());
|
||||
|
||||
//
|
||||
|
|
@ -2060,13 +2091,13 @@ bool TParseContext::executeInitializerError(TSourceLoc loc, TString& identifier,
|
|||
if (qualifier != initializer->getType().getQualifier().storage) {
|
||||
error(loc, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
|
||||
variable->getWritableType().getQualifier().storage = EvqTemporary;
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
if (type != initializer->getType()) {
|
||||
error(loc, " non-matching types for const initializer ",
|
||||
variable->getType().getStorageQualifierString(), "");
|
||||
variable->getWritableType().getQualifier().storage = EvqTemporary;
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
if (initializer->getAsConstantUnion()) {
|
||||
TConstUnion* unionArray = variable->getConstUnionPointer();
|
||||
|
|
@ -2083,26 +2114,25 @@ bool TParseContext::executeInitializerError(TSourceLoc loc, TString& identifier,
|
|||
variable->shareConstPointer(constArray);
|
||||
} else {
|
||||
error(loc, "expected variable", initializer->getAsSymbolNode()->getName().c_str(), "");
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
error(loc, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str());
|
||||
variable->getWritableType().getQualifier().storage = EvqTemporary;
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (qualifier != EvqConst) {
|
||||
TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc);
|
||||
intermNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc);
|
||||
if (intermNode == 0) {
|
||||
TIntermNode* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc);
|
||||
if (! initNode)
|
||||
assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
|
||||
return true;
|
||||
}
|
||||
} else
|
||||
intermNode = 0;
|
||||
|
||||
return false;
|
||||
return initNode;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This function is used to test for the correctness of the parameters passed to various constructor functions
|
||||
|
|
|
|||
|
|
@ -100,13 +100,12 @@ public:
|
|||
void globalCheck(TSourceLoc, bool global, const char* token);
|
||||
bool constructorError(TSourceLoc, TIntermNode*, TFunction&, TOperator, TType&);
|
||||
void arraySizeCheck(TSourceLoc, TIntermTyped* expr, int& size);
|
||||
bool arrayQualifierError(TSourceLoc, const TPublicType&);
|
||||
bool arrayQualifierError(TSourceLoc, const TQualifier&);
|
||||
void arraySizeRequiredCheck(TSourceLoc, int size);
|
||||
void arrayDimError(TSourceLoc);
|
||||
void arrayDimCheck(TSourceLoc, TArraySizes* sizes1, TArraySizes* sizes2);
|
||||
void arrayDimCheck(TSourceLoc, const TType*, TArraySizes*);
|
||||
void arrayCheck(TSourceLoc, TString& identifier, const TPublicType&, TVariable*& variable);
|
||||
bool voidErrorCheck(TSourceLoc, const TString&, const TPublicType&);
|
||||
bool voidErrorCheck(TSourceLoc, const TString&, TBasicType);
|
||||
void boolCheck(TSourceLoc, const TIntermTyped*);
|
||||
void boolCheck(TSourceLoc, const TPublicType&);
|
||||
bool samplerErrorCheck(TSourceLoc, const TPublicType& pType, const char* reason);
|
||||
|
|
@ -119,9 +118,7 @@ public:
|
|||
void precisionQualifierCheck(TSourceLoc, TPublicType&);
|
||||
void parameterSamplerCheck(TSourceLoc, TStorageQualifier qualifier, const TType& type);
|
||||
bool containsSampler(const TType& type);
|
||||
void nonInitConstCheck(TSourceLoc, TString& identifier, TPublicType& type);
|
||||
void nonInitCheck(TSourceLoc, TString& identifier, TPublicType& type);
|
||||
TVariable* redeclare(TSourceLoc, const TString&, const TType&, bool& newDeclaration);
|
||||
TVariable* redeclareBuiltin(TSourceLoc, const TString&, const TType&, bool& newDeclaration);
|
||||
void paramCheck(TSourceLoc, TStorageQualifier qualifier, TType* type);
|
||||
void nestedBlockCheck(TSourceLoc);
|
||||
void nestedStructCheck(TSourceLoc);
|
||||
|
|
@ -131,8 +128,7 @@ public:
|
|||
void mergeLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src);
|
||||
|
||||
const TFunction* findFunction(TSourceLoc, TFunction* pfnCall, bool *builtIn = 0);
|
||||
bool executeInitializerError(TSourceLoc, TString& identifier, TPublicType& pType,
|
||||
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
|
||||
TIntermNode* declareVariable(TSourceLoc, TString& identifier, TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
|
||||
TIntermTyped* addConstructor(TIntermNode*, const TType&, TOperator, TFunction*, TSourceLoc);
|
||||
TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
|
||||
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset);
|
||||
|
|
@ -170,6 +166,11 @@ public:
|
|||
protected:
|
||||
const char* getPreamble();
|
||||
TBehavior getExtensionBehavior(const char* behavior);
|
||||
void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type);
|
||||
TVariable* TParseContext::declareNonArray(TSourceLoc, TString& identifier, TType&, bool& newDeclaration);
|
||||
void declareArray(TSourceLoc, TString& identifier, const TType&, TVariable*&, bool& newDeclaration);
|
||||
TIntermNode* executeInitializer(TSourceLoc, TString& identifier, TType&, TIntermTyped* initializer, TVariable* variable);
|
||||
|
||||
|
||||
public:
|
||||
//
|
||||
|
|
|
|||
|
|
@ -972,61 +972,21 @@ init_declarator_list
|
|||
}
|
||||
| init_declarator_list COMMA IDENTIFIER {
|
||||
$$ = $1;
|
||||
parseContext.nonInitConstCheck($3.loc, *$3.string, $$.type);
|
||||
parseContext.nonInitCheck($3.loc, *$3.string, $$.type);
|
||||
parseContext.declareVariable($3.loc, *$3.string, $1.type);
|
||||
}
|
||||
| init_declarator_list COMMA IDENTIFIER array_specifier {
|
||||
parseContext.nonInitConstCheck($3.loc, *$3.string, $1.type);
|
||||
if (parseContext.profile == EEsProfile)
|
||||
parseContext.arraySizeRequiredCheck($4.loc, $4.arraySizes->getSize());
|
||||
parseContext.arrayDimCheck($3.loc, $1.type.arraySizes, $4.arraySizes);
|
||||
|
||||
$$ = $1;
|
||||
|
||||
if (! parseContext.arrayQualifierError($4.loc, $1.type)) {
|
||||
$1.type.arraySizes = $4.arraySizes;
|
||||
TVariable* variable;
|
||||
parseContext.arrayCheck($4.loc, *$3.string, $1.type, variable);
|
||||
}
|
||||
parseContext.declareVariable($3.loc, *$3.string, $1.type, $4.arraySizes);
|
||||
}
|
||||
| init_declarator_list COMMA IDENTIFIER array_specifier EQUAL initializer {
|
||||
$$ = $1;
|
||||
|
||||
TVariable* variable = 0;
|
||||
if (! parseContext.arrayQualifierError($4.loc, $1.type)) {
|
||||
$1.type.arraySizes = $4.arraySizes;
|
||||
parseContext.arrayCheck($4.loc, *$3.string, $1.type, variable);
|
||||
}
|
||||
parseContext.arrayDimCheck($3.loc, $1.type.arraySizes, $4.arraySizes);
|
||||
|
||||
parseContext.profileRequires($5.loc, ENoProfile, 120, "GL_3DL_array_objects", "initializer");
|
||||
|
||||
TIntermNode* intermNode;
|
||||
if (! parseContext.executeInitializerError($3.loc, *$3.string, $1.type, $6, intermNode, variable)) {
|
||||
//
|
||||
// build the intermediate representation
|
||||
//
|
||||
if (intermNode)
|
||||
$$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $5.loc);
|
||||
else
|
||||
$$.intermAggregate = $1.intermAggregate;
|
||||
} else
|
||||
$$.intermAggregate = 0;
|
||||
$$.type = $1.type;
|
||||
TIntermNode* initNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, $4.arraySizes, $6);
|
||||
$$.intermAggregate = parseContext.intermediate.growAggregate($1.intermAggregate, initNode, $5.loc);
|
||||
}
|
||||
| init_declarator_list COMMA IDENTIFIER EQUAL initializer {
|
||||
$$ = $1;
|
||||
|
||||
TIntermNode* intermNode;
|
||||
if (!parseContext.executeInitializerError($3.loc, *$3.string, $1.type, $5, intermNode)) {
|
||||
//
|
||||
// build the intermediate representation
|
||||
//
|
||||
if (intermNode)
|
||||
$$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $4.loc);
|
||||
else
|
||||
$$.intermAggregate = $1.intermAggregate;
|
||||
} else
|
||||
$$.intermAggregate = 0;
|
||||
$$.type = $1.type;
|
||||
TIntermNode* initNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, 0, $5);
|
||||
$$.intermAggregate = parseContext.intermediate.growAggregate($1.intermAggregate, initNode, $4.loc);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -1037,70 +997,26 @@ single_declaration
|
|||
parseContext.updateTypedDefaults($1.loc, $$.type.qualifier, 0);
|
||||
}
|
||||
| fully_specified_type IDENTIFIER {
|
||||
$$.intermAggregate = 0;
|
||||
$$.type = $1;
|
||||
|
||||
parseContext.nonInitConstCheck($2.loc, *$2.string, $$.type);
|
||||
parseContext.nonInitCheck($2.loc, *$2.string, $$.type);
|
||||
|
||||
$$.intermAggregate = 0;
|
||||
parseContext.declareVariable($2.loc, *$2.string, $1);
|
||||
parseContext.updateTypedDefaults($2.loc, $$.type.qualifier, $2.string);
|
||||
}
|
||||
| fully_specified_type IDENTIFIER array_specifier {
|
||||
$$.intermAggregate = 0;
|
||||
parseContext.nonInitConstCheck($2.loc, *$2.string, $1);
|
||||
if (parseContext.profile == EEsProfile)
|
||||
parseContext.arraySizeRequiredCheck($3.loc, $3.arraySizes->getSize());
|
||||
parseContext.arrayDimCheck($2.loc, $1.arraySizes, $3.arraySizes);
|
||||
|
||||
$$.type = $1;
|
||||
|
||||
if (! parseContext.arrayQualifierError($3.loc, $1)) {
|
||||
$1.arraySizes = $3.arraySizes;
|
||||
TVariable* variable;
|
||||
parseContext.arrayCheck($3.loc, *$2.string, $1, variable);
|
||||
}
|
||||
$$.intermAggregate = 0;
|
||||
parseContext.declareVariable($2.loc, *$2.string, $1, $3.arraySizes);
|
||||
parseContext.updateTypedDefaults($2.loc, $$.type.qualifier, $2.string);
|
||||
}
|
||||
| fully_specified_type IDENTIFIER array_specifier EQUAL initializer {
|
||||
parseContext.arrayDimCheck($3.loc, $1.arraySizes, $3.arraySizes);
|
||||
|
||||
$$.intermAggregate = 0;
|
||||
| fully_specified_type IDENTIFIER array_specifier EQUAL initializer {
|
||||
$$.type = $1;
|
||||
|
||||
TVariable* variable = 0;
|
||||
if (! parseContext.arrayQualifierError($3.loc, $1)) {
|
||||
$1.arraySizes = $3.arraySizes;
|
||||
parseContext.arrayCheck($3.loc, *$2.string, $1, variable);
|
||||
}
|
||||
|
||||
parseContext.profileRequires($4.loc, ENoProfile, 120, "GL_3DL_array_objects", "initializer");
|
||||
|
||||
TIntermNode* intermNode;
|
||||
if (!parseContext.executeInitializerError($2.loc, *$2.string, $1, $5, intermNode, variable)) {
|
||||
//
|
||||
// Build intermediate representation
|
||||
//
|
||||
if (intermNode)
|
||||
$$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $4.loc);
|
||||
else
|
||||
$$.intermAggregate = 0;
|
||||
} else
|
||||
$$.intermAggregate = 0;
|
||||
TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, $3.arraySizes, $5);
|
||||
$$.intermAggregate = parseContext.intermediate.growAggregate(0, initNode, $4.loc);
|
||||
}
|
||||
| fully_specified_type IDENTIFIER EQUAL initializer {
|
||||
$$.type = $1;
|
||||
|
||||
TIntermNode* intermNode;
|
||||
if (!parseContext.executeInitializerError($2.loc, *$2.string, $1, $4, intermNode)) {
|
||||
//
|
||||
// Build intermediate representation
|
||||
//
|
||||
if (intermNode)
|
||||
$$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $3.loc);
|
||||
else
|
||||
$$.intermAggregate = 0;
|
||||
} else
|
||||
$$.intermAggregate = 0;
|
||||
TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, 0, $4);
|
||||
$$.intermAggregate = parseContext.intermediate.growAggregate(0, initNode, $3.loc);
|
||||
}
|
||||
|
||||
// Grammar Note: No 'enum', or 'typedef'.
|
||||
|
|
@ -1128,7 +1044,7 @@ fully_specified_type
|
|||
parseContext.arraySizeRequiredCheck($2.loc, $2.arraySizes->getSize());
|
||||
}
|
||||
|
||||
if ($2.arraySizes && parseContext.arrayQualifierError($2.loc, $1))
|
||||
if ($2.arraySizes && parseContext.arrayQualifierError($2.loc, $1.qualifier))
|
||||
$2.arraySizes = 0;
|
||||
|
||||
parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);
|
||||
|
|
@ -2121,7 +2037,7 @@ struct_declaration
|
|||
|
||||
$$ = $2;
|
||||
|
||||
parseContext.voidErrorCheck($1.loc, (*$2)[0].type->getFieldName(), $1);
|
||||
parseContext.voidErrorCheck($1.loc, (*$2)[0].type->getFieldName(), $1.basicType);
|
||||
parseContext.precisionQualifierCheck($1.loc, $1);
|
||||
|
||||
for (unsigned int i = 0; i < $$->size(); ++i) {
|
||||
|
|
@ -2139,7 +2055,7 @@ struct_declaration
|
|||
|
||||
$$ = $3;
|
||||
|
||||
parseContext.voidErrorCheck($2.loc, (*$3)[0].type->getFieldName(), $2);
|
||||
parseContext.voidErrorCheck($2.loc, (*$3)[0].type->getFieldName(), $2.basicType);
|
||||
parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);
|
||||
parseContext.precisionQualifierCheck($2.loc, $2);
|
||||
|
||||
|
|
@ -2302,13 +2218,14 @@ condition
|
|||
parseContext.boolCheck($1->getLoc(), $1);
|
||||
}
|
||||
| fully_specified_type IDENTIFIER EQUAL initializer {
|
||||
TIntermNode* intermNode;
|
||||
parseContext.boolCheck($2.loc, $1);
|
||||
|
||||
if (parseContext.executeInitializerError($2.loc, *$2.string, $1, $4, intermNode))
|
||||
$$ = 0;
|
||||
TType type($1);
|
||||
TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, 0, $4);
|
||||
if (initNode)
|
||||
$$ = initNode->getAsTyped();
|
||||
else
|
||||
$$ = $4;
|
||||
$$ = 0;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue