From a1e2d4952e0bf6ec809d243e01e0c602797bbfd2 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Tue, 20 Sep 2016 13:22:58 -0600 Subject: [PATCH] HLSL: Move to correct parsing of annotations, improving all annotations and recent string grammar. --- Test/hlsl.string.frag | 2 +- glslang/Include/revision.h | 4 +-- hlsl/hlslGrammar.cpp | 60 ++++++++++++-------------------------- hlsl/hlslGrammar.h | 2 +- hlsl/hlslParseHelper.cpp | 11 +++++-- hlsl/hlslParseHelper.h | 11 ++++--- hlsl/hlslScanContext.cpp | 4 +-- hlsl/hlslTokens.h | 2 +- 8 files changed, 40 insertions(+), 56 deletions(-) diff --git a/Test/hlsl.string.frag b/Test/hlsl.string.frag index 09885ff93..572e73b79 100755 --- a/Test/hlsl.string.frag +++ b/Test/hlsl.string.frag @@ -1,7 +1,7 @@ string s = "string1"; string e = ""; string bracket < string a = "nested" ; > ; -string brackets < string b = "nest1" ; string c = "nest2" ; string d = "nest3" ; > ; +string brackets < string b = "nest1" ; string c = "nest2" ; float test [ 4 ] = { 1.0 , 1.0 , 1.0 , 1.0 } ; vector a = float3(2.0); > ; string brackete1 < > ; string brackete2 < ; > ; string brackete3 < ; ; > ; diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index 32969be12..6850d6fcd 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -2,5 +2,5 @@ // For the version, it uses the latest git tag followed by the number of commits. // For the date, it uses the current date (when then script is run). -#define GLSLANG_REVISION "Overload400-PrecQual.1502" -#define GLSLANG_DATE "19-Sep-2016" +#define GLSLANG_REVISION "Overload400-PrecQual.1503" +#define GLSLANG_DATE "20-Sep-2016" diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 076251458..d458a882c 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -721,36 +721,16 @@ bool HlslGrammar::acceptMatrixTemplateType(TType& type) return true; } -// string_template_type -// : STRING -// | STRING identifier LEFT_ANGLE declaration SEMI_COLON ... declaration SEMICOLON RIGHT_ANGLE +// annotations +// : LEFT_ANGLE declaration SEMI_COLON ... declaration SEMICOLON RIGHT_ANGLE // -bool HlslGrammar::acceptStringTemplateType(TType& type) +bool HlslGrammar::acceptAnnotations(TQualifier&) { - // STRING - if (! acceptTokenClass(EHTokString)) + if (! acceptTokenClass(EHTokLeftAngle)) return false; - // no matter what happens next, we recognized a string type - new(&type) TType(EbtString); - - // identifier LEFT_ANGLE, or not? - if (! acceptTokenClass(EHTokIdentifier)) { - expected("identifier following 'string'"); - return false; - } - - if (! peekTokenClass(EHTokLeftAngle)) { - // then it must be the non-template version, back up and let - // normal declaration code handle it - - // recede the identifier - recedeToken(); - return true; - } - - // move past the LEFT_ANGLE - advanceToken(); + // note that we are nesting a name space + parseContext.nestAnnotations(); // declaration SEMI_COLON ... declaration SEMICOLON RIGHT_ANGLE do { @@ -759,15 +739,18 @@ bool HlslGrammar::acceptStringTemplateType(TType& type) ; if (acceptTokenClass(EHTokRightAngle)) - return true; + break; // declaration TIntermNode* node; if (! acceptDeclaration(node)) { - expected("declaration in string list"); + expected("declaration in annotation"); return false; } } while (true); + + parseContext.unnestAnnotations(); + return true; } // sampler_type @@ -942,10 +925,6 @@ bool HlslGrammar::acceptType(TType& type) return acceptMatrixTemplateType(type); break; - case EHTokString: - return acceptStringTemplateType(type); - break; - case EHTokSampler: // fall through case EHTokSampler1d: // ... case EHTokSampler2d: // ... @@ -991,6 +970,10 @@ bool HlslGrammar::acceptType(TType& type) new(&type) TType(EbtVoid); break; + case EHTokString: + new(&type) TType(EbtString); + break; + case EHTokFloat: new(&type) TType(EbtFloat); break; @@ -2740,16 +2723,9 @@ void HlslGrammar::acceptPostDecls(TQualifier& qualifier) // semantic, in idToken.string parseContext.handleSemantic(idToken.loc, qualifier, *idToken.string); } - } else if (acceptTokenClass(EHTokLeftAngle)) { - // TODO: process annotations, just accepting them for now - do { - if (peekTokenClass(EHTokNone)) - return; - if (acceptTokenClass(EHTokRightAngle)) - break; - advanceToken(); - } while (true); - } else + } else if (peekTokenClass(EHTokLeftAngle)) + acceptAnnotations(qualifier); + else break; } while (true); diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index f5c7d4d2e..992eb5e98 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -73,7 +73,7 @@ namespace glslang { bool acceptTemplateType(TBasicType&); bool acceptVectorTemplateType(TType&); bool acceptMatrixTemplateType(TType&); - bool acceptStringTemplateType(TType&); + bool acceptAnnotations(TQualifier&); bool acceptSamplerType(TType&); bool acceptTextureType(TType&); bool acceptStruct(TType&); diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 9018606a8..63cd5ecf5 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -52,7 +52,8 @@ HlslParseContext::HlslParseContext(TSymbolTable& symbolTable, TIntermediate& int int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) : TParseContextBase(symbolTable, interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages), - contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), + contextPragma(true, false), + loopNestingLevel(0), annotationNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), postMainReturn(false), limits(resources.limits), entryPointOutput(nullptr), @@ -4059,8 +4060,12 @@ void HlslParseContext::declareTypedef(const TSourceLoc& loc, TString& identifier // TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TType& parseType, TArraySizes* arraySizes, TIntermTyped* initializer) { - // string identifiers can nest inside < ... >, apparently with their own namespace, - // which is not implemented + // TODO: things scoped within an annotation need their own name space; + // haven't done that yet + if (annotationNestingLevel > 0) + return nullptr; + + // TODO: strings are not yet handled if (parseType.getBasicType() == EbtString) return nullptr; diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index ea763413c..016208832 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -159,10 +159,12 @@ public: void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index); - void nestLooping() { ++loopNestingLevel; } - void unnestLooping() { --loopNestingLevel; } - void pushScope() { symbolTable.push(); } - void popScope() { symbolTable.pop(0); } + void nestLooping() { ++loopNestingLevel; } + void unnestLooping() { --loopNestingLevel; } + void nestAnnotations() { ++annotationNestingLevel; } + void unnestAnnotations() { --annotationNestingLevel; } + void pushScope() { symbolTable.push(); } + void popScope() { symbolTable.pop(0); } void pushSwitchSequence(TIntermSequence* sequence) { switchSequenceStack.push_back(sequence); } void popSwitchSequence() { switchSequenceStack.pop_back(); } @@ -182,6 +184,7 @@ protected: // Current state of parsing struct TPragma contextPragma; int loopNestingLevel; // 0 if outside all loops + int annotationNestingLevel; // 0 if outside all annotations int structNestingLevel; // 0 if outside blocks and structures int controlFlowNestingLevel; // 0 if outside all flow control TList switchSequenceStack; // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting diff --git a/hlsl/hlslScanContext.cpp b/hlsl/hlslScanContext.cpp index edeee64cc..cf83ef393 100755 --- a/hlsl/hlslScanContext.cpp +++ b/hlsl/hlslScanContext.cpp @@ -122,9 +122,9 @@ void HlslScanContext::fillInKeywordMap() (*KeywordMap)["Buffer"] = EHTokBuffer; (*KeywordMap)["vector"] = EHTokVector; (*KeywordMap)["matrix"] = EHTokMatrix; - (*KeywordMap)["string"] = EHTokString; (*KeywordMap)["void"] = EHTokVoid; + (*KeywordMap)["string"] = EHTokString; (*KeywordMap)["bool"] = EHTokBool; (*KeywordMap)["int"] = EHTokInt; (*KeywordMap)["uint"] = EHTokUint; @@ -472,11 +472,11 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier() case EHTokBuffer: case EHTokVector: case EHTokMatrix: - case EHTokString: return keyword; // scalar types case EHTokVoid: + case EHTokString: case EHTokBool: case EHTokInt: case EHTokUint: diff --git a/hlsl/hlslTokens.h b/hlsl/hlslTokens.h index 9e23cc7af..e38cb9a60 100755 --- a/hlsl/hlslTokens.h +++ b/hlsl/hlslTokens.h @@ -70,10 +70,10 @@ enum EHlslTokenClass { EHTokBuffer, EHTokVector, EHTokMatrix, - EHTokString, // scalar types EHTokVoid, + EHTokString, EHTokBool, EHTokInt, EHTokUint,