diff --git a/Test/120.vert b/Test/120.vert index 9c31d1ac794076832f7e0f0a30a8dc4f37817458..b1f69480ed4e11684c032264c12fbf8525ed3a59 100644 --- a/Test/120.vert +++ b/Test/120.vert @@ -51,3 +51,62 @@ int[2][3] foo( // ERROR float[2][3] a, // ERROR float[2] b[3], // ERROR float c[2][3]); // ERROR + +int overloadA(in float f); +int overloadA(out float f); // ERROR, different qualifiers +float overloadA(float); // ERROR, different return value for same signature +float overloadA(out float f, int); +float overloadA(int i); + +vec2 overloadB(float, float); + +vec2 overloadC(int, int); +vec2 overloadC(int, float); +vec2 overloadC(float, int); +vec2 overloadC(vec2, vec2); + +vec3 overloadD(int, float); +vec3 overloadD(float, int); + +vec3 overloadE(float[2]); +vec3 overloadE(mat2 m); +vec3 overloadE(vec2 v); + +void foo() +{ + float f; + int i; + + overloadB(f, f); + overloadB(f, 2); + overloadB(1, i); + + overloadC(1, i); + overloadC(vec2(1), vec2(2)); + overloadC(f, 3.0); // ERROR, no way + overloadC(ivec2(1), vec2(2)); + + overloadD(i, f); + overloadD(f, i); + overloadD(i, i); // ERROR, ambiguous + + int overloadB; // hiding + overloadB(1, i); // ERROR + + sin(1); + texture2D(s2D, ivec2(0)); + clamp(attv4, 0, 1); + clamp(ivec4(attv4), 0, 1); + + int a[2]; + overloadC(a, 3); // ERROR + overloadE(a); // ERROR + overloadE(3.3); // ERROR + overloadE(vec2(3.3)); + overloadE(mat2(0.5)); + overloadE(ivec4(1)); // ERROR + overloadE(ivec2(1)); + + float b[2]; + overloadE(b); +} diff --git a/Test/baseResults/120.frag.out b/Test/baseResults/120.frag.out index a550fee2ed127657e83859ae56cb6f0116ced57f..3b8bd701d864794272d835a83fd359289833edc2 100644 --- a/Test/baseResults/120.frag.out +++ b/Test/baseResults/120.frag.out @@ -1,4 +1,3 @@ -Warning, version 120 is not yet complete; most features are present, but a few are missing. ERROR: 0:9: 'in for stage inputs' : not supported for this version or the enabled extensions ERROR: 0:10: 'out for stage outputs' : not supported for this version or the enabled extensions ERROR: 0:54: '+' : wrong operand types: no operation '+' exists that takes a left-hand operand of type '2-component vector of float' and a right operand of type '3-component vector of float' (or there is no acceptable conversion) diff --git a/Test/baseResults/120.vert.out b/Test/baseResults/120.vert.out index 9f499f87b65a2f6705c766c354297612dfab49f0..851bbf0172d9df0ce3870714844f95b1eefc75a5 100644 --- a/Test/baseResults/120.vert.out +++ b/Test/baseResults/120.vert.out @@ -1,4 +1,3 @@ -Warning, version 120 is not yet complete; most features are present, but a few are missing. ERROR: 0:3: 'in for stage inputs' : not supported for this version or the enabled extensions ERROR: 0:4: 'out for stage outputs' : not supported for this version or the enabled extensions ERROR: 0:11: 'gl_Position' : cannot add storage, auxiliary, memory, interpolation, or precision qualifier to an existing variable @@ -33,7 +32,15 @@ ERROR: 0:50: 'arrays of arrays' : not supported with this profile: none ERROR: 0:51: 'arrays of arrays' : not supported with this profile: none ERROR: 0:52: 'arrays of arrays' : not supported with this profile: none ERROR: 0:53: 'arrays of arrays' : not supported with this profile: none -ERROR: 34 compilation errors. No code generated. +ERROR: 0:56: 'out' : overloaded functions must have the same parameter qualifiers +ERROR: 0:57: 'float' : overloaded functions must have the same return type +ERROR: 0:86: 'overloadC' : no matching overloaded function found +ERROR: 0:91: 'overloadD' : ambiguous function signature match: multiple signatures match under implicit type conversion +ERROR: 0:102: 'overloadC' : no matching overloaded function found +ERROR: 0:103: 'overloadE' : no matching overloaded function found +ERROR: 0:104: 'overloadE' : no matching overloaded function found +ERROR: 0:107: 'overloadE' : no matching overloaded function found +ERROR: 42 compilation errors. No code generated. ERROR: node is still EOpNull! 0:15 Function Definition: main( (void) @@ -81,6 +88,97 @@ ERROR: node is still EOpNull! 0:43 'gl_PointSize' (invariant gl_PointSize float) 0:43 Constant: 0:43 3.800000 +0:75 Function Definition: foo( (void) +0:75 Function Parameters: +0:? Sequence +0:80 Function Call: overloadB(f1;f1; (2-component vector of float) +0:80 'f' (float) +0:80 'f' (float) +0:81 Function Call: overloadB(f1;f1; (2-component vector of float) +0:81 'f' (float) +0:81 Constant: +0:81 2 (const int) +0:82 Function Call: overloadB(f1;f1; (2-component vector of float) +0:82 Constant: +0:82 1 (const int) +0:82 'i' (int) +0:84 Function Call: overloadC(i1;i1; (2-component vector of float) +0:84 Constant: +0:84 1 (const int) +0:84 'i' (int) +0:85 Function Call: overloadC(vf2;vf2; (2-component vector of float) +0:85 Constant: +0:85 1.000000 +0:85 1.000000 +0:85 Constant: +0:85 2.000000 +0:85 2.000000 +0:86 Constant: +0:86 0.000000 +0:87 Function Call: overloadC(vf2;vf2; (2-component vector of float) +0:87 Constant: +0:87 1 (const int) +0:87 1 (const int) +0:87 Constant: +0:87 2.000000 +0:87 2.000000 +0:89 Function Call: overloadD(i1;f1; (3-component vector of float) +0:89 'i' (int) +0:89 'f' (float) +0:90 Function Call: overloadD(f1;i1; (3-component vector of float) +0:90 'f' (float) +0:90 'i' (int) +0:91 Function Call: overloadD(f1;i1; (3-component vector of float) +0:91 'i' (int) +0:91 'i' (int) +0:94 Function Call: overloadB(f1;f1; (2-component vector of float) +0:94 Constant: +0:94 1 (const int) +0:94 'i' (int) +0:96 Constant: +0:96 0.000000 +0:97 Function Call: texture2D(s21;vf2; (4-component vector of float) +0:97 's2D' (uniform sampler2D) +0:97 Constant: +0:97 0 (const int) +0:97 0 (const int) +0:98 clamp (4-component vector of float) +0:98 'attv4' (in 4-component vector of float) +0:98 Constant: +0:98 0 (const int) +0:98 Constant: +0:98 1 (const int) +0:99 clamp (4-component vector of float) +0:99 Convert float to int (4-component vector of int) +0:99 'attv4' (in 4-component vector of float) +0:99 Constant: +0:99 0 (const int) +0:99 Constant: +0:99 1 (const int) +0:102 Constant: +0:102 0.000000 +0:103 Constant: +0:103 0.000000 +0:104 Constant: +0:104 0.000000 +0:105 Function Call: overloadE(vf2; (3-component vector of float) +0:105 Constant: +0:105 3.300000 +0:105 3.300000 +0:106 Function Call: overloadE(mf22; (3-component vector of float) +0:106 Constant: +0:106 0.500000 +0:106 0.000000 +0:106 0.000000 +0:106 0.500000 +0:107 Constant: +0:107 0.000000 +0:108 Function Call: overloadE(vf2; (3-component vector of float) +0:108 Constant: +0:108 1 (const int) +0:108 1 (const int) +0:111 Function Call: overloadE(f1[2]; (3-component vector of float) +0:111 'b' (2-element array of float) 0:? Linker Objects 0:? 'i' (in 4-component vector of float) 0:? 'o' (smooth out 4-component vector of float) diff --git a/Test/baseResults/always-discard.frag.out b/Test/baseResults/always-discard.frag.out index 76055e5f24659b2e6d9c77c58f0bde94bf91f061..579e3ec5014aa55ba3b79452ccbf486a5c4f106f 100644 --- a/Test/baseResults/always-discard.frag.out +++ b/Test/baseResults/always-discard.frag.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:4 Function Definition: main( (void) 0:4 Function Parameters: diff --git a/Test/baseResults/always-discard2.frag.out b/Test/baseResults/always-discard2.frag.out index 724c8aecca983fcf2a3cd44c3ea46b1d7409dc2d..401fab76f7b0ed62620a58e4800333905f2a644b 100644 --- a/Test/baseResults/always-discard2.frag.out +++ b/Test/baseResults/always-discard2.frag.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:4 Function Definition: main( (void) 0:4 Function Parameters: diff --git a/Test/baseResults/conditionalDiscard.frag.out b/Test/baseResults/conditionalDiscard.frag.out index 1d3359b9dc8161f6fa9eb1e4413836ccf884db9e..a4c3e6c25242e1bf6072ae0faba9e39e59564951 100644 --- a/Test/baseResults/conditionalDiscard.frag.out +++ b/Test/baseResults/conditionalDiscard.frag.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:6 Function Definition: main( (void) 0:6 Function Parameters: diff --git a/Test/baseResults/cppIndent.vert.out b/Test/baseResults/cppIndent.vert.out index 93c643a7db55b7d7325d8f75ec35304262e5f234..221640e41ea5654ab7958847a809c53a2f193957 100644 --- a/Test/baseResults/cppIndent.vert.out +++ b/Test/baseResults/cppIndent.vert.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:5 Sequence 0:5 move second child to first child (float) diff --git a/Test/baseResults/cppNest.vert.out b/Test/baseResults/cppNest.vert.out index 60255be6e45b43cc74474f0506eff3ca9ae73d5e..918f832e08a59f8c99da9429d4dd9fb4ecb3f483 100644 --- a/Test/baseResults/cppNest.vert.out +++ b/Test/baseResults/cppNest.vert.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:5 Sequence 0:5 move second child to first child (float) diff --git a/Test/baseResults/cppSimple.vert.out b/Test/baseResults/cppSimple.vert.out index 48dfcff90c466352ab499efe053d8b8bd260c7f8..89201f1a44ceae6b1ab6cd37df044bc7cf434c32 100644 --- a/Test/baseResults/cppSimple.vert.out +++ b/Test/baseResults/cppSimple.vert.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. ERROR: 0:77: '#error' : good1 ERROR: 0:81: '#error' : good2 ERROR: 0:85: '#error' : good3 diff --git a/Test/baseResults/decls.frag.out b/Test/baseResults/decls.frag.out index 6e11cfff00487ae66e843118ec476d2ec9884bbd..f965ed91083d3d1bea4b0b6fbd9ceb3e0604f4fb 100644 --- a/Test/baseResults/decls.frag.out +++ b/Test/baseResults/decls.frag.out @@ -1,4 +1,3 @@ -Warning, version 120 is not yet complete; most features are present, but a few are missing. ERROR: 0:19: 'vi4' : illegal use of type 'void' ERROR: 0:20: 'vj' : illegal use of type 'void' ERROR: 0:20: 'vk5' : illegal use of type 'void' diff --git a/Test/baseResults/deepRvalue.frag.out b/Test/baseResults/deepRvalue.frag.out index 97a20f8bdb1b94075167a1d140872f024fb31cec..a1281944d819ac42c475b2dd644ed89f755eadf5 100644 --- a/Test/baseResults/deepRvalue.frag.out +++ b/Test/baseResults/deepRvalue.frag.out @@ -1,4 +1,3 @@ -Warning, version 120 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:5 Sequence 0:5 move second child to first child (4-component vector of float) diff --git a/Test/baseResults/discard-dce.frag.out b/Test/baseResults/discard-dce.frag.out index 6cc24a01e46c167131d1bee5681f2fcc7cdcb465..97f012bce61841ad578684d40d5986d6a81f7cf6 100644 --- a/Test/baseResults/discard-dce.frag.out +++ b/Test/baseResults/discard-dce.frag.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:4 Function Definition: main( (void) 0:4 Function Parameters: diff --git a/Test/baseResults/doWhileLoop.frag.out b/Test/baseResults/doWhileLoop.frag.out index 7071474edb252402a3152741a57385c46d619ee0..32956c44f0c679b427fd0375fa639c4b4fde3ff3 100644 --- a/Test/baseResults/doWhileLoop.frag.out +++ b/Test/baseResults/doWhileLoop.frag.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:7 Function Definition: main( (void) 0:7 Function Parameters: diff --git a/Test/baseResults/earlyReturnDiscard.frag.out b/Test/baseResults/earlyReturnDiscard.frag.out index 3b6144bedb17e6d0a7c2253cdb8ebc22a11a175d..288f55efb33f70683bb963aaddd122afdad4d207 100644 --- a/Test/baseResults/earlyReturnDiscard.frag.out +++ b/Test/baseResults/earlyReturnDiscard.frag.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:19 Function Definition: main( (void) 0:19 Function Parameters: diff --git a/Test/baseResults/empty.frag.out b/Test/baseResults/empty.frag.out index fa91cf3bb7d54c5e3999f4e97627a45cfb8efd6b..a17d25409aad69df5a9825976ffff16a0fc32691 100644 --- a/Test/baseResults/empty.frag.out +++ b/Test/baseResults/empty.frag.out @@ -11,7 +11,6 @@ WARNING: #version: statement missing; use #version on first line of shader 0:? Linker Objects empty3.frag -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:? Linker Objects diff --git a/Test/baseResults/flowControl.frag.out b/Test/baseResults/flowControl.frag.out index d237e726c914be634e36fb432e934213a78f5dc3..606671d13a8d720f6235caddc089bd0c7afa2492 100644 --- a/Test/baseResults/flowControl.frag.out +++ b/Test/baseResults/flowControl.frag.out @@ -1,4 +1,3 @@ -Warning, version 120 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:10 Function Definition: main( (void) 0:10 Function Parameters: diff --git a/Test/baseResults/forLoop.frag.out b/Test/baseResults/forLoop.frag.out index 4fec57932540bd24dbcc0ddc584ff27bc2a450c2..5db7911f25db5e1ebb736793704f23b36ee71144 100644 --- a/Test/baseResults/forLoop.frag.out +++ b/Test/baseResults/forLoop.frag.out @@ -1,4 +1,3 @@ -Warning, version 120 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:8 Function Definition: main( (void) 0:8 Function Parameters: diff --git a/Test/baseResults/forwardRef.frag.out b/Test/baseResults/forwardRef.frag.out index 6ea65d7627b8e9318de13b330a7445bc006c65b1..d63454a909454d511a8742805f02a28e1032029a 100644 --- a/Test/baseResults/forwardRef.frag.out +++ b/Test/baseResults/forwardRef.frag.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:11 Function Definition: main( (void) 0:11 Function Parameters: diff --git a/Test/baseResults/length.frag.out b/Test/baseResults/length.frag.out index b51af1706333a9557e43c6359f59dac25be3bea9..0543e1571ad2c6553524528e852e628a482e4d34 100644 --- a/Test/baseResults/length.frag.out +++ b/Test/baseResults/length.frag.out @@ -1,4 +1,3 @@ -Warning, version 120 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:11 Function Definition: main( (void) 0:11 Function Parameters: diff --git a/Test/baseResults/mains1.frag.out b/Test/baseResults/mains1.frag.out index 43dba1490e360ac3c4ffdcf781786a09c0f96bc6..723d725d194a1c09469000d49fabb36704eea5c9 100644 --- a/Test/baseResults/mains1.frag.out +++ b/Test/baseResults/mains1.frag.out @@ -1,5 +1,4 @@ mains1.frag -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:3 Function Definition: main( (void) @@ -7,7 +6,6 @@ Warning, version 110 is not yet complete; most features are present, but a few a 0:? Linker Objects mains2.frag -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:3 Function Definition: main( (void) diff --git a/Test/baseResults/matrixError.vert.out b/Test/baseResults/matrixError.vert.out index fa5a82bd9fab9df0ae53339bb435afb06cb3bbd6..70bdae84a395d43640df265672193b08ab88f30d 100644 --- a/Test/baseResults/matrixError.vert.out +++ b/Test/baseResults/matrixError.vert.out @@ -1,4 +1,3 @@ -Warning, version 120 is not yet complete; most features are present, but a few are missing. ERROR: 0:10: 'constructor' : too many arguments ERROR: 0:7: 'const' : non-matching or non-convertible constant type for const initializer ERROR: 0:17: 'assign' : cannot convert from '2-component vector of float' to '3-component vector of float' diff --git a/Test/baseResults/nonSquare.vert.out b/Test/baseResults/nonSquare.vert.out index 5257200f8a64446db77acd96f9a36ca6746e63e6..6b1961dd10a16f06a2adc96182e0c8faa5e13fbe 100644 --- a/Test/baseResults/nonSquare.vert.out +++ b/Test/baseResults/nonSquare.vert.out @@ -1,4 +1,3 @@ -Warning, version 120 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:15 Function Definition: main( (void) 0:15 Function Parameters: diff --git a/Test/baseResults/sample.frag.out b/Test/baseResults/sample.frag.out index 13c8679c410e5b241323a712d8e128c8b7e006d3..0e85f8e96a63906b312ef14e4e456ae79e8d812d 100644 --- a/Test/baseResults/sample.frag.out +++ b/Test/baseResults/sample.frag.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:38 Function Definition: main( (void) 0:38 Function Parameters: diff --git a/Test/baseResults/sample.vert.out b/Test/baseResults/sample.vert.out index 29e3a05c4b301591eac4ee1ca26b7d1bf58d3bda..e7942be4473c068229b26a5a2c156c1090344179 100644 --- a/Test/baseResults/sample.vert.out +++ b/Test/baseResults/sample.vert.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:38 Function Definition: main( (void) 0:38 Function Parameters: diff --git a/Test/baseResults/swizzle.frag.out b/Test/baseResults/swizzle.frag.out index 3f1b94719f9eb2d8f128806178737949f50d49cd..e6b3a9342b65d8aaacda8984743cf686cd43b64b 100644 --- a/Test/baseResults/swizzle.frag.out +++ b/Test/baseResults/swizzle.frag.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:9 Function Definition: main( (void) 0:9 Function Parameters: diff --git a/Test/baseResults/syntaxError.frag.out b/Test/baseResults/syntaxError.frag.out index f8264de077a4b965210c95a8a784bb9eedfdf49b..54df81398242dba32c5509ddcb6cf09709ebba5d 100644 --- a/Test/baseResults/syntaxError.frag.out +++ b/Test/baseResults/syntaxError.frag.out @@ -1,4 +1,3 @@ -Warning, version 120 is not yet complete; most features are present, but a few are missing. ERROR: 0:9: 'vec5' : undeclared identifier ERROR: 0:9: '' : syntax error ERROR: 2 compilation errors. No code generated. diff --git a/Test/baseResults/test.frag.out b/Test/baseResults/test.frag.out index 9e2a28917e200b42330f268b11e528392ec93edc..74bf2708919ed4b993cb2ceab0d40090c9432e56 100644 --- a/Test/baseResults/test.frag.out +++ b/Test/baseResults/test.frag.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:13 Function Definition: main( (void) 0:13 Function Parameters: diff --git a/Test/baseResults/versionsErrors.frag.out b/Test/baseResults/versionsErrors.frag.out index 6a5f61a35e9394e3741f73df2b74846e0889e0be..b339567bb7abe97c2fc75e59867c6b62fbe7644f 100644 --- a/Test/baseResults/versionsErrors.frag.out +++ b/Test/baseResults/versionsErrors.frag.out @@ -1,5 +1,4 @@ ERROR: #version: versions before 150 do not allow a profile token -Warning, version 110 is not yet complete; most features are present, but a few are missing. ERROR: 0:38: 'attribute' : not supported in this stage: fragment ERROR: 0:40: 'sampler2DRect' : Reserved word. ERROR: 0:40: 'rectangle texture' : not supported for this version or the enabled extensions diff --git a/Test/baseResults/voidFunction.frag.out b/Test/baseResults/voidFunction.frag.out index 5cc5d1eead20d3a21a0632b7c3f72274806f1e81..4b62cd21f9184c8c5e6540ee6216e8fd8fa92bfc 100644 --- a/Test/baseResults/voidFunction.frag.out +++ b/Test/baseResults/voidFunction.frag.out @@ -1,4 +1,3 @@ -Warning, version 120 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:7 Sequence 0:7 move second child to first child (float) diff --git a/Test/baseResults/whileLoop.frag.out b/Test/baseResults/whileLoop.frag.out index 4300f18113259fb045974991d5e62efc5157e2a8..7b25a0c3f8b568df083125bf4068923cdb6bdf06 100644 --- a/Test/baseResults/whileLoop.frag.out +++ b/Test/baseResults/whileLoop.frag.out @@ -1,4 +1,3 @@ -Warning, version 110 is not yet complete; most features are present, but a few are missing. 0:? Sequence 0:7 Function Definition: main( (void) 0:7 Function Parameters: diff --git a/Todo.txt b/Todo.txt index 1e6be183a1a01493c9ae94667bdd11464700221e..f3ce5b4919b9bea45e6aa4c6560d3afbed928503 100644 --- a/Todo.txt +++ b/Todo.txt @@ -57,7 +57,7 @@ Shader Functionality to Implement/Finish GLSL 1.2 + Handle multiple compilation units per stage + Allow initializers on uniform declarations - - signature matching takes type conversions into account, ambiguity is an error + + signature matching takes type conversions into account, ambiguity is an error - allow constructors to contain non-dereferenced arrays? GLSL 1.3 . flat is for both user and predeclared built-in in/out variables diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index e7e4bc37ca3b12495f2b622c528ded704c36604f..9ca44076c9b13906154e3004acc16978cac615df 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -846,20 +846,30 @@ public: // See if two types match, in all aspects except arrayness bool sameElementType(const TType& right) const { - return basicType == right.basicType && - sampler == right.sampler && + return basicType == right.basicType && sameElementShape(right); + } + + // See if two type's arrayness match + bool sameArrayness(const TType& right) const + { + return ((arraySizes == 0 && right.arraySizes == 0) || + (arraySizes && right.arraySizes && arraySizes->sizes == right.arraySizes->sizes)); + } + + // See if two type's elements match in all ways except basic type + bool sameElementShape(const TType& right) const + { + return sampler == right.sampler && vectorSize == right.vectorSize && matrixCols == right.matrixCols && matrixRows == right.matrixRows && sameStructType(right); } - // See if two types match in all ways (just the actual type, not qualification + // See if two types match in all ways (just the actual type, not qualification) bool operator==(const TType& right) const { - return sameElementType(right) && - ((arraySizes == 0 && right.arraySizes == 0) || - (arraySizes && right.arraySizes && arraySizes->sizes == right.arraySizes->sizes)); + return sameElementType(right) && sameArrayness(right); } bool operator!=(const TType& right) const diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 14c92a5f80e9a2938a9a2613f480178943c91a1b..c46b7e4dee653dd8877ffb86f7711eb1e9eebeea 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -829,7 +829,13 @@ TIntermAggregate* TParseContext::handleFunctionPrototype(TSourceLoc loc, TFuncti } // -// Handle seeing a function call in the grammar. +// Handle seeing function call syntax in the grammar, which could be any of +// - .length() method +// - constructor +// - a call to a built-in function mapped to an operator +// - a call to a built-in function that will remain a function call (e.g., texturing) +// - user function +// - subroutine call (not implemented yet) // TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCall, TIntermNode* intermNode, TIntermAggregate* intermAggregate) { @@ -866,11 +872,11 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal } } else { // - // Not a constructor. Find it in the symbol table. + // Find it in the symbol table. // const TFunction* fnCandidate; bool builtIn; - fnCandidate = findFunction(loc, fnCall, &builtIn); + fnCandidate = findFunction(loc, *fnCall, builtIn); if (fnCandidate) { // // A declared function. But, it might still map to a built-in @@ -898,6 +904,7 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName()); } + // Make sure storage qualifications work for these arguments. TStorageQualifier qual; TQualifierList& qualifierList = result->getAsAggregate()->getQualifierList(); for (int i = 0; i < fnCandidate->getParamCount(); ++i) { @@ -912,12 +919,6 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal if (builtIn) nonOpBuiltInCheck(loc, *fnCandidate, result->getAsAggregate()); } - } else { - // error message was put out by PaFindFunction() - // Put on a dummy node for error recovery - TConstUnionArray unionArray(1); - unionArray[0].setDConst(0.0); - result = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), loc); } } @@ -2543,24 +2544,105 @@ void TParseContext::checkNoShaderLayouts(TSourceLoc loc, const TPublicType& publ // // Return the function symbol if found, otherwise 0. // -const TFunction* TParseContext::findFunction(TSourceLoc loc, TFunction* call, bool *builtIn) +const TFunction* TParseContext::findFunction(TSourceLoc loc, const TFunction& call, bool& builtIn) { - TSymbol* symbol = symbolTable.find(call->getMangledName(), builtIn); + const TFunction* function = 0; + + if (profile == EEsProfile || version < 120) + function = findFunctionExact(loc, call, builtIn); + else if (version < 400) + function = findFunction120(loc, call, builtIn); + else + function = findFunction400(loc, call, builtIn); + return function; +} + +// Function finding algorithm for ES and desktop 110. +const TFunction* TParseContext::findFunctionExact(TSourceLoc loc, const TFunction& call, bool& builtIn) +{ + const TFunction* function = 0; + + TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn); if (symbol == 0) { - error(loc, "no matching overloaded function found", call->getName().c_str(), ""); + error(loc, "no matching overloaded function found", call.getName().c_str(), ""); return 0; } - const TFunction* function = symbol->getAsFunction(); - if (! function) { - error(loc, "function name expected", call->getName().c_str(), ""); + return symbol->getAsFunction(); +} - return 0; +// Function finding algorithm for desktop versions 120 through 330. +const TFunction* TParseContext::findFunction120(TSourceLoc loc, const TFunction& call, bool& builtIn) +{ + // first, look for an exact match + TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn); + if (symbol) + return symbol->getAsFunction(); + + // exact match not found, look through a list of overloaded functions of the same name + + // "If no exact match is found, then [implicit conversions] 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. When argument conversions are used to find + // a match, it is a semantic error if there are multiple ways to apply these conversions to make the call match + // more than one function." + + const TFunction* candidate = 0; + TVector<TFunction*> candidateList; + symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn); + + int numPossibleMatches = 0; + for (TVector<TFunction*>::const_iterator it = candidateList.begin(); it != candidateList.end(); ++it) { + bool possibleMatch = true; + const TFunction& function = *(*it); + for (int i = 0; i < function.getParamCount(); ++i) { + // same types is easy + if (*function[i].type == *call[i].type) + continue; + + // We have a mismatch in type, see if it is implicitly convertible + + if (function[i].type->isArray() || call[i].type->isArray() || + ! function[i].type->sameElementShape(*call[i].type)) + possibleMatch = false; + else { + // do direction-specific checks for conversion of basic type + TStorageQualifier qualifier = function[i].type->getQualifier().storage; + if (qualifier == EvqIn || qualifier == EvqInOut) { + if (! intermediate.canImplicitlyPromote(call[i].type->getBasicType(), function[i].type->getBasicType())) + possibleMatch = false; + } + if (qualifier == EvqOut || qualifier == EvqInOut) { + if (! intermediate.canImplicitlyPromote(function[i].type->getBasicType(), call[i].type->getBasicType())) + possibleMatch = false; + } + } + if (! possibleMatch) + break; + } + if (possibleMatch) { + if (candidate) { + // our second match, meaning ambiguity + error(loc, "ambiguous function signature match: multiple signatures match under implicit type conversion", call.getName().c_str(), ""); + } else + candidate = &function; + } } - return function; + if (candidate == 0) + error(loc, "no matching overloaded function found", call.getName().c_str(), ""); + + return candidate; +} + +// Function finding algorithm for desktop version 400 and above. +const TFunction* TParseContext::findFunction400(TSourceLoc loc, const TFunction& call, bool& builtIn) +{ + // TODO: 4.00 functionality: findFunction400() + return findFunction120(loc, call, builtIn); } // diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 4f9e0537d74741a58035b49daa61c54f1b17d769..7e499e7da8747a3dc89b31c33dab9d03ee3f4292 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -140,7 +140,10 @@ public: void layoutQualifierCheck(TSourceLoc, const TQualifier&); void checkNoShaderLayouts(TSourceLoc, const TPublicType&); - const TFunction* findFunction(TSourceLoc, TFunction* pfnCall, bool *builtIn = 0); + const TFunction* findFunction(TSourceLoc loc, const TFunction& call, bool& builtIn); + const TFunction* findFunctionExact(TSourceLoc loc, const TFunction& call, bool& builtIn); + const TFunction* findFunction120(TSourceLoc loc, const TFunction& call, bool& builtIn); + const TFunction* findFunction400(TSourceLoc loc, const TFunction& call, bool& builtIn); TIntermNode* declareVariable(TSourceLoc, TString& identifier, TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0); TIntermTyped* addConstructor(TSourceLoc, TIntermNode*, const TType&, TOperator); TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc); diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 9f8bc17a577e40418bd2d61131f51f654f14f8ca..407277674ccc29d81ca7c7073cb941a1da7e11b6 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -378,10 +378,11 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo switch(version) { case 100: case 300: - // versions are complete - break; + case 110: case 120: + // versions are complete + break; case 130: case 140: infoSink.info << "Warning, version " << version << " is not yet complete; most features are present, but a few are missing.\n"; diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h index b71d62cdd1fd05b85279d4bcbc6e34bb4b104f50..e51f9cee3d17cafb74745e5748c57e4992b3ef99 100644 --- a/glslang/MachineIndependent/SymbolTable.h +++ b/glslang/MachineIndependent/SymbolTable.h @@ -322,6 +322,19 @@ public: return (*it).second; } + void findFunctionNameList(const TString& name, TVector<TFunction*>& list) + { + size_t parenAt = name.find_first_of('('); + TString base(name, 0, parenAt + 1); + + tLevel::const_iterator begin = level.lower_bound(base); + base[parenAt] = ')'; // assume ')' is lexically after '(' + tLevel::const_iterator end = level.upper_bound(base); + for (tLevel::const_iterator it = begin; it != end; ++it) + list.push_back(it->second->getAsFunction()); + } + + // See if there is already a function in the table having the given non-function-style name. bool hasFunctionName(const TString& name) const { tLevel::const_iterator candidate = level.lower_bound(name); @@ -397,7 +410,7 @@ public: while (table.size() > adoptedLevels) pop(0); } - + void adoptLevels(TSymbolTable& symTable) { for (unsigned int level = 0; level < symTable.table.size(); ++level) { @@ -511,6 +524,27 @@ public: return symbol; } + void findFunctionNameList(const TString& name, TVector<TFunction*>& list, bool& builtIn) + { + // For user levels, return the set found in the first scope with a match + builtIn = false; + int level = currentLevel(); + do { + table[level]->findFunctionNameList(name, list); + --level; + } while (list.empty() && level >= globalLevel); + + if (! list.empty()) + return; + + // Gather across all built-in levels; they don't hide each other + builtIn = true; + do { + table[level]->findFunctionNameList(name, list); + --level; + } while (level >= 0); + } + void relateToOperator(const char* name, TOperator op) { for (unsigned int level = 0; level < table.size(); ++level)