HLSL: Fix #747: accept 'struct' in front of previously user-defined type name.

This commit is contained in:
John Kessenich 2017-03-02 14:30:59 -07:00
parent 0479437a5c
commit 854fe24786
8 changed files with 143 additions and 21 deletions

View file

@ -1268,9 +1268,8 @@ bool HlslGrammar::acceptType(TType& type)
// An identifier could be for a user-defined type.
// Note we cache the symbol table lookup, to save for a later rule
// when this is not a type.
token.symbol = parseContext.symbolTable.find(*token.string);
if (token.symbol && token.symbol->getAsVariable() && token.symbol->getAsVariable()->isUserType()) {
type.shallowCopy(token.symbol->getType());
token.symbol = parseContext.lookupUserType(*token.string, type);
if (token.symbol != nullptr) {
advanceToken();
return true;
} else
@ -1729,6 +1728,7 @@ bool HlslGrammar::acceptType(TType& type)
// struct
// : struct_type IDENTIFIER post_decls LEFT_BRACE struct_declaration_list RIGHT_BRACE
// | struct_type post_decls LEFT_BRACE struct_declaration_list RIGHT_BRACE
// | struct_type IDENTIFIER // use of previously declared struct type
//
// struct_type
// : STRUCT
@ -1761,12 +1761,18 @@ bool HlslGrammar::acceptStruct(TType& type)
// post_decls
TQualifier postDeclQualifier;
postDeclQualifier.clear();
acceptPostDecls(postDeclQualifier);
bool postDeclsFound = acceptPostDecls(postDeclQualifier);
// LEFT_BRACE
// struct_type IDENTIFIER
if (! acceptTokenClass(EHTokLeftBrace)) {
expected("{");
return false;
if (structName.size() > 0 && !postDeclsFound && parseContext.lookupUserType(structName, type) != nullptr) {
// struct_type IDENTIFIER
return true;
} else {
expected("{");
return false;
}
}
// struct_declaration_list
@ -3274,11 +3280,18 @@ void HlslGrammar::acceptArraySpecifier(TArraySizes*& arraySizes)
// COLON LAYOUT layout_qualifier_list
// annotations // optional
//
void HlslGrammar::acceptPostDecls(TQualifier& qualifier)
// Return true if any tokens were accepted. That is,
// false can be returned on successfully recognizing nothing,
// not necessarily meaning bad syntax.
//
bool HlslGrammar::acceptPostDecls(TQualifier& qualifier)
{
bool found = false;
do {
// COLON
if (acceptTokenClass(EHTokColon)) {
found = true;
HlslToken idToken;
if (peekTokenClass(EHTokLayout))
acceptLayoutQualifierList(qualifier);
@ -3286,18 +3299,18 @@ void HlslGrammar::acceptPostDecls(TQualifier& qualifier)
// PACKOFFSET LEFT_PAREN c[Subcomponent][.component] RIGHT_PAREN
if (! acceptTokenClass(EHTokLeftParen)) {
expected("(");
return;
return false;
}
HlslToken locationToken;
if (! acceptIdentifier(locationToken)) {
expected("c[subcomponent][.component]");
return;
return false;
}
HlslToken componentToken;
if (acceptTokenClass(EHTokDot)) {
if (! acceptIdentifier(componentToken)) {
expected("component");
return;
return false;
}
}
if (! acceptTokenClass(EHTokRightParen)) {
@ -3307,19 +3320,19 @@ void HlslGrammar::acceptPostDecls(TQualifier& qualifier)
parseContext.handlePackOffset(locationToken.loc, qualifier, *locationToken.string, componentToken.string);
} else if (! acceptIdentifier(idToken)) {
expected("layout, semantic, packoffset, or register");
return;
return false;
} else if (*idToken.string == "register") {
// REGISTER LEFT_PAREN [shader_profile,] Type#[subcomp]opt (COMMA SPACEN)opt RIGHT_PAREN
// LEFT_PAREN
if (! acceptTokenClass(EHTokLeftParen)) {
expected("(");
return;
return false;
}
HlslToken registerDesc; // for Type#
HlslToken profile;
if (! acceptIdentifier(registerDesc)) {
expected("register number description");
return;
return false;
}
if (registerDesc.string->size() > 1 && !isdigit((*registerDesc.string)[1]) &&
acceptTokenClass(EHTokComma)) {
@ -3328,7 +3341,7 @@ void HlslGrammar::acceptPostDecls(TQualifier& qualifier)
profile = registerDesc;
if (! acceptIdentifier(registerDesc)) {
expected("register number description");
return;
return false;
}
}
int subComponent = 0;
@ -3336,7 +3349,7 @@ void HlslGrammar::acceptPostDecls(TQualifier& qualifier)
// LEFT_BRACKET subcomponent RIGHT_BRACKET
if (! peekTokenClass(EHTokIntConstant)) {
expected("literal integer");
return;
return false;
}
subComponent = token.i;
advanceToken();
@ -3350,7 +3363,7 @@ void HlslGrammar::acceptPostDecls(TQualifier& qualifier)
if (acceptTokenClass(EHTokComma)) {
if (! acceptIdentifier(spaceDesc)) {
expected ("space identifier");
return;
return false;
}
}
// RIGHT_PAREN
@ -3363,12 +3376,15 @@ void HlslGrammar::acceptPostDecls(TQualifier& qualifier)
// semantic, in idToken.string
parseContext.handleSemantic(idToken.loc, qualifier, *idToken.string);
}
} else if (peekTokenClass(EHTokLeftAngle))
} else if (peekTokenClass(EHTokLeftAngle)) {
found = true;
acceptAnnotations(qualifier);
else
} else
break;
} while (true);
return found;
}
} // end namespace glslang