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)