Merge pull request #648 from steve-lunarg/type-identifiers

HLSL: allow type keywords as identifiers, and add half type
This commit is contained in:
John Kessenich
2017-01-04 14:07:34 -07:00
committed by GitHub
8 changed files with 657 additions and 21 deletions

View File

@@ -85,21 +85,36 @@ bool HlslGrammar::acceptIdentifier(HlslToken& idToken)
return true;
}
// Even though "sample" is a keyword (for interpolation modifiers), it IS still accepted as
// an identifier. This appears to be a solitary exception: other interp modifier keywords such
// as "linear" or "centroid" NOT valid identifiers. This code special cases "sample",
// so e.g, "int sample;" is accepted.
if (peekTokenClass(EHTokSample)) {
token.string = NewPoolTString("sample");
token.tokenClass = EHTokIdentifier;
token.symbol = nullptr;
idToken = token;
advanceToken();
return true;
// Even though "sample", "bool", "float", etc keywords (for types, interpolation modifiers),
// they ARE still accepted as identifiers. This is not a dense space: e.g, "void" is not a
// valid identifier, nor is "linear". This code special cases the known instances of this, so
// e.g, "int sample;" or "float float;" is accepted. Other cases can be added here if needed.
TString* idString = nullptr;
switch (peek()) {
case EHTokSample: idString = NewPoolTString("sample"); break;
case EHTokHalf: idString = NewPoolTString("half"); break;
case EHTokBool: idString = NewPoolTString("bool"); break;
case EHTokFloat: idString = NewPoolTString("float"); break;
case EHTokDouble: idString = NewPoolTString("double"); break;
case EHTokInt: idString = NewPoolTString("int"); break;
case EHTokUint: idString = NewPoolTString("uint"); break;
case EHTokMin16float: idString = NewPoolTString("min16float"); break;
case EHTokMin10float: idString = NewPoolTString("min10float"); break;
case EHTokMin16int: idString = NewPoolTString("min16int"); break;
case EHTokMin12int: idString = NewPoolTString("min12int"); break;
default:
return false;
}
return false;
token.string = idString;
token.tokenClass = EHTokIdentifier;
token.symbol = nullptr;
idToken = token;
advanceToken();
return true;
}
// compilationUnit
@@ -418,7 +433,15 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
// SEMICOLON
if (! acceptTokenClass(EHTokSemicolon)) {
expected(";");
// This may have been a false detection of what appeared to be a declaration, but
// was actually an assignment such as "float = 4", where "float" is an identifier.
// We put the token back to let further parsing happen for cases where that may
// happen. This errors on the side of caution, and mostly triggers the error.
if (peek() == EHTokAssign || peek() == EHTokLeftBracket || peek() == EHTokDot || peek() == EHTokComma)
recedeToken();
else
expected(";");
return false;
}
@@ -1086,6 +1109,7 @@ bool HlslGrammar::acceptType(TType& type)
// changes, e.g, to use native halfs.
static const TBasicType min16float_bt = EbtFloat;
static const TBasicType min10float_bt = EbtFloat;
static const TBasicType half_bt = EbtFloat;
static const TBasicType min16int_bt = EbtInt;
static const TBasicType min12int_bt = EbtInt;
static const TBasicType min16uint_bt = EbtUint;
@@ -1255,6 +1279,23 @@ bool HlslGrammar::acceptType(TType& type)
new(&type) TType(EbtBool, EvqTemporary, 4);
break;
case EHTokHalf:
new(&type) TType(half_bt, EvqTemporary, EpqMedium);
break;
case EHTokHalf1:
new(&type) TType(half_bt, EvqTemporary, EpqMedium);
type.makeVector();
break;
case EHTokHalf2:
new(&type) TType(half_bt, EvqTemporary, EpqMedium, 2);
break;
case EHTokHalf3:
new(&type) TType(half_bt, EvqTemporary, EpqMedium, 3);
break;
case EHTokHalf4:
new(&type) TType(half_bt, EvqTemporary, EpqMedium, 4);
break;
case EHTokMin16float:
new(&type) TType(min16float_bt, EvqTemporary, EpqMedium);
break;
@@ -1683,6 +1724,7 @@ bool HlslGrammar::acceptStruct(TType& type)
bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
{
typeList = new TTypeList();
HlslToken idToken;
do {
// success on seeing the RIGHT_BRACE coming up
@@ -1700,8 +1742,7 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
// struct_declarator COMMA struct_declarator ...
do {
// peek IDENTIFIER
if (! peekTokenClass(EHTokIdentifier)) {
if (! acceptIdentifier(idToken)) {
expected("member name");
return false;
}
@@ -1709,12 +1750,9 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
// add it to the list of members
TTypeLoc member = { new TType(EbtVoid), token.loc };
member.type->shallowCopy(memberType);
member.type->setFieldName(*token.string);
member.type->setFieldName(*idToken.string);
typeList->push_back(member);
// accept IDENTIFIER
advanceToken();
// array_specifier
TArraySizes* arraySizes = nullptr;
acceptArraySpecifier(arraySizes);
@@ -2378,7 +2416,9 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
// arguments
TIntermTyped* arguments = nullptr;
if (! acceptArguments(constructorFunction, arguments)) {
expected("constructor arguments");
// It's possible this is a type keyword used as an identifier. Put the token back
// for later use.
recedeToken();
return false;
}

View File

@@ -169,6 +169,10 @@ void HlslScanContext::fillInKeywordMap()
(*KeywordMap)["uint3"] = EHTokUint3;
(*KeywordMap)["uint4"] = EHTokUint4;
(*KeywordMap)["half1"] = EHTokHalf1;
(*KeywordMap)["half2"] = EHTokHalf2;
(*KeywordMap)["half3"] = EHTokHalf3;
(*KeywordMap)["half4"] = EHTokHalf4;
(*KeywordMap)["min16float1"] = EHTokMin16float1;
(*KeywordMap)["min16float2"] = EHTokMin16float2;
(*KeywordMap)["min16float3"] = EHTokMin16float3;
@@ -579,6 +583,10 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier()
case EHTokUint2:
case EHTokUint3:
case EHTokUint4:
case EHTokHalf1:
case EHTokHalf2:
case EHTokHalf3:
case EHTokHalf4:
case EHTokMin16float1:
case EHTokMin16float2:
case EHTokMin16float3:

View File

@@ -120,6 +120,10 @@ enum EHlslTokenClass {
EHTokUint2,
EHTokUint3,
EHTokUint4,
EHTokHalf1,
EHTokHalf2,
EHTokHalf3,
EHTokHalf4,
EHTokMin16float1,
EHTokMin16float2,
EHTokMin16float3,