diff --git a/Test/baseResults/hlsl.memberFunCall.frag.out b/Test/baseResults/hlsl.memberFunCall.frag.out
new file mode 100755
index 0000000000000000000000000000000000000000..97743606c0122b1000ba5798086c720888d09210
--- /dev/null
+++ b/Test/baseResults/hlsl.memberFunCall.frag.out
@@ -0,0 +1,264 @@
+hlsl.memberFunCall.frag
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:1  Function Definition: method3(f1; ( temp float)
+0:1    Function Parameters: 
+0:1      'a' ( in float)
+0:?     Sequence
+0:1      Branch: Return with expression
+0:1        Constant:
+0:1          1.000000
+0:4  Function Definition: myContext::method1( ( temp float)
+0:4    Function Parameters: 
+0:4      '@this' ( temp structure{ temp float f})
+0:?     Sequence
+0:4      Branch: Return with expression
+0:4        Function Call: myContext::method2( ( temp float)
+0:?           '@this' ( temp structure{ temp float f})
+0:5  Function Definition: myContext::method2( ( temp float)
+0:5    Function Parameters: 
+0:5      '@this' ( temp structure{ temp float f})
+0:?     Sequence
+0:5      Branch: Return with expression
+0:5        Function Call: myContext::method3(f1; ( temp float)
+0:?           '@this' ( temp structure{ temp float f})
+0:5          Constant:
+0:5            1.000000
+0:6  Function Definition: myContext::method3(f1; ( temp float)
+0:6    Function Parameters: 
+0:6      '@this' ( temp structure{ temp float f})
+0:6      'a' ( in float)
+0:?     Sequence
+0:6      Branch: Return with expression
+0:6        Function Call: myContext::method4(f1;f1; ( temp float)
+0:?           '@this' ( temp structure{ temp float f})
+0:6          'a' ( in float)
+0:6          'a' ( in float)
+0:7  Function Definition: myContext::method4(f1;f1; ( temp float)
+0:7    Function Parameters: 
+0:7      '@this' ( temp structure{ temp float f})
+0:7      'a' ( in float)
+0:7      'b' ( in float)
+0:?     Sequence
+0:7      Branch: Return with expression
+0:7        add ( temp float)
+0:7          add ( temp float)
+0:7            'a' ( in float)
+0:7            'b' ( in float)
+0:7          f: direct index for structure ( temp float)
+0:7            '@this' ( temp structure{ temp float f})
+0:7            Constant:
+0:7              0 (const uint)
+0:12  Function Definition: @main( ( temp 4-component vector of float)
+0:12    Function Parameters: 
+0:?     Sequence
+0:14      move second child to first child ( temp float)
+0:14        f: direct index for structure ( temp float)
+0:14          'context' ( temp structure{ temp float f})
+0:14          Constant:
+0:14            0 (const int)
+0:14        Constant:
+0:14          3.000000
+0:15      Branch: Return with expression
+0:15        Construct vec4 ( temp 4-component vector of float)
+0:15          Function Call: myContext::method1( ( temp float)
+0:15            'context' ( temp structure{ temp float f})
+0:12  Function Definition: main( ( temp void)
+0:12    Function Parameters: 
+0:?     Sequence
+0:12      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:12        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 500
+gl_FragCoord origin is upper left
+0:? Sequence
+0:1  Function Definition: method3(f1; ( temp float)
+0:1    Function Parameters: 
+0:1      'a' ( in float)
+0:?     Sequence
+0:1      Branch: Return with expression
+0:1        Constant:
+0:1          1.000000
+0:4  Function Definition: myContext::method1( ( temp float)
+0:4    Function Parameters: 
+0:4      '@this' ( temp structure{ temp float f})
+0:?     Sequence
+0:4      Branch: Return with expression
+0:4        Function Call: myContext::method2( ( temp float)
+0:?           '@this' ( temp structure{ temp float f})
+0:5  Function Definition: myContext::method2( ( temp float)
+0:5    Function Parameters: 
+0:5      '@this' ( temp structure{ temp float f})
+0:?     Sequence
+0:5      Branch: Return with expression
+0:5        Function Call: myContext::method3(f1; ( temp float)
+0:?           '@this' ( temp structure{ temp float f})
+0:5          Constant:
+0:5            1.000000
+0:6  Function Definition: myContext::method3(f1; ( temp float)
+0:6    Function Parameters: 
+0:6      '@this' ( temp structure{ temp float f})
+0:6      'a' ( in float)
+0:?     Sequence
+0:6      Branch: Return with expression
+0:6        Function Call: myContext::method4(f1;f1; ( temp float)
+0:?           '@this' ( temp structure{ temp float f})
+0:6          'a' ( in float)
+0:6          'a' ( in float)
+0:7  Function Definition: myContext::method4(f1;f1; ( temp float)
+0:7    Function Parameters: 
+0:7      '@this' ( temp structure{ temp float f})
+0:7      'a' ( in float)
+0:7      'b' ( in float)
+0:?     Sequence
+0:7      Branch: Return with expression
+0:7        add ( temp float)
+0:7          add ( temp float)
+0:7            'a' ( in float)
+0:7            'b' ( in float)
+0:7          f: direct index for structure ( temp float)
+0:7            '@this' ( temp structure{ temp float f})
+0:7            Constant:
+0:7              0 (const uint)
+0:12  Function Definition: @main( ( temp 4-component vector of float)
+0:12    Function Parameters: 
+0:?     Sequence
+0:14      move second child to first child ( temp float)
+0:14        f: direct index for structure ( temp float)
+0:14          'context' ( temp structure{ temp float f})
+0:14          Constant:
+0:14            0 (const int)
+0:14        Constant:
+0:14          3.000000
+0:15      Branch: Return with expression
+0:15        Construct vec4 ( temp 4-component vector of float)
+0:15          Function Call: myContext::method1( ( temp float)
+0:15            'context' ( temp structure{ temp float f})
+0:12  Function Definition: main( ( temp void)
+0:12    Function Parameters: 
+0:?     Sequence
+0:12      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:12        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 73
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 71
+                              ExecutionMode 4 OriginUpperLeft
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 10  "method3(f1;"
+                              Name 9  "a"
+                              Name 12  "myContext"
+                              MemberName 12(myContext) 0  "f"
+                              Name 16  "myContext::method1("
+                              Name 15  "@this"
+                              Name 19  "myContext::method2("
+                              Name 18  "@this"
+                              Name 24  "myContext::method3(f1;"
+                              Name 22  "@this"
+                              Name 23  "a"
+                              Name 30  "myContext::method4(f1;f1;"
+                              Name 27  "@this"
+                              Name 28  "a"
+                              Name 29  "b"
+                              Name 34  "@main("
+                              Name 42  "param"
+                              Name 46  "param"
+                              Name 48  "param"
+                              Name 63  "context"
+                              Name 71  "@entryPointOutput"
+                              Decorate 71(@entryPointOutput) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypePointer Function 6(float)
+               8:             TypeFunction 6(float) 7(ptr)
+   12(myContext):             TypeStruct 6(float)
+              13:             TypePointer Function 12(myContext)
+              14:             TypeFunction 6(float) 13(ptr)
+              21:             TypeFunction 6(float) 13(ptr) 7(ptr)
+              26:             TypeFunction 6(float) 13(ptr) 7(ptr) 7(ptr)
+              32:             TypeVector 6(float) 4
+              33:             TypeFunction 32(fvec4)
+              36:    6(float) Constant 1065353216
+              56:             TypeInt 32 1
+              57:     56(int) Constant 0
+              64:    6(float) Constant 1077936128
+              70:             TypePointer Output 32(fvec4)
+71(@entryPointOutput):     70(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              72:   32(fvec4) FunctionCall 34(@main()
+                              Store 71(@entryPointOutput) 72
+                              Return
+                              FunctionEnd
+ 10(method3(f1;):    6(float) Function None 8
+            9(a):      7(ptr) FunctionParameter
+              11:             Label
+                              ReturnValue 36
+                              FunctionEnd
+16(myContext::method1():    6(float) Function None 14
+       15(@this):     13(ptr) FunctionParameter
+              17:             Label
+              39:    6(float) FunctionCall 19(myContext::method2() 15(@this)
+                              ReturnValue 39
+                              FunctionEnd
+19(myContext::method2():    6(float) Function None 14
+       18(@this):     13(ptr) FunctionParameter
+              20:             Label
+       42(param):      7(ptr) Variable Function
+                              Store 42(param) 36
+              43:    6(float) FunctionCall 24(myContext::method3(f1;) 18(@this) 42(param)
+                              ReturnValue 43
+                              FunctionEnd
+24(myContext::method3(f1;):    6(float) Function None 21
+       22(@this):     13(ptr) FunctionParameter
+           23(a):      7(ptr) FunctionParameter
+              25:             Label
+       46(param):      7(ptr) Variable Function
+       48(param):      7(ptr) Variable Function
+              47:    6(float) Load 23(a)
+                              Store 46(param) 47
+              49:    6(float) Load 23(a)
+                              Store 48(param) 49
+              50:    6(float) FunctionCall 30(myContext::method4(f1;f1;) 22(@this) 46(param) 48(param)
+                              ReturnValue 50
+                              FunctionEnd
+30(myContext::method4(f1;f1;):    6(float) Function None 26
+       27(@this):     13(ptr) FunctionParameter
+           28(a):      7(ptr) FunctionParameter
+           29(b):      7(ptr) FunctionParameter
+              31:             Label
+              53:    6(float) Load 28(a)
+              54:    6(float) Load 29(b)
+              55:    6(float) FAdd 53 54
+              58:      7(ptr) AccessChain 27(@this) 57
+              59:    6(float) Load 58
+              60:    6(float) FAdd 55 59
+                              ReturnValue 60
+                              FunctionEnd
+      34(@main():   32(fvec4) Function None 33
+              35:             Label
+     63(context):     13(ptr) Variable Function
+              65:      7(ptr) AccessChain 63(context) 57
+                              Store 65 64
+              66:    6(float) FunctionCall 16(myContext::method1() 63(context)
+              67:   32(fvec4) CompositeConstruct 66 66 66 66
+                              ReturnValue 67
+                              FunctionEnd
diff --git a/Test/hlsl.memberFunCall.frag b/Test/hlsl.memberFunCall.frag
new file mode 100644
index 0000000000000000000000000000000000000000..27d3f6e0177dd5aadb2c827125f15b1f96c4bbf1
--- /dev/null
+++ b/Test/hlsl.memberFunCall.frag
@@ -0,0 +1,16 @@
+float method3(float a) { return 1.0; }
+
+struct myContext {
+    float method1() { return method2(); }
+    float method2() { return method3(1.0); }
+    float method3(float a) { return method4(a, a); }
+    float method4(float a, float b) { return a + b + f; }
+    float f;
+};
+
+float4 main() : SV_TARGET0
+{
+    myContext context;
+    context.f = 3.0;
+    return (float4)context.method1();
+}
diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h
index 3d88bc277ca2e2999adec2eecc07076b51fecc5a..f928b7aedfc80136c9f979e72fd92bddcaca56e4 100644
--- a/glslang/MachineIndependent/SymbolTable.h
+++ b/glslang/MachineIndependent/SymbolTable.h
@@ -262,6 +262,12 @@ public:
         mangledName.insert(0, prefix);
     }
 
+    virtual void removePrefix(const TString& prefix)
+    {
+        assert(mangledName.compare(0, prefix.size(), prefix) == 0);
+        mangledName.erase(0, prefix.size());
+    }
+
     virtual const TString& getMangledName() const override { return mangledName; }
     virtual const TType& getType() const override { return returnType; }
     virtual TBuiltInVariable getDeclaredBuiltInType() const { return declaredBuiltIn; }
@@ -686,19 +692,27 @@ public:
 
     // Normal find of a symbol, that can optionally say whether the symbol was found
     // at a built-in level or the current top-scope level.
-    TSymbol* find(const TString& name, bool* builtIn = 0, bool *currentScope = 0)
+    TSymbol* find(const TString& name, bool* builtIn = 0, bool* currentScope = 0, int* thisDepthP = 0)
     {
         int level = currentLevel();
         TSymbol* symbol;
+        int thisDepth = 0;
         do {
+            if (table[level]->isThisLevel())
+                ++thisDepth;
             symbol = table[level]->find(name);
             --level;
-        } while (symbol == 0 && level >= 0);
+        } while (symbol == nullptr && level >= 0);
         level++;
         if (builtIn)
             *builtIn = isBuiltInLevel(level);
         if (currentScope)
             *currentScope = isGlobalLevel(currentLevel()) || level == currentLevel();  // consider shared levels as "current scope" WRT user globals
+        if (thisDepthP != nullptr) {
+            if (! table[level]->isThisLevel())
+                thisDepth = 0;
+            *thisDepthP = thisDepth;
+        }
 
         return symbol;
     }
diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp
index 9612a4cfb5cd1248d5aa9ba9f6b71a0d11efd7a9..d1800d7877a3ccd80ad45ae3521544509bdab9f2 100644
--- a/gtests/Hlsl.FromFile.cpp
+++ b/gtests/Hlsl.FromFile.cpp
@@ -184,6 +184,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.nonint-index.frag", "main"},
         {"hlsl.matNx1.frag", "main"},
         {"hlsl.matrixSwizzle.vert", "ShaderFunction"},
+        {"hlsl.memberFunCall.frag", "main"},
         {"hlsl.mintypes.frag", "main"},
         {"hlsl.multiEntry.vert", "RealEntrypoint"},
         {"hlsl.multiReturn.frag", "main"},
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index cdf8a077744ed1f4eea07d91e8060be07c7c9b1f..69155850ae2a1778b5dced128d2d92b0af050b30 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -1933,7 +1933,7 @@ bool HlslGrammar::acceptStruct(TType& type, TIntermNode*& nodeList)
     // All member functions get parsed inside the class/struct namespace and with the
     // class/struct members in a symbol-table level.
     parseContext.pushNamespace(structName);
-    parseContext.pushThisScope(type);
+    parseContext.pushThisScope(type, functionDeclarators);
     bool deferredSuccess = true;
     for (int b = 0; b < (int)functionDeclarators.size() && deferredSuccess; ++b) {
         // parse body
diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp
index 85d973dd267f76634b1976b5a1ecdd71fe516def..70a2a655926f449d8b37cc191a30ec9c649d5f07 100755
--- a/hlsl/hlslParseHelper.cpp
+++ b/hlsl/hlslParseHelper.cpp
@@ -4319,6 +4319,7 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
         //
         const TFunction* fnCandidate = nullptr;
         bool builtIn = false;
+        int thisDepth = 0;
 
         // TODO: this needs improvement: there's no way at present to look up a signature in
         // the symbol table for an arbitrary type.  This is a temporary hack until that ability exists.
@@ -4351,7 +4352,7 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
         }
 
         if (fnCandidate == nullptr)
-            fnCandidate = findFunction(loc, *function, builtIn, arguments);
+            fnCandidate = findFunction(loc, *function, builtIn, thisDepth, arguments);
 
         if (fnCandidate) {
             // This is a declared function that might map to
@@ -4363,6 +4364,18 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
             if (builtIn && fnCandidate->getNumExtensions())
                 requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
 
+            // turn an implicit member-function resolution into an explicit call
+            TString callerName;
+            if (thisDepth == 0)
+                callerName = fnCandidate->getMangledName();
+            else {
+                // get the explicit (full) name of the function
+                callerName = currentTypePrefix[currentTypePrefix.size() - thisDepth];
+                callerName += fnCandidate->getMangledName();
+                // insert the implicit calling argument
+                pushFrontArguments(intermediate.addSymbol(*getImplicitThis(thisDepth)), arguments);
+            }
+
             // Convert 'in' arguments
             if (arguments)
                 addInputArgumentConversions(*fnCandidate, arguments);
@@ -4383,14 +4396,14 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
                 // It could still be a built-in function, but only if PureOperatorBuiltins == false.
                 result = intermediate.setAggregateOperator(arguments, EOpFunctionCall, fnCandidate->getType(), loc);
                 TIntermAggregate* call = result->getAsAggregate();
-                call->setName(fnCandidate->getMangledName());
+                call->setName(callerName);
 
                 // this is how we know whether the given function is a built-in function or a user-defined function
                 // if builtIn == false, it's a userDefined -> could be an overloaded built-in function also
                 // if builtIn == true, it's definitely a built-in function with EOpNull
                 if (! builtIn) {
                     call->setUserDefined();
-                    intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName());
+                    intermediate.addToCallGraph(infoSink, currentCaller, callerName);
                 }
             }
 
@@ -4427,6 +4440,19 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
     return result;
 }
 
+// An initial argument list is difficult: it can be null, or a single node,
+// or an aggregate if more than one argument.  Add one to the front, maintaining
+// this lack of uniformity.
+void HlslParseContext::pushFrontArguments(TIntermTyped* front, TIntermTyped*& arguments)
+{
+    if (arguments == nullptr)
+        arguments = front;
+    else if (arguments->getAsAggregate() != nullptr)
+        arguments->getAsAggregate()->getSequence().insert(arguments->getAsAggregate()->getSequence().begin(), front);
+    else
+        arguments = intermediate.growAggregate(front, arguments);
+}
+
 //
 // Add any needed implicit conversions for function-call arguments to input parameters.
 //
@@ -6184,18 +6210,17 @@ void HlslParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQuali
 //
 // Return the function symbol if found, otherwise nullptr.
 //
-const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction& call, bool& builtIn,
+const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction& call, bool& builtIn, int& thisDepth,
                                                 TIntermTyped*& args)
 {
-    // const TFunction* function = nullptr;
-
     if (symbolTable.isFunctionNameVariable(call.getName())) {
         error(loc, "can't use function syntax on variable", call.getName().c_str(), "");
         return nullptr;
     }
 
     // first, look for an exact match
-    TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn);
+    bool dummyScope;
+    TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn, &dummyScope, &thisDepth);
     if (symbol)
         return symbol->getAsFunction();
 
@@ -6205,7 +6230,7 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction
     TVector<const TFunction*> candidateList;
     symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
 
-    // These builtin ops can accept any type, so we bypass the argument selection
+    // These built-in ops can accept any type, so we bypass the argument selection
     if (candidateList.size() == 1 && builtIn &&
         (candidateList[0]->getBuiltInOp() == EOpMethodAppend ||
          candidateList[0]->getBuiltInOp() == EOpMethodRestartStrip ||
@@ -7782,11 +7807,23 @@ TIntermNode* HlslParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* ex
 
 // Make a new symbol-table level that is made out of the members of a structure.
 // This should be done as an anonymous struct (name is "") so that the symbol table
-// finds the members with on explicit reference to a 'this' variable.
-void HlslParseContext::pushThisScope(const TType& thisStruct)
+// finds the members with no explicit reference to a 'this' variable.
+void HlslParseContext::pushThisScope(const TType& thisStruct, const TVector<TFunctionDeclarator>& functionDeclarators)
 {
+    // member variables
     TVariable& thisVariable = *new TVariable(NewPoolTString(""), thisStruct);
     symbolTable.pushThis(thisVariable);
+
+    // member functions
+    for (auto it = functionDeclarators.begin(); it != functionDeclarators.end(); ++it) {
+        // member should have a prefix matching currentTypePrefix.back()
+        // but, symbol lookup within the class scope will just use the
+        // unprefixed name. Hence, there are two: one fully prefixed and
+        // one with no prefix.
+        TFunction& member = *it->function->clone();
+        member.removePrefix(currentTypePrefix.back());
+        symbolTable.insert(member);
+    }
 }
 
 // Track levels of class/struct/namespace nesting with a prefix string using
@@ -7801,11 +7838,10 @@ void HlslParseContext::pushNamespace(const TString& typeName)
 {
     // make new type prefix
     TString newPrefix;
-    if (currentTypePrefix.size() > 0) {
+    if (currentTypePrefix.size() > 0)
         newPrefix = currentTypePrefix.back();
-        newPrefix.append(scopeMangler);
-    }
     newPrefix.append(typeName);
+    newPrefix.append(scopeMangler);
     currentTypePrefix.push_back(newPrefix);
 }
 
@@ -7823,7 +7859,6 @@ void HlslParseContext::getFullNamespaceName(const TString*& name) const
         return;
 
     TString* fullName = NewPoolTString(currentTypePrefix.back().c_str());
-    fullName->append(scopeMangler);
     fullName->append(*name);
     name = fullName;
 }
diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h
index 592cd82933cda0834249db03491fa4dcdd19d26a..c981392dbfec3c56183d0fa91b7ab278d8759652 100755
--- a/hlsl/hlslParseHelper.h
+++ b/hlsl/hlslParseHelper.h
@@ -42,6 +42,7 @@
 namespace glslang {
 
 class TAttributeMap; // forward declare
+class TFunctionDeclarator;
 
 class HlslParseContext : public TParseContextBase {
 public:
@@ -93,6 +94,7 @@ public:
     void decomposeSampleMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
     void decomposeStructBufferMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
     void decomposeGeometryMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
+    void pushFrontArguments(TIntermTyped* front, TIntermTyped*& arguments);
     void addInputArgumentConversions(const TFunction&, TIntermTyped*&);
     TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&);
     void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
@@ -135,7 +137,7 @@ public:
     void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
     void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
 
-    const TFunction* findFunction(const TSourceLoc& loc, TFunction& call, bool& builtIn, TIntermTyped*& args);
+    const TFunction* findFunction(const TSourceLoc& loc, TFunction& call, bool& builtIn, int& thisDepth, TIntermTyped*& args);
     void declareTypedef(const TSourceLoc&, const TString& identifier, const TType&);
     void declareStruct(const TSourceLoc&, TString& structName, TType&);
     TSymbol* lookupUserType(const TString&, TType&);
@@ -166,7 +168,7 @@ public:
     void pushScope()         { symbolTable.push(); }
     void popScope()          { symbolTable.pop(0); }
 
-    void pushThisScope(const TType&);
+    void pushThisScope(const TType&, const TVector<TFunctionDeclarator>&);
     void popThisScope()      { symbolTable.pop(0); }
 
     void pushImplicitThis(TVariable* thisParameter) { implicitThisStack.push_back(thisParameter); }