Skip to content
Snippets Groups Projects
Commit 2c8265bb authored by John Kessenich's avatar John Kessenich
Browse files

GLSL: Fix #1358: Support "struct name", where name could be a user type

parent 1ea8f595
No related branches found
No related tags found
No related merge requests found
...@@ -71,4 +71,17 @@ void main() ...@@ -71,4 +71,17 @@ void main()
int degrees; int degrees;
degrees(3.2); degrees(3.2);
{
S s;
s.x = 3;
struct S { // okay, hides S
bool b;
};
S t;
t.b = true;
struct S { // ERROR, redefinition of struct S
float f;
};
}
} }
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
ERROR: 0:5: 'a' : redefinition ERROR: 0:5: 'a' : redefinition
ERROR: 0:57: 'z' : undeclared identifier ERROR: 0:57: 'z' : undeclared identifier
ERROR: 0:57: 'z' : redefinition 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 Shader version: 110
...@@ -120,6 +121,21 @@ ERROR: node is still EOpNull! ...@@ -120,6 +121,21 @@ ERROR: node is still EOpNull!
0:69 0 (const int) 0:69 0 (const int)
0:73 Constant: 0:73 Constant:
0:73 183.346494 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:? Linker Objects
0:? 'b' ( global bool) 0:? 'b' ( global bool)
0:? 'c' ( global bool) 0:? 'c' ( global bool)
...@@ -236,6 +252,21 @@ ERROR: node is still EOpNull! ...@@ -236,6 +252,21 @@ ERROR: node is still EOpNull!
0:69 0 (const int) 0:69 0 (const int)
0:73 Constant: 0:73 Constant:
0:73 183.346494 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:? Linker Objects
0:? 'b' ( global bool) 0:? 'b' ( global bool)
0:? 'c' ( global bool) 0:? 'c' ( global bool)
......
...@@ -778,7 +778,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token) ...@@ -778,7 +778,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
case '?': return QUESTION; case '?': return QUESTION;
case '[': return LEFT_BRACKET; case '[': return LEFT_BRACKET;
case ']': return RIGHT_BRACKET; case ']': return RIGHT_BRACKET;
case '{': return LEFT_BRACE; case '{': afterStruct = false; return LEFT_BRACE;
case '}': return RIGHT_BRACE; case '}': return RIGHT_BRACE;
case '\\': case '\\':
parseContext.error(loc, "illegal use of escape character", "\\", ""); parseContext.error(loc, "illegal use of escape character", "\\", "");
...@@ -861,7 +861,6 @@ int TScanContext::tokenizeIdentifier() ...@@ -861,7 +861,6 @@ int TScanContext::tokenizeIdentifier()
case IN: case IN:
case OUT: case OUT:
case INOUT: case INOUT:
case STRUCT:
case BREAK: case BREAK:
case CONTINUE: case CONTINUE:
case DO: case DO:
...@@ -874,6 +873,10 @@ int TScanContext::tokenizeIdentifier() ...@@ -874,6 +873,10 @@ int TScanContext::tokenizeIdentifier()
case CASE: case CASE:
return keyword; return keyword;
case STRUCT:
afterStruct = true;
return keyword;
case NONUNIFORM: case NONUNIFORM:
if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier)) if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier))
return keyword; return keyword;
...@@ -1537,7 +1540,7 @@ int TScanContext::identifierOrType() ...@@ -1537,7 +1540,7 @@ int TScanContext::identifierOrType()
return IDENTIFIER; return IDENTIFIER;
parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string); 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 (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) {
if (variable->isUserType()) { if (variable->isUserType()) {
afterType = true; afterType = true;
......
...@@ -50,7 +50,10 @@ class TParserToken; ...@@ -50,7 +50,10 @@ class TParserToken;
class TScanContext { class TScanContext {
public: 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() { } virtual ~TScanContext() { }
static void fillInKeywordMap(); static void fillInKeywordMap();
...@@ -76,6 +79,7 @@ protected: ...@@ -76,6 +79,7 @@ protected:
TParseContextBase& parseContext; TParseContextBase& parseContext;
bool afterType; // true if we've recognized a type, so can only be looking for an identifier 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 '.' bool field; // true if we're on a field, right after a '.'
TSourceLoc loc; TSourceLoc loc;
TParserToken* parserToken; TParserToken* parserToken;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment