--- /dev/null
+hlsl.scope.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:31 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
+0:2 Function Parameters:
+0:2 'input' (temp 4-component vector of float)
+0:? Sequence
+0:4 'x' (temp int)
+0:? Sequence
+0:7 'x' (temp float)
+0:? Sequence
+0:10 'x' (temp bool)
+0:? Sequence
+0:13 'x' (temp 3-component vector of float)
+0:15 'x' (temp bool)
+0:17 'x' (temp float)
+0:19 'x' (temp int)
+0:21 Test condition and select (temp void)
+0:21 Condition
+0:21 Compare Greater Than (temp bool)
+0:21 'x' (temp int)
+0:21 Constant:
+0:21 0 (const int)
+0:21 true case is null
+0:24 Loop with condition tested first
+0:24 Loop Condition
+0:24 Compare Greater Than (temp bool)
+0:24 'x' (temp int)
+0:24 Constant:
+0:24 0 (const int)
+0:24 No loop body
+0:27 Loop with condition not tested first
+0:27 Loop Condition
+0:29 Compare Greater Than (temp bool)
+0:29 'x' (temp int)
+0:29 Constant:
+0:29 0 (const int)
+0:27 No loop body
+0:? Linker Objects
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:31 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
+0:2 Function Parameters:
+0:2 'input' (temp 4-component vector of float)
+0:? Sequence
+0:4 'x' (temp int)
+0:? Sequence
+0:7 'x' (temp float)
+0:? Sequence
+0:10 'x' (temp bool)
+0:? Sequence
+0:13 'x' (temp 3-component vector of float)
+0:15 'x' (temp bool)
+0:17 'x' (temp float)
+0:19 'x' (temp int)
+0:21 Test condition and select (temp void)
+0:21 Condition
+0:21 Compare Greater Than (temp bool)
+0:21 'x' (temp int)
+0:21 Constant:
+0:21 0 (const int)
+0:21 true case is null
+0:24 Loop with condition tested first
+0:24 Loop Condition
+0:24 Compare Greater Than (temp bool)
+0:24 'x' (temp int)
+0:24 Constant:
+0:24 0 (const int)
+0:24 No loop body
+0:27 Loop with condition not tested first
+0:27 Loop Condition
+0:29 Compare Greater Than (temp bool)
+0:29 'x' (temp int)
+0:29 Constant:
+0:29 0 (const int)
+0:27 No loop body
+0:? Linker Objects
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 36
+
+ Capability Shader
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "PixelShaderFunction"
+ ExecutionMode 4 OriginUpperLeft
+ Source HLSL 450
+ Name 4 "PixelShaderFunction"
+ Name 8 "x"
+ Name 11 "x"
+ Name 14 "x"
+ Name 17 "x"
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 1
+ 7: TypePointer Function 6(int)
+ 9: TypeFloat 32
+ 10: TypePointer Function 9(float)
+ 12: TypeBool
+ 13: TypePointer Function 12(bool)
+ 15: TypeVector 9(float) 3
+ 16: TypePointer Function 15(fvec3)
+ 19: 6(int) Constant 0
+4(PixelShaderFunction): 2 Function None 3
+ 5: Label
+ 8(x): 7(ptr) Variable Function
+ 11(x): 10(ptr) Variable Function
+ 14(x): 13(ptr) Variable Function
+ 17(x): 16(ptr) Variable Function
+ 18: 6(int) Load 8(x)
+ 20: 12(bool) SGreaterThan 18 19
+ SelectionMerge 22 None
+ BranchConditional 20 21 22
+ 21: Label
+ Branch 22
+ 22: Label
+ Branch 23
+ 23: Label
+ LoopMerge 25 26 None
+ Branch 27
+ 27: Label
+ 28: 6(int) Load 8(x)
+ 29: 12(bool) SGreaterThan 28 19
+ BranchConditional 29 24 25
+ 24: Label
+ Branch 26
+ 26: Label
+ Branch 23
+ 25: Label
+ Branch 30
+ 30: Label
+ LoopMerge 32 33 None
+ Branch 31
+ 31: Label
+ Branch 33
+ 33: Label
+ 34: 6(int) Load 8(x)
+ 35: 12(bool) SGreaterThan 34 19
+ BranchConditional 35 30 32
+ 32: Label
+ Return
+ FunctionEnd
--- /dev/null
+float4 PixelShaderFunction(float4 input) : COLOR0
+{
+ int x;
+ x;
+ {
+ float x;
+ x;
+ {
+ bool x;
+ x;
+ {
+ float3 x;
+ x;
+ }
+ x;
+ }
+ x;
+ }
+ x;
+
+ if (x > 0)
+ bool x;
+
+ while (x > 0)
+ bool x;
+
+ do {
+ bool x;
+ } while (x > 0);
+}
{"hlsl.max.frag", "PixelShaderFunction"},
{"hlsl.precedence.frag", "PixelShaderFunction"},
{"hlsl.precedence2.frag", "PixelShaderFunction"},
+ {"hlsl.scope.frag", "PixelShaderFunction"},
{"hlsl.sin.frag", "PixelShaderFunction"},
{"hlsl.whileLoop.frag", "PixelShaderFunction"},
{"hlsl.void.frag", "PixelShaderFunction"},
// Otherwise, return false, and don't advance
bool HlslGrammar::acceptType(TType& type)
{
- if (! token.isType)
- return false;
-
switch (peek()) {
case EHTokVoid:
new(&type) TType(EbtVoid);
{
TFunction* functionDeclarator = parseContext.handleFunctionDeclarator(token.loc, function, false /* not prototype */);
- // This does a symbol table push
+ // This does a pushScope()
node = parseContext.handleFunctionDefinition(token.loc, *functionDeclarator);
// compound_statement
node = intermediate.growAggregate(node, functionBody);
intermediate.setAggregateOperator(node, EOpFunction, functionDeclarator->getType(), token.loc);
node->getAsAggregate()->setName(functionDeclarator->getMangledName().c_str());
- parseContext.symbolTable.pop(nullptr);
+ parseContext.popScope();
return true;
}
} else if (acceptIdentifier(idToken)) {
// identifier or function_call name
if (! peekTokenClass(EHTokLeftParen)) {
- node = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
+ node = parseContext.handleVariable(idToken.loc, token.string);
} else if (acceptFunctionCall(idToken, node)) {
// function_call (nothing else to do yet)
} else {
bool HlslGrammar::acceptScopedStatement(TIntermNode*& statement)
{
parseContext.pushScope();
- bool result = acceptNestedStatement(statement);
+ bool result = acceptStatement(statement);
parseContext.popScope();
return result;
}
-bool HlslGrammar::acceptNestedStatement(TIntermNode*& statement)
+bool HlslGrammar::acceptScopedCompoundStatement(TIntermNode*& statement)
{
- parseContext.nestStatement();
- bool result = acceptStatement(statement);
- parseContext.unnestStatement();
+ parseContext.pushScope();
+ bool result = acceptCompoundStatement(statement);
+ parseContext.popScope();
return result;
}
// attributed_statement
switch (peek()) {
case EHTokLeftBrace:
- return acceptCompoundStatement(statement);
+ return acceptScopedCompoundStatement(statement);
case EHTokIf:
return acceptSelectionStatement(statement);
bool acceptCompoundStatement(TIntermNode*&);
bool acceptStatement(TIntermNode*&);
bool acceptScopedStatement(TIntermNode*&);
+ bool acceptScopedCompoundStatement(TIntermNode*&);
bool acceptNestedStatement(TIntermNode*&);
void acceptAttributes();
bool acceptSelectionStatement(TIntermNode*&);
int version, EProfile profile, int spv, int vulkan, EShLanguage language, TInfoSink& infoSink,
bool forwardCompatible, EShMessages messages) :
TParseContextBase(symbolTable, interm, version, profile, spv, vulkan, language, infoSink, forwardCompatible, messages),
- contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0),
+ contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
postMainReturn(false),
limits(resources.limits),
afterEOF(false)
//
// Handle seeing a variable identifier in the grammar.
//
-TIntermTyped* HlslParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symbol, const TString* string)
+TIntermTyped* HlslParseContext::handleVariable(const TSourceLoc& loc, const TString* string)
{
+ TSymbol* symbol = symbolTable.find(*string);
TIntermTyped* node = nullptr;
// Error check for requiring specific extensions present.
//
// New symbol table scope for body of function plus its arguments
//
- symbolTable.push();
+ pushScope();
//
// Insert parameters into the symbol table.
}
intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), loc);
loopNestingLevel = 0;
- statementNestingLevel = 0;
controlFlowNestingLevel = 0;
postMainReturn = false;
bool builtInName(const TString&);
void handlePragma(const TSourceLoc&, const TVector<TString>&);
- TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
+ TIntermTyped* handleVariable(const TSourceLoc&, const TString* string);
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
void checkIndex(const TSourceLoc&, const TType&, int& index);
void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
- void nestStatement() { ++statementNestingLevel; }
- void unnestStatement() { --statementNestingLevel; }
void nestLooping() { ++loopNestingLevel; }
void unnestLooping() { --loopNestingLevel; }
void pushScope() { symbolTable.push(); }
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 inEntrypoint; // if inside a function, true if the function is the entry point
// Wrapper for tokenizeClass()"] = to get everything inside the token.
void HlslScanContext::tokenize(HlslToken& token)
{
- token.isType = false;
EHlslTokenClass tokenClass = tokenizeClass(token);
token.tokenClass = tokenClass;
- if (token.isType)
- afterType = true;
}
//
loc = ppToken.loc;
parserToken->loc = loc;
switch (ppToken.token) {
- case ';': afterType = false; return EHTokSemicolon;
- case ',': afterType = false; return EHTokComma;
+ case ';': return EHTokSemicolon;
+ case ',': return EHTokComma;
case ':': return EHTokColon;
- case '=': afterType = false; return EHTokAssign;
- case '(': afterType = false; return EHTokLeftParen;
- case ')': afterType = false; return EHTokRightParen;
- case '.': field = true; return EHTokDot;
+ case '=': return EHTokAssign;
+ case '(': return EHTokLeftParen;
+ case ')': return EHTokRightParen;
+ case '.': return EHTokDot;
case '!': return EHTokBang;
case '-': return EHTokDash;
case '~': return EHTokTilde;
case PpAtomIdentifier:
{
EHlslTokenClass token = tokenizeIdentifier();
- field = false;
return token;
}
case EHTokDouble4x2:
case EHTokDouble4x3:
case EHTokDouble4x4:
- parserToken->isType = true;
return keyword;
// texturing types
case EHTokTexture2darray:
case EHTokTexture3d:
case EHTokTextureCube:
- parserToken->isType = true;
return keyword;
// variable, user type, ...
EHlslTokenClass HlslScanContext::identifierOrType()
{
parserToken->string = NewPoolTString(tokenText);
- if (field)
- return EHTokIdentifier;
-
- parserToken->symbol = parseContext.symbolTable.find(*parserToken->string);
- if (afterType == false && parserToken->symbol) {
- if (const TVariable* variable = parserToken->symbol->getAsVariable()) {
- if (variable->isUserType()) {
- afterType = true;
-
- return EHTokTypeName;
- }
- }
- }
return EHTokIdentifier;
}
// Everything needed to fully describe a token.
//
struct HlslToken {
- HlslToken() : isType(false), string(nullptr), symbol(nullptr) { loc.init(); }
+ HlslToken() : string(nullptr) { loc.init(); }
TSourceLoc loc; // location of token in the source
EHlslTokenClass tokenClass; // what kind of token it is
- bool isType; // true if the token represents a type
union { // what data the token holds
glslang::TString *string; // for identifiers
int i; // for literals
bool b;
double d;
};
- glslang::TSymbol* symbol; // if a symbol table lookup was done already, this is the result
};
//
class HlslScanContext {
public:
HlslScanContext(TParseContextBase& parseContext, TPpContext& ppContext)
- : parseContext(parseContext), ppContext(ppContext), afterType(false), field(false) { }
+ : parseContext(parseContext), ppContext(ppContext) { }
virtual ~HlslScanContext() { }
static void fillInKeywordMap();
TParseContextBase& parseContext;
TPpContext& ppContext;
- bool afterType; // true if we've recognized a type, so can only be looking for an identifier
- bool field; // true if we're on a field, right after a '.'
TSourceLoc loc;
TPpToken* ppToken;
HlslToken* parserToken;