Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
glslang
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
glslang
Commits
54ee28f4
Commit
54ee28f4
authored
Mar 11, 2017
by
John Kessenich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
HLSL: Add scoping operator, accept static member functions, and support calling them.
parent
5f12d2f7
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
427 additions
and
53 deletions
+427
-53
hlsl.staticMemberFunction.frag.out
Test/baseResults/hlsl.staticMemberFunction.frag.out
+199
-0
hlsl.staticMemberFunction.frag
Test/hlsl.staticMemberFunction.frag
+22
-0
intermediate.h
glslang/Include/intermediate.h
+1
-0
Hlsl.FromFile.cpp
gtests/Hlsl.FromFile.cpp
+1
-0
hlslGrammar.cpp
hlsl/hlslGrammar.cpp
+141
-49
hlslGrammar.h
hlsl/hlslGrammar.h
+8
-3
hlslOpMap.cpp
hlsl/hlslOpMap.cpp
+2
-0
hlslParseHelper.cpp
hlsl/hlslParseHelper.cpp
+46
-0
hlslParseHelper.h
hlsl/hlslParseHelper.h
+5
-0
hlslScanContext.cpp
hlsl/hlslScanContext.cpp
+2
-0
hlslTokens.h
hlsl/hlslTokens.h
+0
-1
No files found.
Test/baseResults/hlsl.staticMemberFunction.frag.out
0 → 100755
View file @
54ee28f4
hlsl.staticMemberFunction.frag
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:5 Function Definition: Test::staticMemFun(vf4; (global 4-component vector of float)
0:5 Function Parameters:
0:5 'a' (in 4-component vector of float)
0:? Sequence
0:6 Branch: Return with expression
0:6 vector-scale (temp 4-component vector of float)
0:6 Constant:
0:6 2.000000
0:6 'a' (in 4-component vector of float)
0:9 Function Definition: Test::staticMemFun(i1; (global int)
0:9 Function Parameters:
0:9 'a' (in int)
0:? Sequence
0:10 Branch: Return with expression
0:10 add (temp int)
0:10 Constant:
0:10 2 (const int)
0:10 'a' (in int)
0:16 Function Definition: @main( (temp 4-component vector of float)
0:16 Function Parameters:
0:? Sequence
0:18 Sequence
0:18 move second child to first child (temp 4-component vector of float)
0:18 'f4' (temp 4-component vector of float)
0:? Constant:
0:? 1.000000
0:? 1.000000
0:? 1.000000
0:? 1.000000
0:19 add second child into first child (temp 4-component vector of float)
0:19 'f4' (temp 4-component vector of float)
0:19 Function Call: Test::staticMemFun(vf4; (global 4-component vector of float)
0:? Constant:
0:? 5.000000
0:? 5.000000
0:? 5.000000
0:? 5.000000
0:20 add second child into first child (temp 4-component vector of float)
0:20 'f4' (temp 4-component vector of float)
0:20 Convert int to float (temp float)
0:20 Function Call: Test::staticMemFun(i1; (global int)
0:20 Constant:
0:20 7 (const int)
0:21 Branch: Return with expression
0:21 'f4' (temp 4-component vector of float)
0:16 Function Definition: main( (temp void)
0:16 Function Parameters:
0:? Sequence
0:16 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:16 Function Call: @main( (temp 4-component vector of float)
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
Linked fragment stage:
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:5 Function Definition: Test::staticMemFun(vf4; (global 4-component vector of float)
0:5 Function Parameters:
0:5 'a' (in 4-component vector of float)
0:? Sequence
0:6 Branch: Return with expression
0:6 vector-scale (temp 4-component vector of float)
0:6 Constant:
0:6 2.000000
0:6 'a' (in 4-component vector of float)
0:9 Function Definition: Test::staticMemFun(i1; (global int)
0:9 Function Parameters:
0:9 'a' (in int)
0:? Sequence
0:10 Branch: Return with expression
0:10 add (temp int)
0:10 Constant:
0:10 2 (const int)
0:10 'a' (in int)
0:16 Function Definition: @main( (temp 4-component vector of float)
0:16 Function Parameters:
0:? Sequence
0:18 Sequence
0:18 move second child to first child (temp 4-component vector of float)
0:18 'f4' (temp 4-component vector of float)
0:? Constant:
0:? 1.000000
0:? 1.000000
0:? 1.000000
0:? 1.000000
0:19 add second child into first child (temp 4-component vector of float)
0:19 'f4' (temp 4-component vector of float)
0:19 Function Call: Test::staticMemFun(vf4; (global 4-component vector of float)
0:? Constant:
0:? 5.000000
0:? 5.000000
0:? 5.000000
0:? 5.000000
0:20 add second child into first child (temp 4-component vector of float)
0:20 'f4' (temp 4-component vector of float)
0:20 Convert int to float (temp float)
0:20 Function Call: Test::staticMemFun(i1; (global int)
0:20 Constant:
0:20 7 (const int)
0:21 Branch: Return with expression
0:21 'f4' (temp 4-component vector of float)
0:16 Function Definition: main( (temp void)
0:16 Function Parameters:
0:? Sequence
0:16 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:16 Function Call: @main( (temp 4-component vector of float)
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 54
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 52
ExecutionMode 4 OriginUpperLeft
Name 4 "main"
Name 11 "Test::staticMemFun(vf4;"
Name 10 "a"
Name 17 "Test::staticMemFun(i1;"
Name 16 "a"
Name 20 "@main("
Name 32 "f4"
Name 37 "param"
Name 42 "param"
Name 52 "@entryPointOutput"
Decorate 52(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Function 7(fvec4)
9: TypeFunction 7(fvec4) 8(ptr)
13: TypeInt 32 1
14: TypePointer Function 13(int)
15: TypeFunction 13(int) 14(ptr)
19: TypeFunction 7(fvec4)
22: 6(float) Constant 1073741824
27: 13(int) Constant 2
33: 6(float) Constant 1065353216
34: 7(fvec4) ConstantComposite 33 33 33 33
35: 6(float) Constant 1084227584
36: 7(fvec4) ConstantComposite 35 35 35 35
41: 13(int) Constant 7
51: TypePointer Output 7(fvec4)
52(@entryPointOutput): 51(ptr) Variable Output
4(main): 2 Function None 3
5: Label
53: 7(fvec4) FunctionCall 20(@main()
Store 52(@entryPointOutput) 53
Return
FunctionEnd
11(Test::staticMemFun(vf4;): 7(fvec4) Function None 9
10(a): 8(ptr) FunctionParameter
12: Label
23: 7(fvec4) Load 10(a)
24: 7(fvec4) VectorTimesScalar 23 22
ReturnValue 24
FunctionEnd
17(Test::staticMemFun(i1;): 13(int) Function None 15
16(a): 14(ptr) FunctionParameter
18: Label
28: 13(int) Load 16(a)
29: 13(int) IAdd 27 28
ReturnValue 29
FunctionEnd
20(@main(): 7(fvec4) Function None 19
21: Label
32(f4): 8(ptr) Variable Function
37(param): 8(ptr) Variable Function
42(param): 14(ptr) Variable Function
Store 32(f4) 34
Store 37(param) 36
38: 7(fvec4) FunctionCall 11(Test::staticMemFun(vf4;) 37(param)
39: 7(fvec4) Load 32(f4)
40: 7(fvec4) FAdd 39 38
Store 32(f4) 40
Store 42(param) 41
43: 13(int) FunctionCall 17(Test::staticMemFun(i1;) 42(param)
44: 6(float) ConvertSToF 43
45: 7(fvec4) Load 32(f4)
46: 7(fvec4) CompositeConstruct 44 44 44 44
47: 7(fvec4) FAdd 45 46
Store 32(f4) 47
48: 7(fvec4) Load 32(f4)
ReturnValue 48
FunctionEnd
Test/hlsl.staticMemberFunction.frag
0 → 100755
View file @
54ee28f4
struct
Test
{
float4
memVar
;
static
float4
staticMemFun
(
float4
a
)
:
SV_Position
{
return
2
*
a
;
}
static
int
staticMemFun
(
int
a
)
:
SV_Position
{
return
2
+
a
;
}
int
i
;
};
float4
main
()
:
SV_Target0
{
Test
test
;
float4
f4
=
float4
(
1
.
0
,
1
.
0
,
1
.
0
,
1
.
0
);
f4
+=
Test
::
staticMemFun
(
float4
(
5
.
0
f
,
5
.
0
f
,
5
.
0
f
,
5
.
0
f
));
f4
+=
Test
::
staticMemFun
(
7
);
return
f4
;
}
glslang/Include/intermediate.h
View file @
54ee28f4
...
...
@@ -183,6 +183,7 @@ enum TOperator {
EOpVectorSwizzle
,
EOpMethod
,
EOpScoping
,
//
// Built-in functions mapped to operators
...
...
gtests/Hlsl.FromFile.cpp
View file @
54ee28f4
...
...
@@ -212,6 +212,7 @@ INSTANTIATE_TEST_CASE_P(
{
"hlsl.semicolons.frag"
,
"main"
},
{
"hlsl.shapeConv.frag"
,
"main"
},
{
"hlsl.shapeConvRet.frag"
,
"main"
},
{
"hlsl.staticMemberFunction.frag"
,
"main"
},
{
"hlsl.stringtoken.frag"
,
"main"
},
{
"hlsl.string.frag"
,
"main"
},
{
"hlsl.struct.split-1.vert"
,
"main"
},
...
...
hlsl/hlslGrammar.cpp
View file @
54ee28f4
...
...
@@ -298,7 +298,7 @@ bool HlslGrammar::acceptSamplerDeclarationDX9(TType& /*type*/)
//
bool
HlslGrammar
::
acceptDeclaration
(
TIntermNode
*&
nodeList
)
{
bool
list
=
false
;
bool
declarator_list
=
false
;
// true when processing comma separation
// attributes
TAttributeMap
attributes
;
...
...
@@ -319,7 +319,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
// return true;
// fully_specified_type
if
(
!
acceptFullySpecifiedType
(
declaredType
))
if
(
!
acceptFullySpecifiedType
(
declaredType
,
nodeList
))
return
false
;
// identifier
...
...
@@ -345,7 +345,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
// compound_statement (function body definition) or just a prototype?
if
(
peekTokenClass
(
EHTokLeftBrace
))
{
if
(
list
)
if
(
declarator_
list
)
parseContext
.
error
(
idToken
.
loc
,
"function body can't be in a declarator list"
,
"{"
,
""
);
if
(
typedefDecl
)
parseContext
.
error
(
idToken
.
loc
,
"function body can't be in a typedef"
,
"{"
,
""
);
...
...
@@ -427,7 +427,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
}
if
(
acceptTokenClass
(
EHTokComma
))
{
list
=
true
;
declarator_
list
=
true
;
continue
;
}
};
...
...
@@ -508,6 +508,11 @@ bool HlslGrammar::acceptControlDeclaration(TIntermNode*& node)
//
bool
HlslGrammar
::
acceptFullySpecifiedType
(
TType
&
type
)
{
TIntermNode
*
nodeList
=
nullptr
;
return
acceptFullySpecifiedType
(
type
,
nodeList
);
}
bool
HlslGrammar
::
acceptFullySpecifiedType
(
TType
&
type
,
TIntermNode
*&
nodeList
)
{
// type_qualifier
TQualifier
qualifier
;
qualifier
.
clear
();
...
...
@@ -516,7 +521,7 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type)
TSourceLoc
loc
=
token
.
loc
;
// type_specifier
if
(
!
acceptType
(
type
))
{
if
(
!
acceptType
(
type
,
nodeList
))
{
// If this is not a type, we may have inadvertently gone down a wrong path
// by parsing "sample", which can be treated like either an identifier or a
// qualifier. Back it out, if we did.
...
...
@@ -1188,6 +1193,11 @@ bool HlslGrammar::acceptTextureType(TType& type)
// Otherwise, return false, and don't advance
bool
HlslGrammar
::
acceptType
(
TType
&
type
)
{
TIntermNode
*
nodeList
=
nullptr
;
return
acceptType
(
type
,
nodeList
);
}
bool
HlslGrammar
::
acceptType
(
TType
&
type
,
TIntermNode
*&
nodeList
)
{
// Basic types for min* types, broken out here in case of future
// changes, e.g, to use native halfs.
static
const
TBasicType
min16float_bt
=
EbtFloat
;
...
...
@@ -1271,7 +1281,7 @@ bool HlslGrammar::acceptType(TType& type)
case
EHTokStruct
:
case
EHTokCBuffer
:
case
EHTokTBuffer
:
return
acceptStruct
(
type
);
return
acceptStruct
(
type
,
nodeList
);
case
EHTokIdentifier
:
// An identifier could be for a user-defined type.
...
...
@@ -1745,7 +1755,7 @@ bool HlslGrammar::acceptType(TType& type)
// | CBUFFER
// | TBUFFER
//
bool
HlslGrammar
::
acceptStruct
(
TType
&
type
)
bool
HlslGrammar
::
acceptStruct
(
TType
&
type
,
TIntermNode
*&
nodeList
)
{
// This storage qualifier will tell us whether it's an AST
// block type or just a generic structure type.
...
...
@@ -1788,7 +1798,7 @@ bool HlslGrammar::acceptStruct(TType& type)
// struct_declaration_list
TTypeList
*
typeList
;
if
(
!
acceptStructDeclarationList
(
typeList
))
{
if
(
!
acceptStructDeclarationList
(
typeList
,
nodeList
,
structName
))
{
expected
(
"struct member declarations"
);
return
false
;
}
...
...
@@ -1913,12 +1923,14 @@ bool HlslGrammar::acceptStructBufferType(TType& type)
//
// struct_declaration
// : fully_specified_type struct_declarator COMMA struct_declarator ...
// | fully_specified_type IDENTIFIER function_parameters post_decls compound_statement // member-function definition
//
// struct_declarator
// : IDENTIFIER post_decls
// | IDENTIFIER array_specifier post_decls
// | IDENTIFIER function_parameters post_decls // member-function prototype
//
bool
HlslGrammar
::
acceptStructDeclarationList
(
TTypeList
*&
typeList
)
bool
HlslGrammar
::
acceptStructDeclarationList
(
TTypeList
*&
typeList
,
TIntermNode
*&
nodeList
,
const
TString
&
typeName
)
{
typeList
=
new
TTypeList
();
HlslToken
idToken
;
...
...
@@ -1929,51 +1941,66 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
return
true
;
// struct_declaration
bool
declarator_list
=
false
;
// fully_specified_type
TType
memberType
;
if
(
!
acceptFullySpecifiedType
(
memberType
))
{
if
(
!
acceptFullySpecifiedType
(
memberType
,
nodeList
))
{
expected
(
"member type"
);
return
false
;
}
// struct_declarator COMMA struct_declarator ...
bool
functionDefinitionAccepted
=
false
;
do
{
if
(
!
acceptIdentifier
(
idToken
))
{
expected
(
"member name"
);
return
false
;
}
// add it to the list of members
TTypeLoc
member
=
{
new
TType
(
EbtVoid
),
token
.
loc
};
member
.
type
->
shallowCopy
(
memberType
);
member
.
type
->
setFieldName
(
*
idToken
.
string
);
typeList
->
push_back
(
member
);
// array_specifier
TArraySizes
*
arraySizes
=
nullptr
;
acceptArraySpecifier
(
arraySizes
);
if
(
arraySizes
)
typeList
->
back
().
type
->
newArraySizes
(
*
arraySizes
);
acceptPostDecls
(
member
.
type
->
getQualifier
());
// EQUAL assignment_expression
if
(
acceptTokenClass
(
EHTokAssign
))
{
parseContext
.
warn
(
idToken
.
loc
,
"struct-member initializers ignored"
,
"typedef"
,
""
);
TIntermTyped
*
expressionNode
=
nullptr
;
if
(
!
acceptAssignmentExpression
(
expressionNode
))
{
expected
(
"initializer"
);
return
false
;
if
(
peekTokenClass
(
EHTokLeftParen
))
{
// function_parameters
if
(
!
declarator_list
)
{
functionDefinitionAccepted
=
acceptMemberFunctionDefinition
(
nodeList
,
typeName
,
memberType
,
*
idToken
.
string
);
if
(
functionDefinitionAccepted
)
break
;
}
expected
(
"member-function definition"
);
return
false
;
}
else
{
// add it to the list of members
TTypeLoc
member
=
{
new
TType
(
EbtVoid
),
token
.
loc
};
member
.
type
->
shallowCopy
(
memberType
);
member
.
type
->
setFieldName
(
*
idToken
.
string
);
typeList
->
push_back
(
member
);
// array_specifier
TArraySizes
*
arraySizes
=
nullptr
;
acceptArraySpecifier
(
arraySizes
);
if
(
arraySizes
)
typeList
->
back
().
type
->
newArraySizes
(
*
arraySizes
);
acceptPostDecls
(
member
.
type
->
getQualifier
());
// EQUAL assignment_expression
if
(
acceptTokenClass
(
EHTokAssign
))
{
parseContext
.
warn
(
idToken
.
loc
,
"struct-member initializers ignored"
,
"typedef"
,
""
);
TIntermTyped
*
expressionNode
=
nullptr
;
if
(
!
acceptAssignmentExpression
(
expressionNode
))
{
expected
(
"initializer"
);
return
false
;
}
}
}
// success on seeing the SEMICOLON coming up
if
(
peekTokenClass
(
EHTokSemicolon
))
break
;
// COMMA
if
(
!
acceptTokenClass
(
EHTokComma
))
{
if
(
acceptTokenClass
(
EHTokComma
))
declarator_list
=
true
;
else
{
expected
(
","
);
return
false
;
}
...
...
@@ -1981,7 +2008,7 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
}
while
(
true
);
// SEMI_COLON
if
(
!
acceptTokenClass
(
EHTokSemicolon
))
{
if
(
!
functionDefinitionAccepted
&&
!
acceptTokenClass
(
EHTokSemicolon
))
{
expected
(
";"
);
return
false
;
}
...
...
@@ -1989,6 +2016,43 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
}
while
(
true
);
}
// member_function_definition
// | function_parameters post_decls compound_statement
//
// Expects type to have EvqGlobal for a static member and
// EvqTemporary for non-static member.
bool
HlslGrammar
::
acceptMemberFunctionDefinition
(
TIntermNode
*&
nodeList
,
const
TString
&
typeName
,
const
TType
&
type
,
const
TString
&
memberName
)
{
// watch early returns...
parseContext
.
pushThis
(
typeName
);
bool
accepted
=
false
;
TString
*
functionName
=
parseContext
.
getFullMemberFunctionName
(
memberName
,
type
.
getQualifier
().
storage
==
EvqGlobal
);
TFunction
&
function
=
*
new
TFunction
(
functionName
,
type
);
// function_parameters
if
(
acceptFunctionParameters
(
function
))
{
// post_decls
acceptPostDecls
(
function
.
getWritableType
().
getQualifier
());
// compound_statement (function body definition)
if
(
peekTokenClass
(
EHTokLeftBrace
))
{
if
(
function
.
getType
().
getQualifier
().
storage
!=
EvqGlobal
)
{
expected
(
"only static member functions are accepted"
);
return
false
;
}
TAttributeMap
attributes
;
accepted
=
acceptFunctionDefinition
(
function
,
nodeList
,
attributes
);
}
}
else
expected
(
"function parameter list"
);
parseContext
.
popThis
();
return
accepted
;
}
// function_parameters
// : LEFT_PAREN parameter_declaration COMMA parameter_declaration ... RIGHT_PAREN
// | LEFT_PAREN VOID RIGHT_PAREN
...
...
@@ -2133,6 +2197,7 @@ bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& no
if
(
!
acceptCompoundStatement
(
functionBody
))
return
false
;
// this does a popScope()
parseContext
.
handleFunctionBody
(
loc
,
functionDeclarator
,
functionBody
,
functionNode
);
// Hook up the 1 or 2 function definitions.
...
...
@@ -2490,17 +2555,21 @@ bool HlslGrammar::acceptUnaryExpression(TIntermTyped*& node)
// | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET
// | postfix_expression DOT IDENTIFIER
// | postfix_expression DOT IDENTIFIER arguments
// | postfix_expression COLONCOLON IDENTIFIER arguments
// | postfix_expression INC_OP
// | postfix_expression DEC_OP
//
bool
HlslGrammar
::
acceptPostfixExpression
(
TIntermTyped
*&
node
)
{
// Not implemented as self-recursive:
// The logical "right recursion" is done with a
n
loop at the end
// The logical "right recursion" is done with a loop at the end
// idToken will pick up either a variable or a function name in a function call
HlslToken
idToken
;
// scopeBase will pick up the type symbol on the left of '::'
TSymbol
*
scopeBase
=
nullptr
;
// Find something before the postfix operations, as they can't operate
// on nothing. So, no "return true", they fall through, only "return false".
if
(
acceptTokenClass
(
EHTokLeftParen
))
{
...
...
@@ -2518,8 +2587,15 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
}
else
if
(
acceptConstructor
(
node
))
{
// constructor (nothing else to do yet)
}
else
if
(
acceptIdentifier
(
idToken
))
{
// identifier or function_call name
if
(
!
peekTokenClass
(
EHTokLeftParen
))
{
// user-type, identifier, or function name
if
(
peekTokenClass
(
EHTokColonColon
))
{
TType
type
;
scopeBase
=
parseContext
.
lookupUserType
(
*
idToken
.
string
,
type
);
if
(
scopeBase
==
nullptr
)
{
expected
(
"type left of ::"
);
return
false
;
}
}
else
if
(
!
peekTokenClass
(
EHTokLeftParen
))
{
node
=
parseContext
.
handleVariable
(
idToken
.
loc
,
idToken
.
symbol
,
idToken
.
string
);
}
else
if
(
acceptFunctionCall
(
idToken
,
node
))
{
// function_call (nothing else to do yet)
...
...
@@ -2560,6 +2636,7 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
case
EOpIndexIndirect
:
case
EOpPostIncrement
:
case
EOpPostDecrement
:
case
EOpScoping
:
advanceToken
();
break
;
default
:
...
...
@@ -2568,6 +2645,7 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
// We have a valid post-unary operator, process it.
switch
(
postOp
)
{
case
EOpScoping
:
case
EOpIndexDirectStruct
:
{
// DOT IDENTIFIER
...
...
@@ -2583,7 +2661,7 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
TIntermTyped
*
thisNode
=
node
;
// arguments
if
(
!
acceptFunctionCall
(
field
,
node
,
thisNode
))
{
if
(
!
acceptFunctionCall
(
field
,
node
,
thisNode
,
scopeBase
))
{
expected
(
"function parameters"
);
return
false
;
}
...
...
@@ -2655,24 +2733,38 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
// function_call
// : [idToken] arguments
//
bool
HlslGrammar
::
acceptFunctionCall
(
HlslToken
callToken
,
TIntermTyped
*&
node
,
TIntermTyped
*
base
)
bool
HlslGrammar
::
acceptFunctionCall
(
HlslToken
callToken
,
TIntermTyped
*&
node
,
TIntermTyped
*
baseObject
,
const
TSymbol
*
baseType
)
{
// arguments
TFunction
*
function
=
new
TFunction
(
callToken
.
string
,
TType
(
EbtVoid
));
TIntermTyped
*
arguments
=
nullptr
;
// member functions have an implicit first argument of the calling object.
if
(
base
!=
nullptr
)
{
if
(
!
parseContext
.
isBuiltInMethod
(
callToken
.
loc
,
node
,
*
callToken
.
string
))
{
expected
(
"built-in method"
);
return
false
;
// name
TString
*
functionName
=
nullptr
;
if
((
baseObject
==
nullptr
&&
baseType
==
nullptr
)
||
parseContext
.
isBuiltInMethod
(
callToken
.
loc
,
baseObject
,
*
callToken
.
string
))
functionName
=
callToken
.
string
;
else
{
functionName
=
NewPoolTString
(
""
);
if
(
baseObject
!=
nullptr
)
{
functionName
->
append
(
baseObject
->
getType
().
getTypeName
().
c_str
());
functionName
->
append
(
"."
);
}
else
if
(
baseType
!=
nullptr
)
{
functionName
->
append
(
baseType
->
getType
().
getTypeName
());
functionName
->
append
(
"::"
);
}
parseContext
.
handleFunctionArgument
(
function
,
arguments
,
base
);
functionName
->
append
(
*
callToken
.
string
);
}
// function
TFunction
*
function
=
new
TFunction
(
functionName
,
TType
(
EbtVoid
));
// arguments
// Non-static member functions have an implicit first argument of the base object.
TIntermTyped
*
arguments
=
nullptr
;
if
(
baseObject
!=
nullptr
)
parseContext
.
handleFunctionArgument
(
function
,
arguments
,
baseObject
);
if
(
!
acceptArguments
(
function
,
arguments
))
return
false
;
// call
node
=
parseContext
.
handleFunctionCall
(
callToken
.
loc
,
function
,
arguments
);
return
true
;
...
...
hlsl/hlslGrammar.h
View file @
54ee28f4
...
...
@@ -69,9 +69,11 @@ namespace glslang {
bool
acceptSamplerDeclarationDX9
(
TType
&
);
bool
acceptSamplerState
();
bool
acceptFullySpecifiedType
(
TType
&
);
bool
acceptFullySpecifiedType
(
TType
&
,
TIntermNode
*&
nodeList
);
bool
acceptQualifier
(
TQualifier
&
);
bool
acceptLayoutQualifierList
(
TQualifier
&
);
bool
acceptType
(
TType
&
);
bool
acceptType
(
TType
&
,
TIntermNode
*&
nodeList
);
bool
acceptTemplateVecMatBasicType
(
TBasicType
&
);
bool
acceptVectorTemplateType
(
TType
&
);
bool
acceptMatrixTemplateType
(
TType
&
);
...
...
@@ -83,8 +85,10 @@ namespace glslang {
bool
acceptSamplerType
(
TType
&
);
bool
acceptTextureType
(
TType
&
);
bool
acceptStructBufferType
(
TType
&
);
bool
acceptStruct
(
TType
&
);
bool
acceptStructDeclarationList
(
TTypeList
*&
);
bool
acceptStruct
(
TType
&
,
TIntermNode
*&
nodeList
);
bool
acceptStructDeclarationList
(
TTypeList
*&
,
TIntermNode
*&
nodeList
,
const
TString
&
typeName
);
bool
acceptMemberFunctionDefinition
(
TIntermNode
*&
nodeList
,
const
TString
&
typeName
,
const
TType
&
,
const
TString
&
memberName
);
bool
acceptFunctionParameters
(
TFunction
&
);
bool
acceptParameterDeclaration
(
TFunction
&
);
bool
acceptFunctionDefinition
(
TFunction
&
,
TIntermNode
*&
nodeList
,
const
TAttributeMap
&
);
...
...
@@ -97,7 +101,8 @@ namespace glslang {
bool
acceptUnaryExpression
(
TIntermTyped
*&
);
bool
acceptPostfixExpression
(
TIntermTyped
*&
);
bool
acceptConstructor
(
TIntermTyped
*&
);
bool
acceptFunctionCall
(
HlslToken
,
TIntermTyped
*&
,
TIntermTyped
*
base
=
nullptr
);
bool
acceptFunctionCall
(
HlslToken
,
TIntermTyped
*&
,
TIntermTyped
*
objectBase
=
nullptr
,
const
TSymbol
*
typeBase
=
nullptr
);
bool
acceptArguments
(
TFunction
*
,
TIntermTyped
*&
);
bool
acceptLiteral
(
TIntermTyped
*&
);
bool
acceptCompoundStatement
(
TIntermNode
*&
);
...
...
hlsl/hlslOpMap.cpp
View file @
54ee28f4
...
...
@@ -118,6 +118,8 @@ TOperator HlslOpMap::postUnary(EHlslTokenClass op)
case
EHTokIncOp
:
return
EOpPostIncrement
;
case
EHTokDecOp
:
return
EOpPostDecrement
;
case
EHTokColonColon
:
return
EOpScoping
;
default
:
return
EOpNull
;
// means not a post-unary op
}
}
...
...
hlsl/hlslParseHelper.cpp
View file @
54ee28f4
...
...
@@ -958,6 +958,9 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
//
bool
HlslParseContext
::
isBuiltInMethod
(
const
TSourceLoc
&
loc
,
TIntermTyped
*
base
,
const
TString
&
field
)
{
if
(
base
==
nullptr
)
return
false
;
variableCheck
(
base
);
if
(
base
->
getType
().
getBasicType
()
==
EbtSampler
)
{
...
...
@@ -7086,6 +7089,49 @@ TIntermNode* HlslParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* ex
return
switchNode
;
}
// Track levels of class/struct nesting with a prefix string using
// the type names separated by the scoping operator. E.g., two levels
// would look like:
//
// outer::inner
//
// The string is empty when at normal global level.
//
void
HlslParseContext
::
pushThis
(
const
TString
&
typeName
)
{
// make new type prefix
TString
newPrefix
;
if
(
currentTypePrefix
.
size
()
>
0
)
{
newPrefix
=
currentTypePrefix
.
back
();
newPrefix
.
append
(
"::"
);
}
newPrefix
.
append
(
typeName
);
currentTypePrefix
.
push_back
(
newPrefix
);
}
// Opposite of pushThis(), see above
void
HlslParseContext
::
popThis
()
{
currentTypePrefix
.
pop_back
();
}
// Use the class/struct nesting string to create a global name for
// a member of a class/struct. Static members use "::" for the final
// step, while non-static members use ".".
TString
*
HlslParseContext
::
getFullMemberFunctionName
(
const
TString
&
memberName
,
bool
isStatic
)
const
{
TString
*
name
=
NewPoolTString
(
""
);
if
(
currentTypePrefix
.
size
()
>
0
)
name
->
append
(
currentTypePrefix
.
back
());
if
(
isStatic
)
name
->
append
(
"::"
);
else
name
->
append
(
"."
);
name
->
append
(
memberName
);
return
name
;
}
// Potentially rename shader entry point function
void
HlslParseContext
::
renameShaderFunction
(
TString
*&
name
)
const
{
...
...
hlsl/hlslParseHelper.h
View file @
54ee28f4
...
...
@@ -160,6 +160,10 @@ public:
void
pushScope
()
{
symbolTable
.
push
();
}
void
popScope
()
{
symbolTable
.
pop
(
0
);
}
void
pushThis
(
const
TString
&
name
);
void
popThis
();
TString
*
getFullMemberFunctionName
(
const
TString
&
name
,
bool
isStatic
)
const
;
void
pushSwitchSequence
(
TIntermSequence
*
sequence
)
{
switchSequenceStack
.
push_back
(
sequence
);
}
void
popSwitchSequence
()
{
switchSequenceStack
.
pop_back
();
}
...
...
@@ -382,6 +386,7 @@ protected:
TString
patchConstantFunctionName
;
// hull shader patch constant function name, from function level attribute.
TMap
<
TBuiltInVariable
,
TSymbol
*>
builtInLinkageSymbols
;
// used for tessellation, finding declared builtins
TVector
<
TString
>
currentTypePrefix
;
};
}
// end namespace glslang
...
...
hlsl/hlslScanContext.cpp
View file @
54ee28f4
...
...
@@ -552,6 +552,8 @@ EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
case
PpAtomDecrement
:
return
EHTokDecOp
;
case
PpAtomIncrement
:
return
EHTokIncOp
;
case
PpAtomColonColon
:
return
EHTokColonColon
;
case
PpAtomConstInt
:
parserToken
->
i
=
ppToken
.
ival
;
return
EHTokIntConstant
;
case
PpAtomConstUint
:
parserToken
->
i
=
ppToken
.
ival
;
return
EHTokUintConstant
;
case
PpAtomConstFloat
:
parserToken
->
d
=
ppToken
.
dval
;
return
EHTokFloatConstant
;
...
...
hlsl/hlslTokens.h
View file @
54ee28f4
...
...
@@ -267,7 +267,6 @@ enum EHlslTokenClass {
// variable, user type, ...
EHTokIdentifier
,
EHTokTypeName
,
EHTokClass
,
EHTokStruct
,
EHTokCBuffer
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment