HLSL default function parameters
authorsteve-lunarg <steve_gh@khasekhemwy.net>
Sat, 24 Dec 2016 01:56:57 +0000 (18:56 -0700)
committersteve-lunarg <steve_gh@khasekhemwy.net>
Thu, 29 Dec 2016 19:15:48 +0000 (12:15 -0700)
This PR adds support for default function parameters in the following cases:

1. Simple constants, such as void fn(int x, float myparam = 3)
2. Expressions that can be const folded, such a ... myparam = sin(some_const)
3. Initializer lists that can be const folded, such as ... float2 myparam = {1,2}

New tests are added: hlsl.params.default.frag and hlsl.params.default.err.frag
(for testing error situations, such as ambiguity or non-const-foldable).

In order to avoid sampler method ambiguity, the hlsl better() lambda now
considers sampler matches.  Previously, all sampler types looked identical
since only the basic type of EbtSampler was considered.

15 files changed:
Test/baseResults/hlsl.intrinsics.negative.frag.out
Test/baseResults/hlsl.params.default.frag.out [new file with mode: 0644]
Test/baseResults/hlsl.params.default.negative.frag.out [new file with mode: 0644]
Test/hlsl.params.default.frag [new file with mode: 0644]
Test/hlsl.params.default.negative.frag [new file with mode: 0644]
glslang/MachineIndependent/Constant.cpp
glslang/MachineIndependent/ParseContextBase.cpp
glslang/MachineIndependent/SymbolTable.cpp
glslang/MachineIndependent/SymbolTable.h
gtests/Hlsl.FromFile.cpp
hlsl/hlslGrammar.cpp
hlsl/hlslGrammar.h
hlsl/hlslParseHelper.cpp
hlsl/hlslParseHelper.h
hlsl/hlslParseables.cpp

index e275054..0325c1c 100644 (file)
@@ -1,6 +1,10 @@
 hlsl.intrinsics.negative.frag
 ERROR: 0:10: 'determinant' : no matching overloaded function found 
 ERROR: 0:12: 'f32tof16' : unimplemented intrinsic: handle natively 
+ERROR: 0:23: 'length' : ambiguous best function under implicit type conversion 
+ERROR: 0:25: 'normalize' : ambiguous best function under implicit type conversion 
+ERROR: 0:26: 'reflect' : ambiguous best function under implicit type conversion 
+ERROR: 0:27: 'refract' : ambiguous best function under implicit type conversion 
 ERROR: 0:28: 'refract' : no matching overloaded function found 
 ERROR: 0:30: 'transpose' : no matching overloaded function found 
 ERROR: 0:39: 'GetRenderTargetSamplePosition' : no matching overloaded function found 
@@ -59,7 +63,7 @@ ERROR: 0:133: 'normalize' : no matching overloaded function found
 ERROR: 0:133: 'reflect' : no matching overloaded function found 
 ERROR: 0:133: 'refract' : no matching overloaded function found 
 ERROR: 0:133: 'reversebits' : no matching overloaded function found 
-ERROR: 60 compilation errors.  No code generated.
+ERROR: 64 compilation errors.  No code generated.
 
 
 Shader version: 450
diff --git a/Test/baseResults/hlsl.params.default.frag.out b/Test/baseResults/hlsl.params.default.frag.out
new file mode 100644 (file)
index 0000000..3c62c5d
--- /dev/null
@@ -0,0 +1,639 @@
+hlsl.params.default.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:9  Function Definition: fn1(vi4;b1;b1; (temp 4-component vector of int)
+0:9    Function Parameters: 
+0:9      'p0' (in 4-component vector of int)
+0:9      'b1' (in bool)
+0:9      'b2' (in bool)
+0:?     Sequence
+0:10      Branch: Return with expression
+0:10        'p0' (in 4-component vector of int)
+0:17  Function Definition: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:17    Function Parameters: 
+0:17      'p0' (in 4-component vector of int)
+0:17      'p1' (in 4-component vector of int)
+0:17      'p2' (in 2-element array of int)
+0:17      'p3' (in int)
+0:?     Sequence
+0:18      Branch: Return with expression
+0:18        add (temp 4-component vector of int)
+0:18          add (temp 4-component vector of int)
+0:18            add (temp 4-component vector of int)
+0:18              'p0' (in 4-component vector of int)
+0:18              'p1' (in 4-component vector of int)
+0:18            direct index (temp int)
+0:18              'p2' (in 2-element array of int)
+0:18              Constant:
+0:18                0 (const int)
+0:18          'p3' (in int)
+0:23  Function Definition: fn2(vi4;i1; (temp 4-component vector of int)
+0:23    Function Parameters: 
+0:23      'p0' (in 4-component vector of int)
+0:23      'x' (in int)
+0:?     Sequence
+0:24      Branch: Return with expression
+0:?         Constant:
+0:?           10 (const int)
+0:?           11 (const int)
+0:?           12 (const int)
+0:?           13 (const int)
+0:28  Function Definition: fn2(vi4;f1; (temp 4-component vector of int)
+0:28    Function Parameters: 
+0:28      'p0' (in 4-component vector of int)
+0:28      'x' (in float)
+0:?     Sequence
+0:29      Branch: Return with expression
+0:29        add (temp 4-component vector of int)
+0:29          'p0' (in 4-component vector of int)
+0:?           Constant:
+0:?             20 (const int)
+0:?             21 (const int)
+0:?             22 (const int)
+0:?             23 (const int)
+0:32  Function Definition: fn3(i1; (temp void)
+0:32    Function Parameters: 
+0:32      'p0' (in int)
+0:36  Function Definition: main( (temp 4-component vector of int)
+0:36    Function Parameters: 
+0:?     Sequence
+0:37      Sequence
+0:37        move second child to first child (temp 2-element array of int)
+0:37          'myarray' (temp 2-element array of int)
+0:37          Constant:
+0:37            30 (const int)
+0:37            31 (const int)
+0:39      Function Call: fn3(i1; (temp void)
+0:32        Constant:
+0:32          3 (const int)
+0:40      Function Call: fn3(i1; (temp void)
+0:40        Constant:
+0:40          5 (const int)
+0:50      Sequence
+0:50        move second child to first child (temp 4-component vector of int)
+0:?           '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
+0:49          add (temp 4-component vector of int)
+0:47            add (temp 4-component vector of int)
+0:46              add (temp 4-component vector of int)
+0:45                add (temp 4-component vector of int)
+0:44                  add (temp 4-component vector of int)
+0:43                    add (temp 4-component vector of int)
+0:42                      add (temp 4-component vector of int)
+0:42                        Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:42                          Constant:
+0:42                            100 (const int)
+0:42                            100 (const int)
+0:42                            100 (const int)
+0:42                            100 (const int)
+0:?                           Constant:
+0:?                             -1 (const int)
+0:?                             -2 (const int)
+0:?                             -3 (const int)
+0:?                             -4 (const int)
+0:15                          Constant:
+0:15                            1 (const int)
+0:15                            2 (const int)
+0:16                          Constant:
+0:16                            42 (const int)
+0:43                        Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:43                          Constant:
+0:43                            101 (const int)
+0:43                            101 (const int)
+0:43                            101 (const int)
+0:43                            101 (const int)
+0:43                          ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
+0:43                            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
+0:43                            Constant:
+0:43                              0 (const uint)
+0:15                          Constant:
+0:15                            1 (const int)
+0:15                            2 (const int)
+0:16                          Constant:
+0:16                            42 (const int)
+0:44                      Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:44                        Constant:
+0:44                          102 (const int)
+0:44                          102 (const int)
+0:44                          102 (const int)
+0:44                          102 (const int)
+0:44                        ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
+0:44                          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
+0:44                          Constant:
+0:44                            0 (const uint)
+0:44                        'myarray' (temp 2-element array of int)
+0:16                        Constant:
+0:16                          42 (const int)
+0:45                    Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:45                      Constant:
+0:45                        103 (const int)
+0:45                        103 (const int)
+0:45                        103 (const int)
+0:45                        103 (const int)
+0:45                      ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
+0:45                        'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
+0:45                        Constant:
+0:45                          0 (const uint)
+0:45                      'myarray' (temp 2-element array of int)
+0:45                      Constant:
+0:45                        99 (const int)
+0:46                  Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
+0:46                    Constant:
+0:46                      104 (const int)
+0:46                      104 (const int)
+0:46                      104 (const int)
+0:46                      104 (const int)
+0:46                    Constant:
+0:46                      false (const bool)
+0:9                    Constant:
+0:9                      false (const bool)
+0:47                Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
+0:47                  Constant:
+0:47                    105 (const int)
+0:47                    105 (const int)
+0:47                    105 (const int)
+0:47                    105 (const int)
+0:47                  Constant:
+0:47                    false (const bool)
+0:47                  Constant:
+0:47                    true (const bool)
+0:49              Function Call: fn2(vi4;f1; (temp 4-component vector of int)
+0:49                Constant:
+0:49                  110 (const int)
+0:49                  110 (const int)
+0:49                  110 (const int)
+0:49                  110 (const int)
+0:49                Constant:
+0:49                  11.110000
+0:50            Function Call: fn2(vi4;i1; (temp 4-component vector of int)
+0:50              Constant:
+0:50                111 (const int)
+0:50                111 (const int)
+0:50                111 (const int)
+0:50                111 (const int)
+0:50              Constant:
+0:50                12 (const int)
+0:50        Branch: Return
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
+0:?     'cia' (const int)
+0:?       -4 (const int)
+0:?     'cib' (const int)
+0:?       -42 (const int)
+0:?     'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:9  Function Definition: fn1(vi4;b1;b1; (temp 4-component vector of int)
+0:9    Function Parameters: 
+0:9      'p0' (in 4-component vector of int)
+0:9      'b1' (in bool)
+0:9      'b2' (in bool)
+0:?     Sequence
+0:10      Branch: Return with expression
+0:10        'p0' (in 4-component vector of int)
+0:17  Function Definition: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:17    Function Parameters: 
+0:17      'p0' (in 4-component vector of int)
+0:17      'p1' (in 4-component vector of int)
+0:17      'p2' (in 2-element array of int)
+0:17      'p3' (in int)
+0:?     Sequence
+0:18      Branch: Return with expression
+0:18        add (temp 4-component vector of int)
+0:18          add (temp 4-component vector of int)
+0:18            add (temp 4-component vector of int)
+0:18              'p0' (in 4-component vector of int)
+0:18              'p1' (in 4-component vector of int)
+0:18            direct index (temp int)
+0:18              'p2' (in 2-element array of int)
+0:18              Constant:
+0:18                0 (const int)
+0:18          'p3' (in int)
+0:23  Function Definition: fn2(vi4;i1; (temp 4-component vector of int)
+0:23    Function Parameters: 
+0:23      'p0' (in 4-component vector of int)
+0:23      'x' (in int)
+0:?     Sequence
+0:24      Branch: Return with expression
+0:?         Constant:
+0:?           10 (const int)
+0:?           11 (const int)
+0:?           12 (const int)
+0:?           13 (const int)
+0:28  Function Definition: fn2(vi4;f1; (temp 4-component vector of int)
+0:28    Function Parameters: 
+0:28      'p0' (in 4-component vector of int)
+0:28      'x' (in float)
+0:?     Sequence
+0:29      Branch: Return with expression
+0:29        add (temp 4-component vector of int)
+0:29          'p0' (in 4-component vector of int)
+0:?           Constant:
+0:?             20 (const int)
+0:?             21 (const int)
+0:?             22 (const int)
+0:?             23 (const int)
+0:32  Function Definition: fn3(i1; (temp void)
+0:32    Function Parameters: 
+0:32      'p0' (in int)
+0:36  Function Definition: main( (temp 4-component vector of int)
+0:36    Function Parameters: 
+0:?     Sequence
+0:37      Sequence
+0:37        move second child to first child (temp 2-element array of int)
+0:37          'myarray' (temp 2-element array of int)
+0:37          Constant:
+0:37            30 (const int)
+0:37            31 (const int)
+0:39      Function Call: fn3(i1; (temp void)
+0:32        Constant:
+0:32          3 (const int)
+0:40      Function Call: fn3(i1; (temp void)
+0:40        Constant:
+0:40          5 (const int)
+0:50      Sequence
+0:50        move second child to first child (temp 4-component vector of int)
+0:?           '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
+0:49          add (temp 4-component vector of int)
+0:47            add (temp 4-component vector of int)
+0:46              add (temp 4-component vector of int)
+0:45                add (temp 4-component vector of int)
+0:44                  add (temp 4-component vector of int)
+0:43                    add (temp 4-component vector of int)
+0:42                      add (temp 4-component vector of int)
+0:42                        Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:42                          Constant:
+0:42                            100 (const int)
+0:42                            100 (const int)
+0:42                            100 (const int)
+0:42                            100 (const int)
+0:?                           Constant:
+0:?                             -1 (const int)
+0:?                             -2 (const int)
+0:?                             -3 (const int)
+0:?                             -4 (const int)
+0:15                          Constant:
+0:15                            1 (const int)
+0:15                            2 (const int)
+0:16                          Constant:
+0:16                            42 (const int)
+0:43                        Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:43                          Constant:
+0:43                            101 (const int)
+0:43                            101 (const int)
+0:43                            101 (const int)
+0:43                            101 (const int)
+0:43                          ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
+0:43                            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
+0:43                            Constant:
+0:43                              0 (const uint)
+0:15                          Constant:
+0:15                            1 (const int)
+0:15                            2 (const int)
+0:16                          Constant:
+0:16                            42 (const int)
+0:44                      Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:44                        Constant:
+0:44                          102 (const int)
+0:44                          102 (const int)
+0:44                          102 (const int)
+0:44                          102 (const int)
+0:44                        ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
+0:44                          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
+0:44                          Constant:
+0:44                            0 (const uint)
+0:44                        'myarray' (temp 2-element array of int)
+0:16                        Constant:
+0:16                          42 (const int)
+0:45                    Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:45                      Constant:
+0:45                        103 (const int)
+0:45                        103 (const int)
+0:45                        103 (const int)
+0:45                        103 (const int)
+0:45                      ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
+0:45                        'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
+0:45                        Constant:
+0:45                          0 (const uint)
+0:45                      'myarray' (temp 2-element array of int)
+0:45                      Constant:
+0:45                        99 (const int)
+0:46                  Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
+0:46                    Constant:
+0:46                      104 (const int)
+0:46                      104 (const int)
+0:46                      104 (const int)
+0:46                      104 (const int)
+0:46                    Constant:
+0:46                      false (const bool)
+0:9                    Constant:
+0:9                      false (const bool)
+0:47                Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
+0:47                  Constant:
+0:47                    105 (const int)
+0:47                    105 (const int)
+0:47                    105 (const int)
+0:47                    105 (const int)
+0:47                  Constant:
+0:47                    false (const bool)
+0:47                  Constant:
+0:47                    true (const bool)
+0:49              Function Call: fn2(vi4;f1; (temp 4-component vector of int)
+0:49                Constant:
+0:49                  110 (const int)
+0:49                  110 (const int)
+0:49                  110 (const int)
+0:49                  110 (const int)
+0:49                Constant:
+0:49                  11.110000
+0:50            Function Call: fn2(vi4;i1; (temp 4-component vector of int)
+0:50              Constant:
+0:50                111 (const int)
+0:50                111 (const int)
+0:50                111 (const int)
+0:50                111 (const int)
+0:50              Constant:
+0:50                12 (const int)
+0:50        Branch: Return
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
+0:?     'cia' (const int)
+0:?       -4 (const int)
+0:?     'cib' (const int)
+0:?       -42 (const int)
+0:?     'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4})
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 173
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 88
+                              ExecutionMode 4 OriginUpperLeft
+                              Name 4  "main"
+                              Name 15  "fn1(vi4;b1;b1;"
+                              Name 12  "p0"
+                              Name 13  "b1"
+                              Name 14  "b2"
+                              Name 27  "fn1(vi4;vi4;i1[2];i1;"
+                              Name 23  "p0"
+                              Name 24  "p1"
+                              Name 25  "p2"
+                              Name 26  "p3"
+                              Name 32  "fn2(vi4;i1;"
+                              Name 30  "p0"
+                              Name 31  "x"
+                              Name 39  "fn2(vi4;f1;"
+                              Name 37  "p0"
+                              Name 38  "x"
+                              Name 43  "fn3(i1;"
+                              Name 42  "p0"
+                              Name 77  "myarray"
+                              Name 82  "param"
+                              Name 85  "param"
+                              Name 88  "@entryPointOutput"
+                              Name 100  "param"
+                              Name 101  "param"
+                              Name 102  "param"
+                              Name 103  "param"
+                              Name 107  "$Global"
+                              MemberName 107($Global) 0  "ui4"
+                              Name 109  ""
+                              Name 110  "param"
+                              Name 111  "param"
+                              Name 115  "param"
+                              Name 116  "param"
+                              Name 121  "param"
+                              Name 122  "param"
+                              Name 125  "param"
+                              Name 127  "param"
+                              Name 133  "param"
+                              Name 134  "param"
+                              Name 137  "param"
+                              Name 139  "param"
+                              Name 145  "param"
+                              Name 146  "param"
+                              Name 147  "param"
+                              Name 153  "param"
+                              Name 154  "param"
+                              Name 155  "param"
+                              Name 161  "param"
+                              Name 162  "param"
+                              Name 167  "param"
+                              Name 168  "param"
+                              Decorate 88(@entryPointOutput) Location 0
+                              MemberDecorate 107($Global) 0 Offset 0
+                              Decorate 107($Global) Block
+                              Decorate 109 DescriptorSet 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 1
+               7:             TypeVector 6(int) 4
+               8:             TypePointer Function 7(ivec4)
+               9:             TypeBool
+              10:             TypePointer Function 9(bool)
+              11:             TypeFunction 7(ivec4) 8(ptr) 10(ptr) 10(ptr)
+              17:             TypeInt 32 0
+              18:     17(int) Constant 2
+              19:             TypeArray 6(int) 18
+              20:             TypePointer Function 19
+              21:             TypePointer Function 6(int)
+              22:             TypeFunction 7(ivec4) 8(ptr) 8(ptr) 20(ptr) 21(ptr)
+              29:             TypeFunction 7(ivec4) 8(ptr) 21(ptr)
+              34:             TypeFloat 32
+              35:             TypePointer Function 34(float)
+              36:             TypeFunction 7(ivec4) 8(ptr) 35(ptr)
+              41:             TypeFunction 2 21(ptr)
+              51:      6(int) Constant 0
+              61:      6(int) Constant 10
+              62:      6(int) Constant 11
+              63:      6(int) Constant 12
+              64:      6(int) Constant 13
+              65:    7(ivec4) ConstantComposite 61 62 63 64
+              69:      6(int) Constant 20
+              70:      6(int) Constant 21
+              71:      6(int) Constant 22
+              72:      6(int) Constant 23
+              73:    7(ivec4) ConstantComposite 69 70 71 72
+              78:      6(int) Constant 30
+              79:      6(int) Constant 31
+              80:          19 ConstantComposite 78 79
+              81:      6(int) Constant 3
+              84:      6(int) Constant 5
+              87:             TypePointer Output 7(ivec4)
+88(@entryPointOutput):     87(ptr) Variable Output
+              89:      6(int) Constant 100
+              90:    7(ivec4) ConstantComposite 89 89 89 89
+              91:      6(int) Constant 4294967295
+              92:      6(int) Constant 4294967294
+              93:      6(int) Constant 4294967293
+              94:      6(int) Constant 4294967292
+              95:    7(ivec4) ConstantComposite 91 92 93 94
+              96:      6(int) Constant 1
+              97:      6(int) Constant 2
+              98:          19 ConstantComposite 96 97
+              99:      6(int) Constant 42
+             105:      6(int) Constant 101
+             106:    7(ivec4) ConstantComposite 105 105 105 105
+    107($Global):             TypeStruct 7(ivec4)
+             108:             TypePointer Uniform 107($Global)
+             109:    108(ptr) Variable Uniform
+             112:             TypePointer Uniform 7(ivec4)
+             119:      6(int) Constant 102
+             120:    7(ivec4) ConstantComposite 119 119 119 119
+             130:      6(int) Constant 103
+             131:    7(ivec4) ConstantComposite 130 130 130 130
+             132:      6(int) Constant 99
+             142:      6(int) Constant 104
+             143:    7(ivec4) ConstantComposite 142 142 142 142
+             144:     9(bool) ConstantFalse
+             150:      6(int) Constant 105
+             151:    7(ivec4) ConstantComposite 150 150 150 150
+             152:     9(bool) ConstantTrue
+             158:      6(int) Constant 110
+             159:    7(ivec4) ConstantComposite 158 158 158 158
+             160:   34(float) Constant 1093780111
+             165:      6(int) Constant 111
+             166:    7(ivec4) ConstantComposite 165 165 165 165
+             172:      6(int) Constant 4294967254
+         4(main):           2 Function None 3
+               5:             Label
+     77(myarray):     20(ptr) Variable Function
+       82(param):     21(ptr) Variable Function
+       85(param):     21(ptr) Variable Function
+      100(param):      8(ptr) Variable Function
+      101(param):      8(ptr) Variable Function
+      102(param):     20(ptr) Variable Function
+      103(param):     21(ptr) Variable Function
+      110(param):      8(ptr) Variable Function
+      111(param):      8(ptr) Variable Function
+      115(param):     20(ptr) Variable Function
+      116(param):     21(ptr) Variable Function
+      121(param):      8(ptr) Variable Function
+      122(param):      8(ptr) Variable Function
+      125(param):     20(ptr) Variable Function
+      127(param):     21(ptr) Variable Function
+      133(param):      8(ptr) Variable Function
+      134(param):      8(ptr) Variable Function
+      137(param):     20(ptr) Variable Function
+      139(param):     21(ptr) Variable Function
+      145(param):      8(ptr) Variable Function
+      146(param):     10(ptr) Variable Function
+      147(param):     10(ptr) Variable Function
+      153(param):      8(ptr) Variable Function
+      154(param):     10(ptr) Variable Function
+      155(param):     10(ptr) Variable Function
+      161(param):      8(ptr) Variable Function
+      162(param):     35(ptr) Variable Function
+      167(param):      8(ptr) Variable Function
+      168(param):     21(ptr) Variable Function
+                              Store 77(myarray) 80
+                              Store 82(param) 81
+              83:           2 FunctionCall 43(fn3(i1;) 82(param)
+                              Store 85(param) 84
+              86:           2 FunctionCall 43(fn3(i1;) 85(param)
+                              Store 100(param) 90
+                              Store 101(param) 95
+                              Store 102(param) 98
+                              Store 103(param) 99
+             104:    7(ivec4) FunctionCall 27(fn1(vi4;vi4;i1[2];i1;) 100(param) 101(param) 102(param) 103(param)
+                              Store 110(param) 106
+             113:    112(ptr) AccessChain 109 51
+             114:    7(ivec4) Load 113
+                              Store 111(param) 114
+                              Store 115(param) 98
+                              Store 116(param) 99
+             117:    7(ivec4) FunctionCall 27(fn1(vi4;vi4;i1[2];i1;) 110(param) 111(param) 115(param) 116(param)
+             118:    7(ivec4) IAdd 104 117
+                              Store 121(param) 120
+             123:    112(ptr) AccessChain 109 51
+             124:    7(ivec4) Load 123
+                              Store 122(param) 124
+             126:          19 Load 77(myarray)
+                              Store 125(param) 126
+                              Store 127(param) 99
+             128:    7(ivec4) FunctionCall 27(fn1(vi4;vi4;i1[2];i1;) 121(param) 122(param) 125(param) 127(param)
+             129:    7(ivec4) IAdd 118 128
+                              Store 133(param) 131
+             135:    112(ptr) AccessChain 109 51
+             136:    7(ivec4) Load 135
+                              Store 134(param) 136
+             138:          19 Load 77(myarray)
+                              Store 137(param) 138
+                              Store 139(param) 132
+             140:    7(ivec4) FunctionCall 27(fn1(vi4;vi4;i1[2];i1;) 133(param) 134(param) 137(param) 139(param)
+             141:    7(ivec4) IAdd 129 140
+                              Store 145(param) 143
+                              Store 146(param) 144
+                              Store 147(param) 144
+             148:    7(ivec4) FunctionCall 15(fn1(vi4;b1;b1;) 145(param) 146(param) 147(param)
+             149:    7(ivec4) IAdd 141 148
+                              Store 153(param) 151
+                              Store 154(param) 144
+                              Store 155(param) 152
+             156:    7(ivec4) FunctionCall 15(fn1(vi4;b1;b1;) 153(param) 154(param) 155(param)
+             157:    7(ivec4) IAdd 149 156
+                              Store 161(param) 159
+                              Store 162(param) 160
+             163:    7(ivec4) FunctionCall 39(fn2(vi4;f1;) 161(param) 162(param)
+             164:    7(ivec4) IAdd 157 163
+                              Store 167(param) 166
+                              Store 168(param) 63
+             169:    7(ivec4) FunctionCall 32(fn2(vi4;i1;) 167(param) 168(param)
+             170:    7(ivec4) IAdd 164 169
+                              Store 88(@entryPointOutput) 170
+                              Return
+                              FunctionEnd
+15(fn1(vi4;b1;b1;):    7(ivec4) Function None 11
+          12(p0):      8(ptr) FunctionParameter
+          13(b1):     10(ptr) FunctionParameter
+          14(b2):     10(ptr) FunctionParameter
+              16:             Label
+              45:    7(ivec4) Load 12(p0)
+                              ReturnValue 45
+                              FunctionEnd
+27(fn1(vi4;vi4;i1[2];i1;):    7(ivec4) Function None 22
+          23(p0):      8(ptr) FunctionParameter
+          24(p1):      8(ptr) FunctionParameter
+          25(p2):     20(ptr) FunctionParameter
+          26(p3):     21(ptr) FunctionParameter
+              28:             Label
+              48:    7(ivec4) Load 23(p0)
+              49:    7(ivec4) Load 24(p1)
+              50:    7(ivec4) IAdd 48 49
+              52:     21(ptr) AccessChain 25(p2) 51
+              53:      6(int) Load 52
+              54:    7(ivec4) CompositeConstruct 53 53 53 53
+              55:    7(ivec4) IAdd 50 54
+              56:      6(int) Load 26(p3)
+              57:    7(ivec4) CompositeConstruct 56 56 56 56
+              58:    7(ivec4) IAdd 55 57
+                              ReturnValue 58
+                              FunctionEnd
+ 32(fn2(vi4;i1;):    7(ivec4) Function None 29
+          30(p0):      8(ptr) FunctionParameter
+           31(x):     21(ptr) FunctionParameter
+              33:             Label
+                              ReturnValue 65
+                              FunctionEnd
+ 39(fn2(vi4;f1;):    7(ivec4) Function None 36
+          37(p0):      8(ptr) FunctionParameter
+           38(x):     35(ptr) FunctionParameter
+              40:             Label
+              68:    7(ivec4) Load 37(p0)
+              74:    7(ivec4) IAdd 68 73
+                              ReturnValue 74
+                              FunctionEnd
+     43(fn3(i1;):           2 Function None 41
+          42(p0):     21(ptr) FunctionParameter
+              44:             Label
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/hlsl.params.default.negative.frag.out b/Test/baseResults/hlsl.params.default.negative.frag.out
new file mode 100644 (file)
index 0000000..fa723f3
--- /dev/null
@@ -0,0 +1,379 @@
+hlsl.params.default.negative.frag
+ERROR: 0:27: '' : invalid default parameter value 
+ERROR: 0:32: 'p1' : invalid parameter after default value parameters 
+ERROR: 0:40: 'fn1' : ambiguous best function under implicit type conversion 
+ERROR: 0:47: 'fn2' : ambiguous best function under implicit type conversion 
+ERROR: 4 compilation errors.  No code generated.
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+ERROR: node is still EOpNull!
+0:7  Function Definition: fn1(vi4; (temp 4-component vector of int)
+0:7    Function Parameters: 
+0:7      'p0' (in 4-component vector of int)
+0:?     Sequence
+0:7      Branch: Return with expression
+0:?         Constant:
+0:?           1 (const int)
+0:?           2 (const int)
+0:?           3 (const int)
+0:?           4 (const int)
+0:9  Function Definition: fn1(vi4;b1;b1; (temp 4-component vector of int)
+0:9    Function Parameters: 
+0:9      'p0' (in 4-component vector of int)
+0:9      'b1' (in bool)
+0:9      'b2' (in bool)
+0:?     Sequence
+0:10      Branch: Return with expression
+0:10        'p0' (in 4-component vector of int)
+0:17  Function Definition: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:17    Function Parameters: 
+0:17      'p0' (in 4-component vector of int)
+0:17      'p1' (in 4-component vector of int)
+0:17      'p2' (in 2-element array of int)
+0:17      'p3' (in int)
+0:?     Sequence
+0:18      Branch: Return with expression
+0:18        add (temp 4-component vector of int)
+0:18          add (temp 4-component vector of int)
+0:18            add (temp 4-component vector of int)
+0:18              'p0' (in 4-component vector of int)
+0:18              'p1' (in 4-component vector of int)
+0:18            direct index (temp int)
+0:18              'p2' (in 2-element array of int)
+0:18              Constant:
+0:18                0 (const int)
+0:18          'p3' (in int)
+0:23  Function Definition: fn2(vi4;i1; (temp 4-component vector of int)
+0:23    Function Parameters: 
+0:23      'p0' (in 4-component vector of int)
+0:23      'x' (in int)
+0:?     Sequence
+0:24      Branch: Return with expression
+0:?         Constant:
+0:?           10 (const int)
+0:?           11 (const int)
+0:?           12 (const int)
+0:?           13 (const int)
+0:28  Function Definition: fn2(vi4; (temp 4-component vector of int)
+0:28    Function Parameters: 
+0:28      'p0' (in 4-component vector of int)
+0:?     Sequence
+0:29      Branch: Return with expression
+0:29        add (temp 4-component vector of int)
+0:29          'p0' (in 4-component vector of int)
+0:?           Constant:
+0:?             20 (const int)
+0:?             21 (const int)
+0:?             22 (const int)
+0:?             23 (const int)
+0:33  Function Definition: fn3(i1; (temp void)
+0:33    Function Parameters: 
+0:33      'p0' (in int)
+0:37  Function Definition: main( (temp 4-component vector of int)
+0:37    Function Parameters: 
+0:?     Sequence
+0:38      Sequence
+0:38        move second child to first child (temp 2-element array of int)
+0:38          'myarray' (temp 2-element array of int)
+0:38          Constant:
+0:38            30 (const int)
+0:38            31 (const int)
+0:49      Sequence
+0:49        move second child to first child (temp 4-component vector of int)
+0:?           '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
+0:48          add (temp 4-component vector of int)
+0:47            add (temp 4-component vector of int)
+0:45              add (temp 4-component vector of int)
+0:44                add (temp 4-component vector of int)
+0:43                  add (temp 4-component vector of int)
+0:42                    add (temp 4-component vector of int)
+0:41                      add (temp 4-component vector of int)
+0:40                        add (temp 4-component vector of int)
+0:40                          Function Call: fn1(vi4; (temp 4-component vector of int)
+0:40                            Constant:
+0:40                              100 (const int)
+0:40                              100 (const int)
+0:40                              100 (const int)
+0:40                              100 (const int)
+0:41                          Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:41                            Constant:
+0:41                              101 (const int)
+0:41                              101 (const int)
+0:41                              101 (const int)
+0:41                              101 (const int)
+0:41                            ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
+0:41                              'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
+0:41                              Constant:
+0:41                                0 (const uint)
+0:15                            Constant:
+0:15                              1 (const int)
+0:15                              2 (const int)
+0:16                            Constant:
+0:16                              42 (const int)
+0:42                        Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:42                          Constant:
+0:42                            102 (const int)
+0:42                            102 (const int)
+0:42                            102 (const int)
+0:42                            102 (const int)
+0:42                          ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
+0:42                            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
+0:42                            Constant:
+0:42                              0 (const uint)
+0:42                          'myarray' (temp 2-element array of int)
+0:16                          Constant:
+0:16                            42 (const int)
+0:43                      Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:43                        Constant:
+0:43                          103 (const int)
+0:43                          103 (const int)
+0:43                          103 (const int)
+0:43                          103 (const int)
+0:43                        ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
+0:43                          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
+0:43                          Constant:
+0:43                            0 (const uint)
+0:43                        'myarray' (temp 2-element array of int)
+0:43                        Constant:
+0:43                          99 (const int)
+0:44                    Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
+0:44                      Constant:
+0:44                        104 (const int)
+0:44                        104 (const int)
+0:44                        104 (const int)
+0:44                        104 (const int)
+0:44                      Constant:
+0:44                        false (const bool)
+0:9                      Constant:
+0:9                        false (const bool)
+0:45                  Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
+0:45                    Constant:
+0:45                      105 (const int)
+0:45                      105 (const int)
+0:45                      105 (const int)
+0:45                      105 (const int)
+0:45                    Constant:
+0:45                      false (const bool)
+0:45                    Constant:
+0:45                      true (const bool)
+0:47                Function Call: fn2(vi4; (temp 4-component vector of int)
+0:47                  Constant:
+0:47                    112 (const int)
+0:47                    112 (const int)
+0:47                    112 (const int)
+0:47                    112 (const int)
+0:48              Function Call: fn2(vi4;i1; (temp 4-component vector of int)
+0:48                Constant:
+0:48                  110 (const int)
+0:48                  110 (const int)
+0:48                  110 (const int)
+0:48                  110 (const int)
+0:48                Constant:
+0:48                  11 (const int)
+0:49            Function Call: fn2(vi4;i1; (temp 4-component vector of int)
+0:49              Constant:
+0:49                111 (const int)
+0:49                111 (const int)
+0:49                111 (const int)
+0:49                111 (const int)
+0:49              Constant:
+0:49                12 (const int)
+0:49        Branch: Return
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
+0:?     'cia' (const int)
+0:?       -4 (const int)
+0:?     'cib' (const int)
+0:?       -42 (const int)
+0:?     'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+ERROR: node is still EOpNull!
+0:7  Function Definition: fn1(vi4; (temp 4-component vector of int)
+0:7    Function Parameters: 
+0:7      'p0' (in 4-component vector of int)
+0:?     Sequence
+0:7      Branch: Return with expression
+0:?         Constant:
+0:?           1 (const int)
+0:?           2 (const int)
+0:?           3 (const int)
+0:?           4 (const int)
+0:9  Function Definition: fn1(vi4;b1;b1; (temp 4-component vector of int)
+0:9    Function Parameters: 
+0:9      'p0' (in 4-component vector of int)
+0:9      'b1' (in bool)
+0:9      'b2' (in bool)
+0:?     Sequence
+0:10      Branch: Return with expression
+0:10        'p0' (in 4-component vector of int)
+0:17  Function Definition: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:17    Function Parameters: 
+0:17      'p0' (in 4-component vector of int)
+0:17      'p1' (in 4-component vector of int)
+0:17      'p2' (in 2-element array of int)
+0:17      'p3' (in int)
+0:?     Sequence
+0:18      Branch: Return with expression
+0:18        add (temp 4-component vector of int)
+0:18          add (temp 4-component vector of int)
+0:18            add (temp 4-component vector of int)
+0:18              'p0' (in 4-component vector of int)
+0:18              'p1' (in 4-component vector of int)
+0:18            direct index (temp int)
+0:18              'p2' (in 2-element array of int)
+0:18              Constant:
+0:18                0 (const int)
+0:18          'p3' (in int)
+0:23  Function Definition: fn2(vi4;i1; (temp 4-component vector of int)
+0:23    Function Parameters: 
+0:23      'p0' (in 4-component vector of int)
+0:23      'x' (in int)
+0:?     Sequence
+0:24      Branch: Return with expression
+0:?         Constant:
+0:?           10 (const int)
+0:?           11 (const int)
+0:?           12 (const int)
+0:?           13 (const int)
+0:28  Function Definition: fn2(vi4; (temp 4-component vector of int)
+0:28    Function Parameters: 
+0:28      'p0' (in 4-component vector of int)
+0:?     Sequence
+0:29      Branch: Return with expression
+0:29        add (temp 4-component vector of int)
+0:29          'p0' (in 4-component vector of int)
+0:?           Constant:
+0:?             20 (const int)
+0:?             21 (const int)
+0:?             22 (const int)
+0:?             23 (const int)
+0:33  Function Definition: fn3(i1; (temp void)
+0:33    Function Parameters: 
+0:33      'p0' (in int)
+0:37  Function Definition: main( (temp 4-component vector of int)
+0:37    Function Parameters: 
+0:?     Sequence
+0:38      Sequence
+0:38        move second child to first child (temp 2-element array of int)
+0:38          'myarray' (temp 2-element array of int)
+0:38          Constant:
+0:38            30 (const int)
+0:38            31 (const int)
+0:49      Sequence
+0:49        move second child to first child (temp 4-component vector of int)
+0:?           '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
+0:48          add (temp 4-component vector of int)
+0:47            add (temp 4-component vector of int)
+0:45              add (temp 4-component vector of int)
+0:44                add (temp 4-component vector of int)
+0:43                  add (temp 4-component vector of int)
+0:42                    add (temp 4-component vector of int)
+0:41                      add (temp 4-component vector of int)
+0:40                        add (temp 4-component vector of int)
+0:40                          Function Call: fn1(vi4; (temp 4-component vector of int)
+0:40                            Constant:
+0:40                              100 (const int)
+0:40                              100 (const int)
+0:40                              100 (const int)
+0:40                              100 (const int)
+0:41                          Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:41                            Constant:
+0:41                              101 (const int)
+0:41                              101 (const int)
+0:41                              101 (const int)
+0:41                              101 (const int)
+0:41                            ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
+0:41                              'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
+0:41                              Constant:
+0:41                                0 (const uint)
+0:15                            Constant:
+0:15                              1 (const int)
+0:15                              2 (const int)
+0:16                            Constant:
+0:16                              42 (const int)
+0:42                        Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:42                          Constant:
+0:42                            102 (const int)
+0:42                            102 (const int)
+0:42                            102 (const int)
+0:42                            102 (const int)
+0:42                          ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
+0:42                            'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
+0:42                            Constant:
+0:42                              0 (const uint)
+0:42                          'myarray' (temp 2-element array of int)
+0:16                          Constant:
+0:16                            42 (const int)
+0:43                      Function Call: fn1(vi4;vi4;i1[2];i1; (temp 4-component vector of int)
+0:43                        Constant:
+0:43                          103 (const int)
+0:43                          103 (const int)
+0:43                          103 (const int)
+0:43                          103 (const int)
+0:43                        ui4: direct index for structure (layout(offset=0 ) uniform 4-component vector of int)
+0:43                          'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
+0:43                          Constant:
+0:43                            0 (const uint)
+0:43                        'myarray' (temp 2-element array of int)
+0:43                        Constant:
+0:43                          99 (const int)
+0:44                    Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
+0:44                      Constant:
+0:44                        104 (const int)
+0:44                        104 (const int)
+0:44                        104 (const int)
+0:44                        104 (const int)
+0:44                      Constant:
+0:44                        false (const bool)
+0:9                      Constant:
+0:9                        false (const bool)
+0:45                  Function Call: fn1(vi4;b1;b1; (temp 4-component vector of int)
+0:45                    Constant:
+0:45                      105 (const int)
+0:45                      105 (const int)
+0:45                      105 (const int)
+0:45                      105 (const int)
+0:45                    Constant:
+0:45                      false (const bool)
+0:45                    Constant:
+0:45                      true (const bool)
+0:47                Function Call: fn2(vi4; (temp 4-component vector of int)
+0:47                  Constant:
+0:47                    112 (const int)
+0:47                    112 (const int)
+0:47                    112 (const int)
+0:47                    112 (const int)
+0:48              Function Call: fn2(vi4;i1; (temp 4-component vector of int)
+0:48                Constant:
+0:48                  110 (const int)
+0:48                  110 (const int)
+0:48                  110 (const int)
+0:48                  110 (const int)
+0:48                Constant:
+0:48                  11 (const int)
+0:49            Function Call: fn2(vi4;i1; (temp 4-component vector of int)
+0:49              Constant:
+0:49                111 (const int)
+0:49                111 (const int)
+0:49                111 (const int)
+0:49                111 (const int)
+0:49              Constant:
+0:49                12 (const int)
+0:49        Branch: Return
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout(location=0 ) out 4-component vector of int)
+0:?     'cia' (const int)
+0:?       -4 (const int)
+0:?     'cib' (const int)
+0:?       -42 (const int)
+0:?     'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of int ui4, layout(offset=16 ) uniform float ufvar})
+
+SPIR-V is not generated for failed compile or link
diff --git a/Test/hlsl.params.default.frag b/Test/hlsl.params.default.frag
new file mode 100644 (file)
index 0000000..42ad84f
--- /dev/null
@@ -0,0 +1,51 @@
+uniform int4 ui4;
+
+static const int cia = -4;
+static const int cib = -42;
+
+// ERROR: Ambiguous with fn1 below.
+// int4 fn1(int4 p0) { return int4(1,2,3,4); }
+
+int4 fn1(int4 p0, bool b1, bool b2 = false) {
+    return p0;
+}
+
+int4 fn1(int4 p0,
+         int4 p1    : FOO = int4(-1,-2,-3, cia),
+         int  p2[2] : BAR = { int(1), 2 },
+         int  p3          = abs(cib) )
+{
+    return p0 + p1 + p2[0] + p3;
+}
+
+// These should not be ambiguous if given either an int or a float explicit second parameter.
+int4 fn2(int4 p0, int x = 3)
+{
+    return int4(10,11,12,13);
+}
+
+int4 fn2(int4 p0, float x = sin(3.3)) // OK to have a const expression as a default value
+{
+    return p0 + int4(20,21,22,23);
+}
+
+void fn3(int p0 = 3) { }
+
+
+int4 main() : SV_Target0
+{
+    int myarray[2] = {30,31};
+
+    fn3();
+    fn3(5);
+
+    return fn1(100) +
+           fn1(101, ui4) +
+           fn1(102, ui4, myarray) +
+           fn1(103, ui4, myarray, 99) +
+           fn1(104, false) +
+           fn1(105, false, true) +
+
+           fn2(110, 11.11) +             // calls int4, float form
+           fn2(111, 12);                // calls int4, int form
+}
diff --git a/Test/hlsl.params.default.negative.frag b/Test/hlsl.params.default.negative.frag
new file mode 100644 (file)
index 0000000..c9ff330
--- /dev/null
@@ -0,0 +1,50 @@
+uniform int4 ui4;
+uniform float ufvar;
+
+static const int cia = -4;
+static const int cib = -42;
+
+int4 fn1(int4 p0) { return int4(1,2,3,4); }
+
+int4 fn1(int4 p0, bool b1, bool b2 = false) {
+    return p0;
+}
+
+int4 fn1(int4 p0,
+         int4 p1 : FOO = int4(-1,-2,-3, cia),
+         int p2[2] : BAR = { int(1), 2 },
+         int p3 = abs(cib) )
+{
+    return p0 + p1 + p2[0] + p3;
+}
+
+// These should not be ambiguous if given either an int or a float explicit second parameter.
+int4 fn2(int4 p0, int x = 3)
+{
+    return int4(10,11,12,13);
+}
+
+int4 fn2(int4 p0, float x = ufvar) // ERROR: non-const expression
+{
+    return p0 + int4(20,21,22,23);
+}
+
+void fn3(int p0 = 5, int p1)  // ERROR no-default param after default param
+{
+}
+
+int4 main() : SV_Target0
+{
+    int myarray[2] = {30,31};
+
+    return fn1(100) +                    // ERROR: ambiguous
+           fn1(101, ui4) +
+           fn1(102, ui4, myarray) +
+           fn1(103, ui4, myarray, 99) +
+           fn1(104, false) +
+           fn1(105, false, true) +
+
+           fn2(112) +                    // ERROR: ambiguous
+           fn2(110, 11.11) +             // calls int4, float form
+           fn2(111, 12);                 // calls int4, int form
+}
index 61b6f67..537eb5d 100644 (file)
@@ -629,6 +629,9 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
 //
 TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
 {
+    if (aggrNode == nullptr)
+        return aggrNode;
+
     if (! areAllChildConst(aggrNode))
         return aggrNode;
 
index d86e19d..872c276 100644 (file)
@@ -348,13 +348,18 @@ const TFunction* TParseContextBase::selectFunction(
     for (auto it = candidateList.begin(); it != candidateList.end(); ++it) {
         const TFunction& candidate = *(*it);
 
-        // to even be a potential match, number of arguments has to match
-        if (call.getParamCount() != candidate.getParamCount())
+        // to even be a potential match, number of arguments must be >= the number of
+        // fixed (non-default) parameters, and <= the total (including parameter with defaults).
+        if (call.getParamCount() < candidate.getFixedParamCount() ||
+            call.getParamCount() > candidate.getParamCount())
             continue;
 
         // see if arguments are convertible
         bool viable = true;
-        for (int param = 0; param < candidate.getParamCount(); ++param) {
+
+        // The call can have fewer parameters than the candidate, if some have defaults.
+        const int paramCount = std::min(call.getParamCount(), candidate.getParamCount());
+        for (int param = 0; param < paramCount; ++param) {
             if (candidate[param].type->getQualifier().isParamInput()) {
                 if (! convertible(*call[param].type, *candidate[param].type, candidate.getBuiltInOp(), param)) {
                     viable = false;
@@ -382,7 +387,7 @@ const TFunction* TParseContextBase::selectFunction(
         return viableCandidates.front();
 
     // 4. find best...
-    auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
+    const auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
         // is call -> can2 better than call -> can1 for any parameter
         bool hasBetterParam = false;
         for (int param = 0; param < call.getParamCount(); ++param) {
@@ -394,6 +399,16 @@ const TFunction* TParseContextBase::selectFunction(
         return hasBetterParam;
     };
 
+    const auto equivalentParams = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
+        // is call -> can2 equivalent to call -> can1 for all the call parameters?
+        for (int param = 0; param < call.getParamCount(); ++param) {
+            if (better(*call[param].type, *can1[param].type, *can2[param].type) ||
+                better(*call[param].type, *can2[param].type, *can1[param].type))
+                return false;
+        }
+        return true;
+    };
+    
     const TFunction* incumbent = viableCandidates.front();
     for (auto it = viableCandidates.begin() + 1; it != viableCandidates.end(); ++it) {
         const TFunction& candidate = *(*it);
@@ -406,7 +421,10 @@ const TFunction* TParseContextBase::selectFunction(
         if (incumbent == *it)
             continue;
         const TFunction& candidate = *(*it);
-        if (betterParam(*incumbent, candidate))
+        
+        // In the case of default parameters, it may have an identical initial set, which is
+        // also ambiguous
+        if (betterParam(*incumbent, candidate) || equivalentParams(*incumbent, candidate))
             tie = true;
     }
 
index fb09fdf..d34f4d2 100644 (file)
@@ -295,6 +295,7 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
     op = copyOf.op;
     defined = copyOf.defined;
     prototyped = copyOf.prototyped;
+    defaultParamCount = copyOf.defaultParamCount;
 }
 
 TFunction* TFunction::clone() const
index aeec34f..1cb08d6 100644 (file)
@@ -191,6 +191,7 @@ protected:
 struct TParameter {
     TString *name;
     TType* type;
+    TIntermTyped* defaultValue;
     void copyParam(const TParameter& param) 
     {
         if (param.name)
@@ -198,6 +199,7 @@ struct TParameter {
         else
             name = 0;
         type = param.type->clone();
+        defaultValue = param.defaultValue;
     }
 };
 
@@ -209,12 +211,12 @@ public:
     explicit TFunction(TOperator o) :
         TSymbol(0),
         op(o),
-        defined(false), prototyped(false) { }
+        defined(false), prototyped(false), defaultParamCount(0) { }
     TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
         TSymbol(name),
         mangledName(*name + '('),
         op(tOp),
-        defined(false), prototyped(false) { returnType.shallowCopy(retType); }
+        defined(false), prototyped(false), defaultParamCount(0) { returnType.shallowCopy(retType); }
     virtual TFunction* clone() const;
     virtual ~TFunction();
 
@@ -226,6 +228,9 @@ public:
         assert(writable);
         parameters.push_back(p);
         p.type->appendMangledName(mangledName);
+
+        if (p.defaultValue != nullptr)
+            defaultParamCount++;
     }
 
     virtual const TString& getMangledName() const { return mangledName; }
@@ -238,7 +243,13 @@ public:
     virtual void setPrototyped() { assert(writable); prototyped = true; }
     virtual bool isPrototyped() const { return prototyped; }
 
+    // Return total number of parameters
     virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
+    // Return number of parameters with default values.
+    virtual int getDefaultParamCount() const { return defaultParamCount; }
+    // Return number of fixed parameters (without default values)
+    virtual int getFixedParamCount() const { return getParamCount() - getDefaultParamCount(); }
+
     virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
     virtual const TParameter& operator[](int i) const { return parameters[i]; }
 
@@ -255,6 +266,7 @@ protected:
     TOperator op;
     bool defined;
     bool prototyped;
+    int  defaultParamCount;
 };
 
 //
index f0332aa..2acd241 100644 (file)
@@ -160,6 +160,8 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.numericsuffixes.frag", "main"},
         {"hlsl.numthreads.comp", "main_aux1"},
         {"hlsl.overload.frag", "PixelShaderFunction"},
+        {"hlsl.params.default.frag", "main"},
+        {"hlsl.params.default.negative.frag", "main"},
         {"hlsl.partialInit.frag", "PixelShaderFunction"},
         {"hlsl.pp.line.frag", "main"},
         {"hlsl.precise.frag", "main"},
index b874aa8..d0f3b00 100755 (executable)
@@ -1776,9 +1776,55 @@ bool HlslGrammar::acceptFunctionParameters(TFunction& function)
     return true;
 }
 
+
+// default_parameter_declaration
+//      : EQUAL conditional_expression
+//      : EQUAL initializer
+bool HlslGrammar::acceptDefaultParameterDeclaration(const TType& type, TIntermTyped*& node)
+{
+    node = nullptr;
+
+    // Valid not to have a default_parameter_declaration
+    if (!acceptTokenClass(EHTokAssign))
+        return true;
+
+    if (!acceptConditionalExpression(node)) {
+        if (!acceptInitializer(node))
+            return false;
+
+        // For initializer lists, we have to const-fold into a constructor for the type, so build
+        // that.
+        TFunction* constructor = parseContext.handleConstructorCall(token.loc, type);
+        if (constructor == nullptr)  // cannot construct
+            return false;
+
+        TIntermTyped* arguments = nullptr;
+        for (int i=0; i<int(node->getAsAggregate()->getSequence().size()); i++)
+            parseContext.handleFunctionArgument(constructor, arguments, node->getAsAggregate()->getSequence()[i]->getAsTyped());
+        
+        node = parseContext.handleFunctionCall(token.loc, constructor, node);
+    }
+
+    // If this is simply a constant, we can use it directly.
+    if (node->getAsConstantUnion())
+        return true;
+
+    // Otherwise, it has to be const-foldable.
+    TIntermTyped* origNode = node;
+
+    node = intermediate.fold(node->getAsAggregate());
+
+    if (node != nullptr && origNode != node)
+        return true;
+
+    parseContext.error(token.loc, "invalid default parameter value", "", "");
+
+    return false;
+}
+
 // parameter_declaration
-//      : fully_specified_type post_decls
-//      | fully_specified_type identifier array_specifier post_decls
+//      : fully_specified_type post_decls [ = default_parameter_declaration ]
+//      | fully_specified_type identifier array_specifier post_decls [ = default_parameter_declaration ]
 //
 bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
 {
@@ -1806,9 +1852,19 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
     // post_decls
     acceptPostDecls(type->getQualifier());
 
+    TIntermTyped* defaultValue;
+    if (!acceptDefaultParameterDeclaration(*type, defaultValue))
+        return false;
+
     parseContext.paramFix(*type);
 
-    TParameter param = { idToken.string, type };
+    // If any prior parameters have default values, all the parameters after that must as well.
+    if (defaultValue == nullptr && function.getDefaultParamCount() > 0) {
+        parseContext.error(idToken.loc, "invalid parameter after default value parameters", idToken.string->c_str(), "");
+        return false;
+    }
+
+    TParameter param = { idToken.string, type, defaultValue };
     function.addParameter(param);
 
     return true;
index 8804b21..8612c90 100755 (executable)
@@ -111,6 +111,7 @@ namespace glslang {
         bool acceptDefaultLabel(TIntermNode*&);
         void acceptArraySpecifier(TArraySizes*&);
         void acceptPostDecls(TQualifier&);
+        bool acceptDefaultParameterDeclaration(const TType&, TIntermTyped*&);
 
         HlslParseContext& parseContext;  // state of parsing and helper functions for building the intermediate
         TIntermediate& intermediate;     // the final product, the intermediate representation, includes the AST
index 62dac4b..46ae897 100755 (executable)
@@ -1375,7 +1375,7 @@ TIntermNode* HlslParseContext::handleReturnValue(const TSourceLoc& loc, TIntermT
 
 void HlslParseContext::handleFunctionArgument(TFunction* function, TIntermTyped*& arguments, TIntermTyped* newArg)
 {
-    TParameter param = { 0, new TType };
+    TParameter param = { 0, new TType, nullptr };
     param.type->shallowCopy(newArg->getType());
     function->addParameter(param);
     if (arguments)
@@ -2643,7 +2643,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
 //  - user function
 //  - subroutine call (not implemented yet)
 //
-TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermNode* arguments)
+TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction* function, TIntermTyped* arguments)
 {
     TIntermTyped* result = nullptr;
 
@@ -2783,10 +2783,10 @@ TIntermTyped* HlslParseContext::handleLengthMethod(const TSourceLoc& loc, TFunct
 //
 // Add any needed implicit conversions for function-call arguments to input parameters.
 //
-void HlslParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments)
+void HlslParseContext::addInputArgumentConversions(const TFunction& function, TIntermTyped*& arguments)
 {
     TIntermAggregate* aggregate = arguments->getAsAggregate();
-    const auto setArg = [&](int argNum, TIntermNode* arg) {
+    const auto setArg = [&](int argNum, TIntermTyped* arg) {
         if (function.getParamCount() == 1)
             arguments = arg;
         else {
@@ -4483,8 +4483,8 @@ void HlslParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQuali
 //
 // Return the function symbol if found, otherwise nullptr.
 //
-const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn,
-                                                TIntermNode* args)
+const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction& call, bool& builtIn,
+                                                TIntermTyped*& args)
 {
     // const TFunction* function = nullptr;
 
@@ -4583,6 +4583,22 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
                 return false;
         }
 
+        // Handle sampler betterness: An exact sampler match beats a non-exact match.
+        // (If we just looked at basic type, all EbtSamplers would look the same).
+        // If any type is not a sampler, just use the linearize function below.
+        if (from.getBasicType() == EbtSampler && to1.getBasicType() == EbtSampler && to2.getBasicType() == EbtSampler) {
+            // We can ignore the vector size in the comparison.
+            TSampler to1Sampler = to1.getSampler();
+            TSampler to2Sampler = to2.getSampler();
+
+            to1Sampler.vectorSize = to2Sampler.vectorSize = from.getSampler().vectorSize;
+
+            if (from.getSampler() == to2Sampler)
+                return from.getSampler() != to1Sampler;
+            if (from.getSampler() == to1Sampler)
+                return false;
+        }
+
         // Might or might not be changing shape, which means basic type might
         // or might not match, so within that, the question is how big a
         // basic-type conversion is being done.
@@ -4672,18 +4688,18 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
             // Handle aggregates: put all args into the new function call
             for (int arg=0; arg<int(args->getAsAggregate()->getSequence().size()); ++arg) {
                 // TODO: But for constness, we could avoid the new & shallowCopy, and use the pointer directly.
-                TParameter param = { 0, new TType };
+                TParameter param = { 0, new TType, nullptr };
                 param.type->shallowCopy(args->getAsAggregate()->getSequence()[arg]->getAsTyped()->getType());
                 convertedCall.addParameter(param);
             }
         } else if (args->getAsUnaryNode()) {
             // Handle unaries: put all args into the new function call
-            TParameter param = { 0, new TType };
+            TParameter param = { 0, new TType, nullptr };
             param.type->shallowCopy(args->getAsUnaryNode()->getOperand()->getAsTyped()->getType());
             convertedCall.addParameter(param);
         } else if (args->getAsTyped()) {
             // Handle bare e.g, floats, not in an aggregate.
-            TParameter param = { 0, new TType };
+            TParameter param = { 0, new TType, nullptr };
             param.type->shallowCopy(args->getAsTyped()->getType());
             convertedCall.addParameter(param);
         } else {
@@ -4701,6 +4717,13 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, const TFu
     if (tie)
         error(loc, "ambiguous best function under implicit type conversion", call.getName().c_str(), "");
 
+    // Append default parameter values if needed
+    if (!tie && bestMatch != nullptr) {
+        for (int defParam = call.getParamCount(); defParam < bestMatch->getParamCount(); ++defParam) {
+            handleFunctionArgument(&call, args, (*bestMatch)[defParam].defaultValue);
+        }
+    }
+
     return bestMatch;
 }
 
index d017a2a..6280ab4 100755 (executable)
@@ -79,12 +79,12 @@ public:
     TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*);
     void handleFunctionArgument(TFunction*, TIntermTyped*& arguments, TIntermTyped* newArg);
     TIntermTyped* handleAssign(const TSourceLoc&, TOperator, TIntermTyped* left, TIntermTyped* right) const;
-    TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
+    TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermTyped*);
     void decomposeIntrinsic(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
     void decomposeSampleMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
     void decomposeGeometryMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
     TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
-    void addInputArgumentConversions(const TFunction&, TIntermNode*&);
+    void addInputArgumentConversions(const TFunction&, TIntermTyped*&);
     TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&);
     void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
     TFunction* handleConstructorCall(const TSourceLoc&, const TType&);
@@ -126,7 +126,7 @@ public:
     void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
     void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
 
-    const TFunction* findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn, TIntermNode* args);
+    const TFunction* findFunction(const TSourceLoc& loc, TFunction& call, bool& builtIn, TIntermTyped*& args);
     void declareTypedef(const TSourceLoc&, TString& identifier, const TType&, TArraySizes* typeArray = 0);
     TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, TType&, TIntermTyped* initializer = 0);
     void lengthenList(const TSourceLoc&, TIntermSequence& list, int size);
index 8ecaec9..ee89af5 100755 (executable)
@@ -586,7 +586,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
         { "DeviceMemoryBarrier",              nullptr, nullptr,   "-",              "-",             EShLangPSCS },
         { "DeviceMemoryBarrierWithGroupSync", nullptr, nullptr,   "-",              "-",             EShLangCS },
         { "distance",                         "S",     "F",       "V,",             "F,",            EShLangAll },
-        { "dot",                              "S",     nullptr,   "V,",             "FI,",           EShLangAll },
+        { "dot",                              "S",     nullptr,   "SV,",            "FI,",           EShLangAll },
         { "dst",                              nullptr, nullptr,   "V4,",            "F,",            EShLangAll },
         // { "errorf",                           "-",     "-",       "",             "",             EShLangAll }, TODO: varargs
         { "EvaluateAttributeAtCentroid",      nullptr, nullptr,   "SVM",            "F",             EShLangPS },