GLSL: Fix #1358: Support "struct name", where name could be a user type
authorJohn Kessenich <cepheus@frii.com>
Tue, 12 Jun 2018 01:25:24 +0000 (19:25 -0600)
committerJohn Kessenich <cepheus@frii.com>
Tue, 12 Jun 2018 01:28:15 +0000 (19:28 -0600)
Test/110scope.vert [changed mode: 0644->0755]
Test/baseResults/110scope.vert.out
glslang/MachineIndependent/Scan.cpp
glslang/MachineIndependent/ScanContext.h [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index e28db0f..86c27a5
@@ -71,4 +71,17 @@ void main()
 \r
     int degrees;\r
     degrees(3.2);\r
+\r
+    {\r
+        S s;\r
+        s.x = 3;\r
+        struct S {   // okay, hides S\r
+            bool b;\r
+        };\r
+        S t;\r
+        t.b = true;\r
+        struct S {    // ERROR, redefinition of struct S\r
+            float f;\r
+        };\r
+    }\r
 }\r
index a07de4f..e23d3c0 100644 (file)
@@ -2,7 +2,8 @@
 ERROR: 0:5: 'a' : redefinition 
 ERROR: 0:57: 'z' : undeclared identifier 
 ERROR: 0:57: 'z' : redefinition 
-ERROR: 3 compilation errors.  No code generated.
+ERROR: 0:83: 'S' : redefinition struct
+ERROR: 4 compilation errors.  No code generated.
 
 
 Shader version: 110
@@ -120,6 +121,21 @@ ERROR: node is still EOpNull!
 0:69            0 (const int)
 0:73      Constant:
 0:73        183.346494
+0:?       Sequence
+0:77        move second child to first child ( temp int)
+0:77          x: direct index for structure ( temp int)
+0:77            's' ( temp structure{ temp int x})
+0:77            Constant:
+0:77              0 (const int)
+0:77          Constant:
+0:77            3 (const int)
+0:82        move second child to first child ( temp bool)
+0:82          b: direct index for structure ( temp bool)
+0:82            't' ( temp structure{ temp bool b})
+0:82            Constant:
+0:82              0 (const int)
+0:82          Constant:
+0:82            true (const bool)
 0:?   Linker Objects
 0:?     'b' ( global bool)
 0:?     'c' ( global bool)
@@ -236,6 +252,21 @@ ERROR: node is still EOpNull!
 0:69            0 (const int)
 0:73      Constant:
 0:73        183.346494
+0:?       Sequence
+0:77        move second child to first child ( temp int)
+0:77          x: direct index for structure ( temp int)
+0:77            's' ( temp structure{ temp int x})
+0:77            Constant:
+0:77              0 (const int)
+0:77          Constant:
+0:77            3 (const int)
+0:82        move second child to first child ( temp bool)
+0:82          b: direct index for structure ( temp bool)
+0:82            't' ( temp structure{ temp bool b})
+0:82            Constant:
+0:82              0 (const int)
+0:82          Constant:
+0:82            true (const bool)
 0:?   Linker Objects
 0:?     'b' ( global bool)
 0:?     'c' ( global bool)
index 7232bae..aa21d8a 100755 (executable)
@@ -778,7 +778,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
         case '?':                       return QUESTION;
         case '[':                       return LEFT_BRACKET;
         case ']':                       return RIGHT_BRACKET;
-        case '{':                       return LEFT_BRACE;
+        case '{':  afterStruct = false; return LEFT_BRACE;
         case '}':                       return RIGHT_BRACE;
         case '\\':
             parseContext.error(loc, "illegal use of escape character", "\\", "");
@@ -861,7 +861,6 @@ int TScanContext::tokenizeIdentifier()
     case IN:
     case OUT:
     case INOUT:
-    case STRUCT:
     case BREAK:
     case CONTINUE:
     case DO:
@@ -874,6 +873,10 @@ int TScanContext::tokenizeIdentifier()
     case CASE:
         return keyword;
 
+    case STRUCT:
+        afterStruct = true;
+        return keyword;
+
     case NONUNIFORM:
         if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier))
             return keyword;
@@ -1537,7 +1540,7 @@ int TScanContext::identifierOrType()
         return IDENTIFIER;
 
     parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string);
-    if (afterType == false && parserToken->sType.lex.symbol) {
+    if ((afterType == false && afterStruct == false) && parserToken->sType.lex.symbol != nullptr) {
         if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) {
             if (variable->isUserType()) {
                 afterType = true;
old mode 100644 (file)
new mode 100755 (executable)
index 608ae06..0cc7ea0
@@ -50,7 +50,10 @@ class TParserToken;
 
 class TScanContext {
 public:
-    explicit TScanContext(TParseContextBase& pc) : parseContext(pc), afterType(false), field(false) { }
+    explicit TScanContext(TParseContextBase& pc) :
+        parseContext(pc),
+        afterType(false), afterStruct(false),
+        field(false) { }
     virtual ~TScanContext() { }
 
     static void fillInKeywordMap();
@@ -76,6 +79,7 @@ protected:
 
     TParseContextBase& parseContext;
     bool afterType;           // true if we've recognized a type, so can only be looking for an identifier
+    bool afterStruct;         // true if we've recognized the STRUCT keyword, so can only be looking for an identifier
     bool field;               // true if we're on a field, right after a '.'
     TSourceLoc loc;
     TParserToken* parserToken;