ERROR: 0:3: 'vertex-shader `double` type input' : not supported for this version or the enabled extensions
ERROR: 0:4: 'vertex-shader `double` type input' : not supported for this version or the enabled extensions
ERROR: 0:5: 'vertex-shader `double` type input' : not supported for this version or the enabled extensions
-ERROR: 3 compilation errors. No code generated.
+ERROR: 0:70: 'foo3' : no matching overloaded function found
+ERROR: 0:76: 'foo3' : ambiguous best function under implicit type conversion
+ERROR: 0:77: 'foo3' : ambiguous best function under implicit type conversion
+ERROR: 0:78: 'foo3' : ambiguous best function under implicit type conversion
+ERROR: 0:81: 'foo3' : ambiguous best function under implicit type conversion
+ERROR: 0:82: 'foo3' : ambiguous best function under implicit type conversion
+ERROR: 0:83: 'foo3' : ambiguous best function under implicit type conversion
+ERROR: 0:86: 'foo3' : ambiguous best function under implicit type conversion
+ERROR: 0:87: 'foo3' : ambiguous best function under implicit type conversion
+ERROR: 0:88: 'foo3' : ambiguous best function under implicit type conversion
+ERROR: 13 compilation errors. No code generated.
Shader version: 400
ERROR: node is still EOpNull!
-0:7 Function Definition: main( (global void)
-0:7 Function Parameters:
+0:8 Function Definition: foo1(d1;u1; (global void)
+0:8 Function Parameters:
+0:8 'a' (in double)
+0:8 'b' (in uint)
+0:9 Function Definition: foo1(d1;i1; (global void)
+0:9 Function Parameters:
+0:9 'a' (in double)
+0:9 'b' (in int)
+0:10 Function Definition: foo1(d1;f1; (global void)
+0:10 Function Parameters:
+0:10 'a' (in double)
+0:10 'b' (in float)
+0:11 Function Definition: foo1(d1;d1; (global void)
+0:11 Function Parameters:
+0:11 'a' (in double)
+0:11 'b' (in double)
+0:13 Function Definition: foo2(d1;f1; (global void)
+0:13 Function Parameters:
+0:13 'a' (in double)
+0:13 'b' (in float)
+0:14 Function Definition: foo2(d1;d1; (global void)
+0:14 Function Parameters:
+0:14 'a' (in double)
+0:14 'b' (in double)
+0:16 Function Definition: foo3(d1;f1; (global void)
+0:16 Function Parameters:
+0:16 'a' (in double)
+0:16 'b' (in float)
+0:17 Function Definition: foo3(f1;d1; (global void)
+0:17 Function Parameters:
+0:17 'a' (in float)
+0:17 'b' (in double)
+0:19 Function Definition: ftd(i1;f1;d1; (global void)
+0:19 Function Parameters:
+0:19 '' (in int)
+0:19 '' (in float)
+0:19 '' (in double)
+0:20 Function Definition: ftd(u1;f1;d1; (global void)
+0:20 Function Parameters:
+0:20 '' (in uint)
+0:20 '' (in float)
+0:20 '' (in double)
+0:21 Function Definition: ftd(f1;d1;d1; (global void)
+0:21 Function Parameters:
+0:21 '' (in float)
+0:21 '' (in double)
+0:21 '' (in double)
+0:23 Function Definition: main( (global void)
+0:23 Function Parameters:
+0:? Sequence
+0:30 Function Call: foo1(d1;d1; (global void)
+0:30 'd' (temp double)
+0:30 'd' (temp double)
+0:31 Function Call: foo1(d1;u1; (global void)
+0:31 'd' (temp double)
+0:31 'u' (temp uint)
+0:32 Function Call: foo1(d1;i1; (global void)
+0:32 'd' (temp double)
+0:32 'i' (temp int)
+0:33 Function Call: foo1(d1;f1; (global void)
+0:33 'd' (temp double)
+0:33 'f' (temp float)
+0:35 Function Call: foo1(d1;d1; (global void)
+0:35 Convert float to double (temp double)
+0:35 'f' (temp float)
+0:35 'd' (temp double)
+0:36 Function Call: foo1(d1;u1; (global void)
+0:36 Convert float to double (temp double)
+0:36 'f' (temp float)
+0:36 'u' (temp uint)
+0:37 Function Call: foo1(d1;i1; (global void)
+0:37 Convert float to double (temp double)
+0:37 'f' (temp float)
+0:37 'i' (temp int)
+0:38 Function Call: foo1(d1;f1; (global void)
+0:38 Convert float to double (temp double)
+0:38 'f' (temp float)
+0:38 'f' (temp float)
+0:40 Function Call: foo1(d1;d1; (global void)
+0:40 Convert uint to double (temp double)
+0:40 'u' (temp uint)
+0:40 'd' (temp double)
+0:41 Function Call: foo1(d1;u1; (global void)
+0:41 Convert uint to double (temp double)
+0:41 'u' (temp uint)
+0:41 'u' (temp uint)
+0:42 Function Call: foo1(d1;i1; (global void)
+0:42 Convert uint to double (temp double)
+0:42 'u' (temp uint)
+0:42 'i' (temp int)
+0:43 Function Call: foo1(d1;f1; (global void)
+0:43 Convert uint to double (temp double)
+0:43 'u' (temp uint)
+0:43 'f' (temp float)
+0:45 Function Call: foo1(d1;d1; (global void)
+0:45 Convert int to double (temp double)
+0:45 'i' (temp int)
+0:45 'd' (temp double)
+0:46 Function Call: foo1(d1;u1; (global void)
+0:46 Convert int to double (temp double)
+0:46 'i' (temp int)
+0:46 'u' (temp uint)
+0:47 Function Call: foo1(d1;i1; (global void)
+0:47 Convert int to double (temp double)
+0:47 'i' (temp int)
+0:47 'i' (temp int)
+0:48 Function Call: foo1(d1;f1; (global void)
+0:48 Convert int to double (temp double)
+0:48 'i' (temp int)
+0:48 'f' (temp float)
+0:50 Function Call: foo2(d1;d1; (global void)
+0:50 'd' (temp double)
+0:50 'd' (temp double)
+0:51 Function Call: foo2(d1;f1; (global void)
+0:51 'd' (temp double)
+0:51 Convert uint to float (temp float)
+0:51 'u' (temp uint)
+0:52 Function Call: foo2(d1;f1; (global void)
+0:52 'd' (temp double)
+0:52 Convert int to float (temp float)
+0:52 'i' (temp int)
+0:53 Function Call: foo2(d1;f1; (global void)
+0:53 'd' (temp double)
+0:53 'f' (temp float)
+0:55 Function Call: foo2(d1;d1; (global void)
+0:55 Convert float to double (temp double)
+0:55 'f' (temp float)
+0:55 'd' (temp double)
+0:56 Function Call: foo2(d1;f1; (global void)
+0:56 Convert float to double (temp double)
+0:56 'f' (temp float)
+0:56 Convert uint to float (temp float)
+0:56 'u' (temp uint)
+0:57 Function Call: foo2(d1;f1; (global void)
+0:57 Convert float to double (temp double)
+0:57 'f' (temp float)
+0:57 Convert int to float (temp float)
+0:57 'i' (temp int)
+0:58 Function Call: foo2(d1;f1; (global void)
+0:58 Convert float to double (temp double)
+0:58 'f' (temp float)
+0:58 'f' (temp float)
+0:60 Function Call: foo2(d1;d1; (global void)
+0:60 Convert uint to double (temp double)
+0:60 'u' (temp uint)
+0:60 'd' (temp double)
+0:61 Function Call: foo2(d1;f1; (global void)
+0:61 Convert uint to double (temp double)
+0:61 'u' (temp uint)
+0:61 Convert uint to float (temp float)
+0:61 'u' (temp uint)
+0:62 Function Call: foo2(d1;f1; (global void)
+0:62 Convert uint to double (temp double)
+0:62 'u' (temp uint)
+0:62 Convert int to float (temp float)
+0:62 'i' (temp int)
+0:63 Function Call: foo2(d1;f1; (global void)
+0:63 Convert uint to double (temp double)
+0:63 'u' (temp uint)
+0:63 'f' (temp float)
+0:65 Function Call: foo2(d1;d1; (global void)
+0:65 Convert int to double (temp double)
+0:65 'i' (temp int)
+0:65 'd' (temp double)
+0:66 Function Call: foo2(d1;f1; (global void)
+0:66 Convert int to double (temp double)
+0:66 'i' (temp int)
+0:66 Convert uint to float (temp float)
+0:66 'u' (temp uint)
+0:67 Function Call: foo2(d1;f1; (global void)
+0:67 Convert int to double (temp double)
+0:67 'i' (temp int)
+0:67 Convert int to float (temp float)
+0:67 'i' (temp int)
+0:68 Function Call: foo2(d1;f1; (global void)
+0:68 Convert int to double (temp double)
+0:68 'i' (temp int)
+0:68 'f' (temp float)
+0:70 Constant:
+0:70 0.000000
+0:71 Function Call: foo3(d1;f1; (global void)
+0:71 'd' (temp double)
+0:71 Convert uint to float (temp float)
+0:71 'u' (temp uint)
+0:72 Function Call: foo3(d1;f1; (global void)
+0:72 'd' (temp double)
+0:72 Convert int to float (temp float)
+0:72 'i' (temp int)
+0:73 Function Call: foo3(d1;f1; (global void)
+0:73 'd' (temp double)
+0:73 'f' (temp float)
+0:75 Function Call: foo3(f1;d1; (global void)
+0:75 'f' (temp float)
+0:75 'd' (temp double)
+0:76 Function Call: foo3(d1;f1; (global void)
+0:76 Convert float to double (temp double)
+0:76 'f' (temp float)
+0:76 Convert uint to float (temp float)
+0:76 'u' (temp uint)
+0:77 Function Call: foo3(d1;f1; (global void)
+0:77 Convert float to double (temp double)
+0:77 'f' (temp float)
+0:77 Convert int to float (temp float)
+0:77 'i' (temp int)
+0:78 Function Call: foo3(d1;f1; (global void)
+0:78 Convert float to double (temp double)
+0:78 'f' (temp float)
+0:78 'f' (temp float)
+0:80 Function Call: foo3(f1;d1; (global void)
+0:80 Convert uint to float (temp float)
+0:80 'u' (temp uint)
+0:80 'd' (temp double)
+0:81 Function Call: foo3(d1;f1; (global void)
+0:81 Convert uint to double (temp double)
+0:81 'u' (temp uint)
+0:81 Convert uint to float (temp float)
+0:81 'u' (temp uint)
+0:82 Function Call: foo3(d1;f1; (global void)
+0:82 Convert uint to double (temp double)
+0:82 'u' (temp uint)
+0:82 Convert int to float (temp float)
+0:82 'i' (temp int)
+0:83 Function Call: foo3(d1;f1; (global void)
+0:83 Convert uint to double (temp double)
+0:83 'u' (temp uint)
+0:83 'f' (temp float)
+0:85 Function Call: foo3(f1;d1; (global void)
+0:85 Convert int to float (temp float)
+0:85 'i' (temp int)
+0:85 'd' (temp double)
+0:86 Function Call: foo3(d1;f1; (global void)
+0:86 Convert int to double (temp double)
+0:86 'i' (temp int)
+0:86 Convert uint to float (temp float)
+0:86 'u' (temp uint)
+0:87 Function Call: foo3(d1;f1; (global void)
+0:87 Convert int to double (temp double)
+0:87 'i' (temp int)
+0:87 Convert int to float (temp float)
+0:87 'i' (temp int)
+0:88 Function Call: foo3(d1;f1; (global void)
+0:88 Convert int to double (temp double)
+0:88 'i' (temp int)
+0:88 'f' (temp float)
+0:90 Function Call: ftd(i1;f1;d1; (global void)
+0:90 'i' (temp int)
+0:90 'f' (temp float)
+0:90 Convert float to double (temp double)
+0:90 'f' (temp float)
+0:91 Function Call: ftd(u1;f1;d1; (global void)
+0:91 'u' (temp uint)
+0:91 'f' (temp float)
+0:91 Convert float to double (temp double)
+0:91 'f' (temp float)
+0:97 Function Definition: tf( (global void)
+0:97 Function Parameters:
+0:? Sequence
+0:104 Function Call: itf(i1;f1;i1; (global void)
+0:104 'i' (temp int)
+0:104 Convert int to float (temp float)
+0:104 'i' (temp int)
+0:104 'i' (temp int)
+0:105 Function Call: itf(i1;f1;i1; (global void)
+0:105 'i' (temp int)
+0:105 Convert uint to float (temp float)
+0:105 'u' (temp uint)
+0:105 'i' (temp int)
0:? Linker Objects
0:? 'd' (in double)
0:? 'd3' (in 3-component vector of double)
Shader version: 400
ERROR: node is still EOpNull!
-0:7 Function Definition: main( (global void)
-0:7 Function Parameters:
+0:8 Function Definition: foo1(d1;u1; (global void)
+0:8 Function Parameters:
+0:8 'a' (in double)
+0:8 'b' (in uint)
+0:9 Function Definition: foo1(d1;i1; (global void)
+0:9 Function Parameters:
+0:9 'a' (in double)
+0:9 'b' (in int)
+0:10 Function Definition: foo1(d1;f1; (global void)
+0:10 Function Parameters:
+0:10 'a' (in double)
+0:10 'b' (in float)
+0:11 Function Definition: foo1(d1;d1; (global void)
+0:11 Function Parameters:
+0:11 'a' (in double)
+0:11 'b' (in double)
+0:13 Function Definition: foo2(d1;f1; (global void)
+0:13 Function Parameters:
+0:13 'a' (in double)
+0:13 'b' (in float)
+0:14 Function Definition: foo2(d1;d1; (global void)
+0:14 Function Parameters:
+0:14 'a' (in double)
+0:14 'b' (in double)
+0:16 Function Definition: foo3(d1;f1; (global void)
+0:16 Function Parameters:
+0:16 'a' (in double)
+0:16 'b' (in float)
+0:17 Function Definition: foo3(f1;d1; (global void)
+0:17 Function Parameters:
+0:17 'a' (in float)
+0:17 'b' (in double)
+0:19 Function Definition: ftd(i1;f1;d1; (global void)
+0:19 Function Parameters:
+0:19 '' (in int)
+0:19 '' (in float)
+0:19 '' (in double)
+0:20 Function Definition: ftd(u1;f1;d1; (global void)
+0:20 Function Parameters:
+0:20 '' (in uint)
+0:20 '' (in float)
+0:20 '' (in double)
+0:21 Function Definition: ftd(f1;d1;d1; (global void)
+0:21 Function Parameters:
+0:21 '' (in float)
+0:21 '' (in double)
+0:21 '' (in double)
+0:23 Function Definition: main( (global void)
+0:23 Function Parameters:
+0:? Sequence
+0:30 Function Call: foo1(d1;d1; (global void)
+0:30 'd' (temp double)
+0:30 'd' (temp double)
+0:31 Function Call: foo1(d1;u1; (global void)
+0:31 'd' (temp double)
+0:31 'u' (temp uint)
+0:32 Function Call: foo1(d1;i1; (global void)
+0:32 'd' (temp double)
+0:32 'i' (temp int)
+0:33 Function Call: foo1(d1;f1; (global void)
+0:33 'd' (temp double)
+0:33 'f' (temp float)
+0:35 Function Call: foo1(d1;d1; (global void)
+0:35 Convert float to double (temp double)
+0:35 'f' (temp float)
+0:35 'd' (temp double)
+0:36 Function Call: foo1(d1;u1; (global void)
+0:36 Convert float to double (temp double)
+0:36 'f' (temp float)
+0:36 'u' (temp uint)
+0:37 Function Call: foo1(d1;i1; (global void)
+0:37 Convert float to double (temp double)
+0:37 'f' (temp float)
+0:37 'i' (temp int)
+0:38 Function Call: foo1(d1;f1; (global void)
+0:38 Convert float to double (temp double)
+0:38 'f' (temp float)
+0:38 'f' (temp float)
+0:40 Function Call: foo1(d1;d1; (global void)
+0:40 Convert uint to double (temp double)
+0:40 'u' (temp uint)
+0:40 'd' (temp double)
+0:41 Function Call: foo1(d1;u1; (global void)
+0:41 Convert uint to double (temp double)
+0:41 'u' (temp uint)
+0:41 'u' (temp uint)
+0:42 Function Call: foo1(d1;i1; (global void)
+0:42 Convert uint to double (temp double)
+0:42 'u' (temp uint)
+0:42 'i' (temp int)
+0:43 Function Call: foo1(d1;f1; (global void)
+0:43 Convert uint to double (temp double)
+0:43 'u' (temp uint)
+0:43 'f' (temp float)
+0:45 Function Call: foo1(d1;d1; (global void)
+0:45 Convert int to double (temp double)
+0:45 'i' (temp int)
+0:45 'd' (temp double)
+0:46 Function Call: foo1(d1;u1; (global void)
+0:46 Convert int to double (temp double)
+0:46 'i' (temp int)
+0:46 'u' (temp uint)
+0:47 Function Call: foo1(d1;i1; (global void)
+0:47 Convert int to double (temp double)
+0:47 'i' (temp int)
+0:47 'i' (temp int)
+0:48 Function Call: foo1(d1;f1; (global void)
+0:48 Convert int to double (temp double)
+0:48 'i' (temp int)
+0:48 'f' (temp float)
+0:50 Function Call: foo2(d1;d1; (global void)
+0:50 'd' (temp double)
+0:50 'd' (temp double)
+0:51 Function Call: foo2(d1;f1; (global void)
+0:51 'd' (temp double)
+0:51 Convert uint to float (temp float)
+0:51 'u' (temp uint)
+0:52 Function Call: foo2(d1;f1; (global void)
+0:52 'd' (temp double)
+0:52 Convert int to float (temp float)
+0:52 'i' (temp int)
+0:53 Function Call: foo2(d1;f1; (global void)
+0:53 'd' (temp double)
+0:53 'f' (temp float)
+0:55 Function Call: foo2(d1;d1; (global void)
+0:55 Convert float to double (temp double)
+0:55 'f' (temp float)
+0:55 'd' (temp double)
+0:56 Function Call: foo2(d1;f1; (global void)
+0:56 Convert float to double (temp double)
+0:56 'f' (temp float)
+0:56 Convert uint to float (temp float)
+0:56 'u' (temp uint)
+0:57 Function Call: foo2(d1;f1; (global void)
+0:57 Convert float to double (temp double)
+0:57 'f' (temp float)
+0:57 Convert int to float (temp float)
+0:57 'i' (temp int)
+0:58 Function Call: foo2(d1;f1; (global void)
+0:58 Convert float to double (temp double)
+0:58 'f' (temp float)
+0:58 'f' (temp float)
+0:60 Function Call: foo2(d1;d1; (global void)
+0:60 Convert uint to double (temp double)
+0:60 'u' (temp uint)
+0:60 'd' (temp double)
+0:61 Function Call: foo2(d1;f1; (global void)
+0:61 Convert uint to double (temp double)
+0:61 'u' (temp uint)
+0:61 Convert uint to float (temp float)
+0:61 'u' (temp uint)
+0:62 Function Call: foo2(d1;f1; (global void)
+0:62 Convert uint to double (temp double)
+0:62 'u' (temp uint)
+0:62 Convert int to float (temp float)
+0:62 'i' (temp int)
+0:63 Function Call: foo2(d1;f1; (global void)
+0:63 Convert uint to double (temp double)
+0:63 'u' (temp uint)
+0:63 'f' (temp float)
+0:65 Function Call: foo2(d1;d1; (global void)
+0:65 Convert int to double (temp double)
+0:65 'i' (temp int)
+0:65 'd' (temp double)
+0:66 Function Call: foo2(d1;f1; (global void)
+0:66 Convert int to double (temp double)
+0:66 'i' (temp int)
+0:66 Convert uint to float (temp float)
+0:66 'u' (temp uint)
+0:67 Function Call: foo2(d1;f1; (global void)
+0:67 Convert int to double (temp double)
+0:67 'i' (temp int)
+0:67 Convert int to float (temp float)
+0:67 'i' (temp int)
+0:68 Function Call: foo2(d1;f1; (global void)
+0:68 Convert int to double (temp double)
+0:68 'i' (temp int)
+0:68 'f' (temp float)
+0:70 Constant:
+0:70 0.000000
+0:71 Function Call: foo3(d1;f1; (global void)
+0:71 'd' (temp double)
+0:71 Convert uint to float (temp float)
+0:71 'u' (temp uint)
+0:72 Function Call: foo3(d1;f1; (global void)
+0:72 'd' (temp double)
+0:72 Convert int to float (temp float)
+0:72 'i' (temp int)
+0:73 Function Call: foo3(d1;f1; (global void)
+0:73 'd' (temp double)
+0:73 'f' (temp float)
+0:75 Function Call: foo3(f1;d1; (global void)
+0:75 'f' (temp float)
+0:75 'd' (temp double)
+0:76 Function Call: foo3(d1;f1; (global void)
+0:76 Convert float to double (temp double)
+0:76 'f' (temp float)
+0:76 Convert uint to float (temp float)
+0:76 'u' (temp uint)
+0:77 Function Call: foo3(d1;f1; (global void)
+0:77 Convert float to double (temp double)
+0:77 'f' (temp float)
+0:77 Convert int to float (temp float)
+0:77 'i' (temp int)
+0:78 Function Call: foo3(d1;f1; (global void)
+0:78 Convert float to double (temp double)
+0:78 'f' (temp float)
+0:78 'f' (temp float)
+0:80 Function Call: foo3(f1;d1; (global void)
+0:80 Convert uint to float (temp float)
+0:80 'u' (temp uint)
+0:80 'd' (temp double)
+0:81 Function Call: foo3(d1;f1; (global void)
+0:81 Convert uint to double (temp double)
+0:81 'u' (temp uint)
+0:81 Convert uint to float (temp float)
+0:81 'u' (temp uint)
+0:82 Function Call: foo3(d1;f1; (global void)
+0:82 Convert uint to double (temp double)
+0:82 'u' (temp uint)
+0:82 Convert int to float (temp float)
+0:82 'i' (temp int)
+0:83 Function Call: foo3(d1;f1; (global void)
+0:83 Convert uint to double (temp double)
+0:83 'u' (temp uint)
+0:83 'f' (temp float)
+0:85 Function Call: foo3(f1;d1; (global void)
+0:85 Convert int to float (temp float)
+0:85 'i' (temp int)
+0:85 'd' (temp double)
+0:86 Function Call: foo3(d1;f1; (global void)
+0:86 Convert int to double (temp double)
+0:86 'i' (temp int)
+0:86 Convert uint to float (temp float)
+0:86 'u' (temp uint)
+0:87 Function Call: foo3(d1;f1; (global void)
+0:87 Convert int to double (temp double)
+0:87 'i' (temp int)
+0:87 Convert int to float (temp float)
+0:87 'i' (temp int)
+0:88 Function Call: foo3(d1;f1; (global void)
+0:88 Convert int to double (temp double)
+0:88 'i' (temp int)
+0:88 'f' (temp float)
+0:90 Function Call: ftd(i1;f1;d1; (global void)
+0:90 'i' (temp int)
+0:90 'f' (temp float)
+0:90 Convert float to double (temp double)
+0:90 'f' (temp float)
+0:91 Function Call: ftd(u1;f1;d1; (global void)
+0:91 'u' (temp uint)
+0:91 'f' (temp float)
+0:91 Convert float to double (temp double)
+0:91 'f' (temp float)
+0:97 Function Definition: tf( (global void)
+0:97 Function Parameters:
+0:? Sequence
+0:104 Function Call: itf(i1;f1;i1; (global void)
+0:104 'i' (temp int)
+0:104 Convert int to float (temp float)
+0:104 'i' (temp int)
+0:104 'i' (temp int)
+0:105 Function Call: itf(i1;f1;i1; (global void)
+0:105 'i' (temp int)
+0:105 Convert uint to float (temp float)
+0:105 'u' (temp uint)
+0:105 'i' (temp int)
0:? Linker Objects
0:? 'd' (in double)
0:? 'd3' (in 3-component vector of double)
}
// Function finding algorithm for desktop version 400 and above.
+//
+// "When function calls are resolved, an exact type match for all the arguments
+// is sought. If an exact match is found, all other functions are ignored, and
+// the exact match is used. If no exact match is found, then the implicit
+// conversions in section 4.1.10 \93Implicit Conversions\94 will be applied to find
+// a match. Mismatched types on input parameters (in or inout or default) must
+// have a conversion from the calling argument type to the formal parameter type.
+// Mismatched types on output parameters (out or inout) must have a conversion
+// from the formal parameter type to the calling argument type.
+//
+// "If implicit conversions can be used to find more than one matching function,
+// a single best-matching function is sought. To determine a best match, the
+// conversions between calling argument and formal parameter types are compared
+// for each function argument and pair of matching functions. After these
+// comparisons are performed, each pair of matching functions are compared.
+// A function declaration A is considered a better match than function
+// declaration B if
+//
+// * for at least one function argument, the conversion for that argument in A
+// is better than the corresponding conversion in B; and
+// * there is no function argument for which the conversion in B is better than
+// the corresponding conversion in A.
+//
+// "If a single function declaration is considered a better match than every
+// other matching function declaration, it will be used. Otherwise, a
+// compile-time semantic error for an ambiguous overloaded function call occurs.
+//
+// "To determine whether the conversion for a single argument in one match is
+// better than that for another match, the following rules are applied, in order:
+//
+// 1. An exact match is better than a match involving any implicit conversion.
+// 2. A match involving an implicit conversion from float to double is better
+// than a match involving any other implicit conversion.
+// 3. A match involving an implicit conversion from either int or uint to float
+// is better than a match involving an implicit conversion from either int
+// or uint to double.
+//
+// "If none of the rules above apply to a particular pair of conversions, neither
+// conversion is considered better than the other."
+//
const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn)
{
- // TODO: 4.00 functionality: findFunction400()
- return findFunction120(loc, call, builtIn);
+ // first, look for an exact match
+ TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
+ if (symbol)
+ return symbol->getAsFunction();
+
+ // no exact match, use the generic selector, parameterized by the GLSL rules
+
+ // create list of candidates to send
+ TVector<const TFunction*> candidateList;
+ symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
+
+ // can 'from' convert to 'to'?
+ auto convertible = [this](const TType& from, const TType& to) {
+ if (from == to)
+ return true;
+ if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
+ return false;
+ return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType());
+ };
+
+ // Is 'to2' a better conversion than 'to1'?
+ // Ties should not be considered as better.
+ // Assumes 'convertible' already said true.
+ auto better = [](const TType& from, const TType& to1, const TType& to2) {
+ // 1. exact match
+ if (from == to2)
+ return from != to1;
+ if (from == to1)
+ return false;
+
+ // 2. float -> double is better
+ if (from.getBasicType() == EbtFloat) {
+ if (to2.getBasicType() == EbtDouble && to1.getBasicType() != EbtDouble)
+ return true;
+ }
+
+ // 3. -> float is better than -> double
+ return to2.getBasicType() == EbtFloat && to1.getBasicType() == EbtDouble;
+ };
+
+ // for ambiguity reporting
+ bool tie = false;
+
+ // send to the generic selector
+ const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie);
+
+ if (bestMatch == nullptr)
+ error(loc, "no matching overloaded function found", call.getName().c_str(), "");
+ else if (tie)
+ error(loc, "ambiguous best function under implicit type conversion", call.getName().c_str(), "");
+
+ return bestMatch;
+}
+
+// Select the best matching function for 'call' from 'candidateList'.
+//
+// Assumptions
+//
+// There is no exact match, so a selection algorithm needs to run. That is, the
+// language-specific handler should should check for exact match first, to
+// decide what to do, before calling this selector.
+//
+// Input
+//
+// * list of candidate signatures to select from
+// * the call
+// * a predicate function convertible(from, to) that says whether or not type
+// 'from' can implicitly convert to type 'to' (it includes the case of what
+// the calling language would consider a matching type with no conversion
+// needed)
+// * a predicate function better(from1, from2, to1, to2) that says whether or
+// not a conversion from from <-> to2 is considered better than a conversion
+// from <-> to1 (both in and out directions need testing, as declared by the
+// formal parameter)
+//
+// Output
+//
+// * best matching candidate (or none, if no viable candidates found)
+// * whether there was a tie for the best match (ambiguous overload selection,
+// caller's choice for how to report)
+//
+const TFunction* TParseContextBase::selectFunction(
+ TVector<const TFunction*> candidateList,
+ const TFunction& call,
+ std::function<bool(const TType& from, const TType& to)> convertible,
+ std::function<bool(const TType& from, const TType& to1, const TType& to2)> better,
+ /* output */ bool& tie)
+{
+//
+// Operation
+//
+// 1. Prune the input list of candidates down to a list of viable candidates,
+// where each viable candidate has
+//
+// * at least as many parameters as there are calling arguments, with any
+// remainding parameters being optional or having default values
+// * each parameter is true under convertible(A, B), where A is the calling
+// type for in and B is the formal type, and in addition, for out B is the
+// calling type and A is the formal type
+//
+// 2. If there are no viable candidates, return with no match.
+//
+// 3. If there is only one viable candidate, it is the best match.
+//
+// 4. If there are multiple viable candidates, select the first viable candidate
+// as the incumbent. Compare the incumbent to the next viable candidate, and if
+// that candidate is better (bullets below), make it the incumbent. Repeat, with
+// a linear walk through the viable candidate list. The final incumbent will be
+// returned as the best match. A viable candidate is better than the incumbent if
+//
+// * it has a function argument with a better(...) conversion than the incumbent,
+// for all directions needed by in and out
+// * the incumbent has no argument with a better(...) conversion then the
+// candidate, for either in or out (as needed)
+//
+// 5. Check for ambiguity by comparing the best match against all other viable
+// candidates. If any other viable candidate has a function argument with a
+// better(...) conversion than the best candidate (for either in or out
+// directions), return that there was a tie for best.
+//
+
+ tie = false;
+
+ // 1. prune to viable...
+ TVector<const TFunction*> viableCandidates;
+ 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())
+ continue;
+
+ // see if arguments are convertible
+ bool viable = true;
+ for (int param = 0; param < candidate.getParamCount(); ++param) {
+ if (candidate[param].type->getQualifier().isParamInput()) {
+ if (! convertible(*call[param].type, *candidate[param].type)) {
+ viable = false;
+ break;
+ }
+ }
+ if (candidate[param].type->getQualifier().isParamOutput()) {
+ if (! convertible(*candidate[param].type, *call[param].type)) {
+ viable = false;
+ break;
+ }
+ }
+ }
+
+ if (viable)
+ viableCandidates.push_back(&candidate);
+ }
+
+ // 2. none viable...
+ if (viableCandidates.size() == 0)
+ return nullptr;
+
+ // 3. only one viable...
+ if (viableCandidates.size() == 1)
+ return viableCandidates.front();
+
+ // 4. find best...
+ auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2){
+ // is call -> can2 better than call -> can1 for any parameter
+ bool hasBetterParam = false;
+ for (int param = 0; param < call.getParamCount(); ++param) {
+ if (better(*call[param].type, *can1[param].type, *can2[param].type)) {
+ hasBetterParam = true;
+ break;
+ }
+ }
+ return hasBetterParam;
+ };
+
+ const TFunction* incumbent = viableCandidates.front();
+ for (auto it = viableCandidates.begin() + 1; it != viableCandidates.end(); ++it) {
+ const TFunction& candidate = *(*it);
+ if (betterParam(*incumbent, candidate) && ! betterParam(candidate, *incumbent))
+ incumbent = &candidate;
+ }
+
+ // 5. ambiguity...
+ for (auto it = viableCandidates.begin(); it != viableCandidates.end(); ++it) {
+ if (incumbent == *it)
+ continue;
+ const TFunction& candidate = *(*it);
+ if (betterParam(*incumbent, candidate))
+ tie = true;
+ }
+
+ return incumbent;
}
// When a declaration includes a type, but not a variable name, it can be