Infrastructure: Move nesting counters, etc., to base class.
This lets all languages share the same definitions.
This commit is contained in:
parent
b4d46627cb
commit
9b2531ba23
@ -51,8 +51,8 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b
|
|||||||
int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
|
int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
|
||||||
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) :
|
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) :
|
||||||
TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
||||||
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0),
|
inMain(false),
|
||||||
inMain(false), postMainReturn(false), currentFunctionType(nullptr), blockName(nullptr),
|
blockName(nullptr),
|
||||||
limits(resources.limits),
|
limits(resources.limits),
|
||||||
atomicUintOffsets(nullptr), anyIndexLimits(false)
|
atomicUintOffsets(nullptr), anyIndexLimits(false)
|
||||||
{
|
{
|
||||||
@ -912,7 +912,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc,
|
|||||||
loopNestingLevel = 0;
|
loopNestingLevel = 0;
|
||||||
statementNestingLevel = 0;
|
statementNestingLevel = 0;
|
||||||
controlFlowNestingLevel = 0;
|
controlFlowNestingLevel = 0;
|
||||||
postMainReturn = false;
|
postEntryPointReturn = false;
|
||||||
|
|
||||||
return paramNodes;
|
return paramNodes;
|
||||||
}
|
}
|
||||||
@ -1193,7 +1193,7 @@ void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
|
|||||||
error(loc, "tessellation control barrier() cannot be placed within flow control", "", "");
|
error(loc, "tessellation control barrier() cannot be placed within flow control", "", "");
|
||||||
if (! inMain)
|
if (! inMain)
|
||||||
error(loc, "tessellation control barrier() must be in main()", "", "");
|
error(loc, "tessellation control barrier() must be in main()", "", "");
|
||||||
else if (postMainReturn)
|
else if (postEntryPointReturn)
|
||||||
error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
|
error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", "");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -77,6 +77,10 @@ public:
|
|||||||
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages)
|
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages)
|
||||||
: TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
: TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
||||||
symbolTable(symbolTable),
|
symbolTable(symbolTable),
|
||||||
|
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
|
||||||
|
postEntryPointReturn(false),
|
||||||
|
contextPragma(true, false),
|
||||||
|
limits(resources.limits),
|
||||||
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
|
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
|
||||||
globalUniformBlock(nullptr)
|
globalUniformBlock(nullptr)
|
||||||
{ }
|
{ }
|
||||||
@ -133,8 +137,6 @@ public:
|
|||||||
extensionCallback(line, extension, behavior);
|
extensionCallback(line, extension, behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
|
|
||||||
|
|
||||||
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
|
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
|
||||||
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
|
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
|
||||||
|
|
||||||
@ -143,6 +145,23 @@ public:
|
|||||||
|
|
||||||
const char* const scopeMangler = "::";
|
const char* const scopeMangler = "::";
|
||||||
|
|
||||||
|
// Basic parsing state, easily accessible to the grammar
|
||||||
|
|
||||||
|
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
|
||||||
|
int statementNestingLevel; // 0 if outside all flow control or compound statements
|
||||||
|
int loopNestingLevel; // 0 if outside all loops
|
||||||
|
int structNestingLevel; // 0 if outside blocks and structures
|
||||||
|
int controlFlowNestingLevel; // 0 if outside all flow control
|
||||||
|
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
||||||
|
bool functionReturnsValue; // true if a non-void function has a return
|
||||||
|
// if inside a function, true if the function is the entry point and this is after a return statement
|
||||||
|
bool postEntryPointReturn;
|
||||||
|
// case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting
|
||||||
|
TList<TIntermSequence*> switchSequenceStack;
|
||||||
|
// the statementNestingLevel the current switch statement is at, which must match the level of its case statements
|
||||||
|
TList<int> switchLevel;
|
||||||
|
struct TPragma contextPragma;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TParseContextBase(TParseContextBase&);
|
TParseContextBase(TParseContextBase&);
|
||||||
TParseContextBase& operator=(TParseContextBase&);
|
TParseContextBase& operator=(TParseContextBase&);
|
||||||
@ -151,6 +170,8 @@ protected:
|
|||||||
TVector<TSymbol*> linkageSymbols; // these need to be transferred to 'linkage', after all editing is done
|
TVector<TSymbol*> linkageSymbols; // these need to be transferred to 'linkage', after all editing is done
|
||||||
TScanContext* scanContext;
|
TScanContext* scanContext;
|
||||||
TPpContext* ppContext;
|
TPpContext* ppContext;
|
||||||
|
TBuiltInResource resources;
|
||||||
|
TLimits& limits;
|
||||||
|
|
||||||
// These, if set, will be called when a line, pragma ... is preprocessed.
|
// These, if set, will be called when a line, pragma ... is preprocessed.
|
||||||
// They will be called with any parameters to the original directive.
|
// They will be called with any parameters to the original directive.
|
||||||
@ -384,17 +405,7 @@ public:
|
|||||||
//
|
//
|
||||||
|
|
||||||
// Current state of parsing
|
// Current state of parsing
|
||||||
struct TPragma contextPragma;
|
|
||||||
int loopNestingLevel; // 0 if outside all loops
|
|
||||||
int structNestingLevel; // 0 if outside blocks and structures
|
|
||||||
int controlFlowNestingLevel; // 0 if outside all flow control
|
|
||||||
int statementNestingLevel; // 0 if outside all flow control or compound statements
|
|
||||||
TList<TIntermSequence*> switchSequenceStack; // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting
|
|
||||||
TList<int> switchLevel; // the statementNestingLevel the current switch statement is at, which must match the level of its case statements
|
|
||||||
bool inMain; // if inside a function, true if the function is main
|
bool inMain; // if inside a function, true if the function is main
|
||||||
bool postMainReturn; // if inside a function, true if the function is main and this is after a return statement
|
|
||||||
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
|
||||||
bool functionReturnsValue; // true if a non-void function has a return
|
|
||||||
const TString* blockName;
|
const TString* blockName;
|
||||||
TQualifier currentBlockQualifier;
|
TQualifier currentBlockQualifier;
|
||||||
TPrecisionQualifier defaultPrecision[EbtNumTypes];
|
TPrecisionQualifier defaultPrecision[EbtNumTypes];
|
||||||
|
|||||||
@ -2777,7 +2777,7 @@ jump_statement
|
|||||||
if (parseContext.currentFunctionType->getBasicType() != EbtVoid)
|
if (parseContext.currentFunctionType->getBasicType() != EbtVoid)
|
||||||
parseContext.error($1.loc, "non-void function must return a value", "return", "");
|
parseContext.error($1.loc, "non-void function must return a value", "return", "");
|
||||||
if (parseContext.inMain)
|
if (parseContext.inMain)
|
||||||
parseContext.postMainReturn = true;
|
parseContext.postEntryPointReturn = true;
|
||||||
}
|
}
|
||||||
| RETURN expression SEMICOLON {
|
| RETURN expression SEMICOLON {
|
||||||
$$ = parseContext.handleReturnValue($1.loc, $2);
|
$$ = parseContext.handleReturnValue($1.loc, $2);
|
||||||
|
|||||||
@ -7704,7 +7704,7 @@ yyreduce:
|
|||||||
if (parseContext.currentFunctionType->getBasicType() != EbtVoid)
|
if (parseContext.currentFunctionType->getBasicType() != EbtVoid)
|
||||||
parseContext.error((yyvsp[-1].lex).loc, "non-void function must return a value", "return", "");
|
parseContext.error((yyvsp[-1].lex).loc, "non-void function must return a value", "return", "");
|
||||||
if (parseContext.inMain)
|
if (parseContext.inMain)
|
||||||
parseContext.postMainReturn = true;
|
parseContext.postEntryPointReturn = true;
|
||||||
}
|
}
|
||||||
#line 7710 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */
|
#line 7710 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -57,10 +57,7 @@ HlslParseContext::HlslParseContext(TSymbolTable& symbolTable, TIntermediate& int
|
|||||||
const TString sourceEntryPointName,
|
const TString sourceEntryPointName,
|
||||||
bool forwardCompatible, EShMessages messages) :
|
bool forwardCompatible, EShMessages messages) :
|
||||||
TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
||||||
contextPragma(true, false),
|
annotationNestingLevel(0),
|
||||||
loopNestingLevel(0), annotationNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
|
|
||||||
postEntryPointReturn(false),
|
|
||||||
limits(resources.limits),
|
|
||||||
inputPatch(nullptr),
|
inputPatch(nullptr),
|
||||||
builtInIoIndex(nullptr),
|
builtInIoIndex(nullptr),
|
||||||
builtInIoBase(nullptr),
|
builtInIoBase(nullptr),
|
||||||
@ -520,6 +517,9 @@ TIntermTyped* HlslParseContext::handleSamplerLvalue(const TSourceLoc& loc, const
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (controlFlowNestingLevel > 0)
|
||||||
|
error(loc, "can't alias sampler in control flow", op, "");
|
||||||
|
|
||||||
// Best is if we are aliasing a flattened struct member "S.s1 = s2",
|
// Best is if we are aliasing a flattened struct member "S.s1 = s2",
|
||||||
// in which case we want to update the flattening information with the alias,
|
// in which case we want to update the flattening information with the alias,
|
||||||
// making everything else work seamlessly.
|
// making everything else work seamlessly.
|
||||||
|
|||||||
@ -314,17 +314,7 @@ protected:
|
|||||||
TIntermSymbol* findLinkageSymbol(TBuiltInVariable biType) const;
|
TIntermSymbol* findLinkageSymbol(TBuiltInVariable biType) const;
|
||||||
|
|
||||||
// Current state of parsing
|
// Current state of parsing
|
||||||
struct TPragma contextPragma;
|
|
||||||
int loopNestingLevel; // 0 if outside all loops
|
|
||||||
int annotationNestingLevel; // 0 if outside all annotations
|
int annotationNestingLevel; // 0 if outside all annotations
|
||||||
int structNestingLevel; // 0 if outside blocks and structures
|
|
||||||
int controlFlowNestingLevel; // 0 if outside all flow control
|
|
||||||
TList<TIntermSequence*> switchSequenceStack; // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting
|
|
||||||
bool postEntryPointReturn; // if inside a function, true if the function is the entry point and this is after a return statement
|
|
||||||
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
|
||||||
bool functionReturnsValue; // true if a non-void function has a return
|
|
||||||
TBuiltInResource resources;
|
|
||||||
TLimits& limits;
|
|
||||||
|
|
||||||
HlslParseContext(HlslParseContext&);
|
HlslParseContext(HlslParseContext&);
|
||||||
HlslParseContext& operator=(HlslParseContext&);
|
HlslParseContext& operator=(HlslParseContext&);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user