mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-08 11:30:06 +00:00
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,
|
||||
TInfoSink& infoSink, bool forwardCompatible, EShMessages 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), postMainReturn(false), currentFunctionType(nullptr), blockName(nullptr),
|
||||
inMain(false),
|
||||
blockName(nullptr),
|
||||
limits(resources.limits),
|
||||
atomicUintOffsets(nullptr), anyIndexLimits(false)
|
||||
{
|
||||
@ -912,7 +912,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc,
|
||||
loopNestingLevel = 0;
|
||||
statementNestingLevel = 0;
|
||||
controlFlowNestingLevel = 0;
|
||||
postMainReturn = false;
|
||||
postEntryPointReturn = false;
|
||||
|
||||
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", "", "");
|
||||
if (! inMain)
|
||||
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()", "", "");
|
||||
}
|
||||
break;
|
||||
|
@ -77,6 +77,10 @@ public:
|
||||
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages)
|
||||
: TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
||||
symbolTable(symbolTable),
|
||||
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
|
||||
postEntryPointReturn(false),
|
||||
contextPragma(true, false),
|
||||
limits(resources.limits),
|
||||
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
|
||||
globalUniformBlock(nullptr)
|
||||
{ }
|
||||
@ -133,8 +137,6 @@ public:
|
||||
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)
|
||||
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
|
||||
|
||||
@ -143,6 +145,23 @@ public:
|
||||
|
||||
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:
|
||||
TParseContextBase(TParseContextBase&);
|
||||
TParseContextBase& operator=(TParseContextBase&);
|
||||
@ -151,6 +170,8 @@ protected:
|
||||
TVector<TSymbol*> linkageSymbols; // these need to be transferred to 'linkage', after all editing is done
|
||||
TScanContext* scanContext;
|
||||
TPpContext* ppContext;
|
||||
TBuiltInResource resources;
|
||||
TLimits& limits;
|
||||
|
||||
// These, if set, will be called when a line, pragma ... is preprocessed.
|
||||
// They will be called with any parameters to the original directive.
|
||||
@ -384,17 +405,7 @@ public:
|
||||
//
|
||||
|
||||
// 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 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;
|
||||
TQualifier currentBlockQualifier;
|
||||
TPrecisionQualifier defaultPrecision[EbtNumTypes];
|
||||
|
@ -2777,7 +2777,7 @@ jump_statement
|
||||
if (parseContext.currentFunctionType->getBasicType() != EbtVoid)
|
||||
parseContext.error($1.loc, "non-void function must return a value", "return", "");
|
||||
if (parseContext.inMain)
|
||||
parseContext.postMainReturn = true;
|
||||
parseContext.postEntryPointReturn = true;
|
||||
}
|
||||
| RETURN expression SEMICOLON {
|
||||
$$ = parseContext.handleReturnValue($1.loc, $2);
|
||||
|
@ -7704,7 +7704,7 @@ yyreduce:
|
||||
if (parseContext.currentFunctionType->getBasicType() != EbtVoid)
|
||||
parseContext.error((yyvsp[-1].lex).loc, "non-void function must return a value", "return", "");
|
||||
if (parseContext.inMain)
|
||||
parseContext.postMainReturn = true;
|
||||
parseContext.postEntryPointReturn = true;
|
||||
}
|
||||
#line 7710 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */
|
||||
break;
|
||||
|
@ -57,10 +57,7 @@ HlslParseContext::HlslParseContext(TSymbolTable& symbolTable, TIntermediate& int
|
||||
const TString sourceEntryPointName,
|
||||
bool forwardCompatible, EShMessages messages) :
|
||||
TParseContextBase(symbolTable, interm, parsingBuiltins, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
||||
contextPragma(true, false),
|
||||
loopNestingLevel(0), annotationNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
|
||||
postEntryPointReturn(false),
|
||||
limits(resources.limits),
|
||||
annotationNestingLevel(0),
|
||||
inputPatch(nullptr),
|
||||
builtInIoIndex(nullptr),
|
||||
builtInIoBase(nullptr),
|
||||
@ -520,6 +517,9 @@ TIntermTyped* HlslParseContext::handleSamplerLvalue(const TSourceLoc& loc, const
|
||||
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",
|
||||
// in which case we want to update the flattening information with the alias,
|
||||
// making everything else work seamlessly.
|
||||
|
@ -314,17 +314,7 @@ protected:
|
||||
TIntermSymbol* findLinkageSymbol(TBuiltInVariable biType) const;
|
||||
|
||||
// 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<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& operator=(HlslParseContext&);
|
||||
|
Loading…
Reference in New Issue
Block a user