diff --git a/Test/baseResults/specExamples.frag.out b/Test/baseResults/specExamples.frag.out index 6d49ed31..7c0558d0 100644 --- a/Test/baseResults/specExamples.frag.out +++ b/Test/baseResults/specExamples.frag.out @@ -8,17 +8,10 @@ ERROR: 0:71: 'Material' : only uniform interface blocks are supported ERROR: 0:79: 'Light' : only uniform interface blocks are supported ERROR: 0:83: 'ColoredTexture' : only uniform interface blocks are supported ERROR: 0:87: 'Color' : redefinition -ERROR: 0:89: 'gl_' : reserved built-in name ERROR: 0:92: 'origin_upper_left' : unrecognized layout identifier -ERROR: 0:92: 'gl_' : reserved built-in name -ERROR: 0:92: 'gl_FragCoord' : redefinition ERROR: 0:93: 'pixel_center_integer' : unrecognized layout identifier -ERROR: 0:93: 'gl_' : reserved built-in name -ERROR: 0:93: 'gl_FragCoord' : redefinition ERROR: 0:94: 'origin_upper_left' : unrecognized layout identifier ERROR: 0:94: 'pixel_center_integer' : unrecognized layout identifier -ERROR: 0:94: 'gl_' : reserved built-in name -ERROR: 0:94: 'gl_FragCoord' : redefinition ERROR: 0:96: 'early_fragment_tests' : unrecognized layout identifier ERROR: 0:99: 'local_size_x' : there is no such layout identifier taking an assigned value ERROR: 0:99: 'local_size_y' : there is no such layout identifier taking an assigned value @@ -26,24 +19,11 @@ ERROR: 0:100: 'local_size_x' : there is no such layout identifier taking an assi ERROR: 0:102: 'color' : redefinition ERROR: 0:103: 'index' : there is no such layout identifier taking an assigned value ERROR: 0:106: 'depth_greater' : unrecognized layout identifier -ERROR: 0:106: 'gl_' : reserved built-in name -ERROR: 0:109: 'gl_' : reserved built-in name -ERROR: 0:109: 'gl_FragDepth' : redefinition ERROR: 0:112: 'depth_any' : unrecognized layout identifier -ERROR: 0:112: 'gl_' : reserved built-in name -ERROR: 0:112: 'gl_FragDepth' : redefinition ERROR: 0:115: 'depth_greater' : unrecognized layout identifier -ERROR: 0:115: 'gl_' : reserved built-in name -ERROR: 0:115: 'gl_FragDepth' : redefinition ERROR: 0:118: 'depth_less' : unrecognized layout identifier -ERROR: 0:118: 'gl_' : reserved built-in name -ERROR: 0:118: 'gl_FragDepth' : redefinition ERROR: 0:121: 'depth_unchanged' : unrecognized layout identifier -ERROR: 0:121: 'gl_' : reserved built-in name -ERROR: 0:121: 'gl_FragDepth' : redefinition ERROR: 0:123: 'gl_' : reserved built-in name -ERROR: 0:124: 'gl_' : reserved built-in name -ERROR: 0:124: 'gl_Color' : redefinition ERROR: 0:150: 'constructor' : constructing from a non-dereferenced array ERROR: 0:152: '=' : cannot convert from 'const 2-element array of 4-component vector of float' to '3-element array of 4-component vector of float' ERROR: 0:172: 'x' : undeclared identifier @@ -74,7 +54,7 @@ ERROR: 0:226: 'in' : only allowed at global scope ERROR: 0:227: 'in' : only allowed at global scope ERROR: 0:228: 'in' : only allowed at global scope ERROR: 0:232: 'out' : only allowed at global scope -ERROR: 76 compilation errors. No code generated. +ERROR: 56 compilation errors. No code generated. ERROR: node is still EOpNull! 0:5 Sequence @@ -222,8 +202,8 @@ ERROR: node is still EOpNull! 0:? 'temperature' (noperspective in float) 0:? 'myColor' (flat in 3-component vector of float) 0:? 'myTexCoord' (centroid noperspective in 2-component vector of float) -0:? 'gl_FragCoord' (smooth in 4-component vector of float) +0:? 'gl_FragCoord' (gl_FragCoord 4-component vector of float) 0:? 'factor' (layout(location=3 ) out 4-component vector of float) -0:? 'gl_FragDepth' (out float) +0:? 'gl_FragDepth' (gl_FragDepth float) 0:? 'gl_Color' (smooth in 4-component vector of float) diff --git a/Test/baseResults/specExamples.vert.out b/Test/baseResults/specExamples.vert.out index 7902a8c3..f8b3a34c 100644 --- a/Test/baseResults/specExamples.vert.out +++ b/Test/baseResults/specExamples.vert.out @@ -36,8 +36,6 @@ ERROR: 0:96: 'binding' : not supported ERROR: 0:97: 'binding' : not supported ERROR: 0:106: '' : vertex input cannot be further qualified ERROR: 0:106: 'gl_' : reserved built-in name -ERROR: 0:107: 'gl_' : reserved built-in name -ERROR: 0:107: 'gl_FrontColor' : redefinition ERROR: 0:119: 'a' : redefinition ERROR: 0:127: 'Block2' : nameless block contains a member that already has a name at global scope ERROR: 0:132: 'shared' : not supported in this stage: vertex @@ -56,7 +54,7 @@ ERROR: 0:191: '=' : cannot convert from 'const 4-component vector of float' to ERROR: 0:192: 'constructor' : constructing from a non-dereferenced array ERROR: 0:193: 'constructor' : constructing from a non-dereferenced array ERROR: 0:194: 'constructor' : constructing from a non-dereferenced array -ERROR: 58 compilation errors. No code generated. +ERROR: 56 compilation errors. No code generated. ERROR: node is still EOpNull! 0:134 Function Definition: funcA(I21; (4-component vector of float) diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 2ad40e7d..25de8f98 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -1180,13 +1180,13 @@ void TParseContext::globalCheck(TSourceLoc loc, bool global, const char* token) } // -// For now, keep it simple: if it starts "gl_", it's reserved, independent -// of scope. Except, if the symbol table is at the built-in push-level, +// If it starts "gl_" or has double underscore, it's a reserved name. +// Except, if the symbol table is at a built-in level, // which is when we are parsing built-ins. // bool TParseContext::reservedErrorCheck(TSourceLoc loc, const TString& identifier) { - if (!symbolTable.atBuiltInLevel()) { + if (! symbolTable.atBuiltInLevel()) { if (identifier.substr(0, 3) == TString("gl_")) { error(loc, "reserved built-in name", "gl_", ""); @@ -1805,23 +1805,81 @@ void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TPubl // Do semantic checking for a variable declaration that has no initializer, // and update the symbol table. // -void TParseContext::nonInitCheck(TSourceLoc loc, TString& identifier, TPublicType& type) +void TParseContext::nonInitCheck(TSourceLoc loc, TString& identifier, TPublicType& publicType) { - reservedErrorCheck(loc, identifier); + TType type(publicType); + bool newDeclaration; + 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; + } - TVariable* variable = new TVariable(&identifier, TType(type)); - - if (! symbolTable.insert(*variable)) - error(loc, "redefinition", variable->getName().c_str(), ""); - else { - voidErrorCheck(loc, identifier, type); + if (newDeclaration) { + voidErrorCheck(loc, identifier, publicType); // see if it's a linker-level object to track - if (type.qualifier.isUniform() || type.qualifier.isPipeInput() || type.qualifier.isPipeOutput()) - intermediate.addSymbolLinkageNode(linkage, *variable); + if (type.getQualifier().isUniform() || type.getQualifier().isPipeInput() || type.getQualifier().isPipeOutput()) + 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 +// globol level, so it can be modified. +// +TVariable* TParseContext::redeclare(TSourceLoc loc, const TString& identifier, const TType& type, bool& newDeclaration) +{ + newDeclaration = false; + + if (profile == EEsProfile || identifier.substr(0, 3) != TString("gl_") || symbolTable.atBuiltInLevel()) + return 0; + + // Potentially redeclaring a built-in variable... + + if (identifier == "gl_FragDepth" && version >= 420 || + identifier == "gl_PerVertex" && version >= 410 || + identifier == "gl_PerFragment" && version >= 410 || + identifier == "gl_FragCoord" && version >= 150 || + identifier == "gl_ClipDistance" && version >= 130 || + identifier == "gl_FrontColor" && version >= 130 || + identifier == "gl_BackColor" && version >= 130 || + identifier == "gl_FrontSecondaryColor" && version >= 130 || + identifier == "gl_BackSecondaryColor" && version >= 130 || + identifier == "gl_SecondaryColor" && version >= 130 || + identifier == "gl_Color" && version >= 130 && language == EShLangFragment || + identifier == "gl_TexCoord") { + + // Find the existing symbol, if any. + bool builtIn; + TSymbol* symbol = symbolTable.find(identifier, &builtIn); + + // 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; + + // Otherwise, time to copy the symbol up to make a writable version + newDeclaration = true; + variable = symbolTable.copyUp(variable); + return variable; + } + + error(loc, "cannot redeclare this built-in variable", identifier.c_str(), ""); + return 0; +} + void TParseContext::paramCheck(TSourceLoc loc, TStorageQualifier qualifier, TType* type) { switch (qualifier) { diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 22ded39d..2737553c 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -121,6 +121,7 @@ public: 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); void paramCheck(TSourceLoc, TStorageQualifier qualifier, TType* type); void nestedBlockCheck(TSourceLoc); void nestedStructCheck(TSourceLoc); @@ -212,6 +213,7 @@ protected: TQualifier globalUniformDefaults; TQualifier globalInputDefaults; TQualifier globalOutputDefaults; + // TODO: desktop functionality: track use of gl_FragDepth before redeclaration }; } // end namespace glslang