HLSL non-functional: Generalize namespace nesting.

Also use this to move deferred member-function-body parsing to a better
place.

This should also be well poised for implementing the 'namespace' keyword.
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index 1dc500b..be58dbc 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -1788,7 +1788,7 @@
     postDeclQualifier.clear();
     bool postDeclsFound = acceptPostDecls(postDeclQualifier);
 
-    // LEFT_BRACE
+    // LEFT_BRACE, or
     // struct_type IDENTIFIER
     if (! acceptTokenClass(EHTokLeftBrace)) {
         if (structName.size() > 0 && !postDeclsFound && parseContext.lookupUserType(structName, type) != nullptr) {
@@ -1800,9 +1800,17 @@
         }
     }
 
+
     // struct_declaration_list
     TTypeList* typeList;
-    if (! acceptStructDeclarationList(typeList, nodeList, structName)) {
+    // Save each member function so they can be processed after we have a fully formed 'this'.
+    TVector<TFunctionDeclarator> functionDeclarators;
+
+    parseContext.pushNamespace(structName);
+    bool acceptedList = acceptStructDeclarationList(typeList, nodeList, structName, functionDeclarators);
+    parseContext.popNamespace();
+
+    if (! acceptedList) {
         expected("struct member declarations");
         return false;
     }
@@ -1823,7 +1831,20 @@
 
     parseContext.declareStruct(token.loc, structName, type);
 
-    return true;
+    // All member functions get parsed inside the class/struct namespace and with the
+    // class/struct members in a symbol-table level.
+    parseContext.pushNamespace(structName);
+    bool deferredSuccess = true;
+    for (int b = 0; b < (int)functionDeclarators.size() && deferredSuccess; ++b) {
+        // parse body
+        pushTokenStream(functionDeclarators[b].body);
+        if (! acceptFunctionBody(functionDeclarators[b], nodeList))
+            deferredSuccess = false;
+        popTokenStream();
+    }
+    parseContext.popNamespace();
+
+    return deferredSuccess;
 }
 
 // struct_buffer
@@ -1934,16 +1955,12 @@
 //      | IDENTIFIER array_specifier post_decls
 //      | IDENTIFIER function_parameters post_decls                                         // member-function prototype
 //
-bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*& nodeList, const TString& typeName)
+bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*& nodeList, const TString& typeName,
+                                              TVector<TFunctionDeclarator>& declarators)
 {
     typeList = new TTypeList();
     HlslToken idToken;
 
-    // Save these away for each member function so they can be processed after
-    // all member variables/types have been declared.
-    TVector<TVector<HlslToken>*> memberBodies;
-    TVector<TFunctionDeclarator> declarators;
-
     do {
         // success on seeing the RIGHT_BRACE coming up
         if (peekTokenClass(EHTokRightBrace))
@@ -1973,11 +1990,8 @@
                 if (!declarator_list) {
                     declarators.resize(declarators.size() + 1);
                     // request a token stream for deferred processing
-                    TVector<HlslToken>* deferredTokens = new TVector<HlslToken>;
-                    functionDefinitionAccepted = acceptMemberFunctionDefinition(nodeList, typeName, memberType,
-                                                                                *idToken.string, declarators.back(),
-                                                                                deferredTokens);
-                    memberBodies.push_back(deferredTokens);
+                    functionDefinitionAccepted = acceptMemberFunctionDefinition(nodeList, memberType, *idToken.string,
+                                                                                declarators.back());
                     if (functionDefinitionAccepted)
                         break;
                 }
@@ -2030,14 +2044,6 @@
 
     } while (true);
 
-    // parse member-function bodies now
-    for (int b = 0; b < (int)memberBodies.size(); ++b) {
-        pushTokenStream(memberBodies[b]);
-        if (! acceptFunctionBody(declarators[b], nodeList))
-            return false;
-        popTokenStream();
-    }
-
     return true;
 }
 
@@ -2046,15 +2052,12 @@
 //
 // Expects type to have EvqGlobal for a static member and
 // EvqTemporary for non-static member.
-bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TString& typeName,
-                                                 const TType& type, const TString& memberName,
-                                                 TFunctionDeclarator& declarator, TVector<HlslToken>* deferredTokens)
+bool HlslGrammar::acceptMemberFunctionDefinition(TIntermNode*& nodeList, const TType& type, const TString& memberName,
+                                                 TFunctionDeclarator& declarator)
 {
-    // watch early returns...
-    parseContext.pushThis(typeName);
     bool accepted = false;
 
-    TString* functionName = parseContext.getFullMemberFunctionName(memberName, type.getQualifier().storage == EvqGlobal);
+    TString* functionName = parseContext.getFullNamespaceName(memberName);
     declarator.function = new TFunction(functionName, type);
 
     // function_parameters
@@ -2070,12 +2073,12 @@
             }
 
             declarator.loc = token.loc;
-            accepted = acceptFunctionDefinition(declarator, nodeList, deferredTokens);
+            declarator.body = new TVector<HlslToken>;
+            accepted = acceptFunctionDefinition(declarator, nodeList, declarator.body);
         }
     } else
         expected("function parameter list");
 
-    parseContext.popThis();
     return accepted;
 }
 
@@ -2781,13 +2784,8 @@
         functionName = callToken.string;
     else {
         functionName = NewPoolTString("");
-        if (baseObject != nullptr) {
-            functionName->append(baseObject->getType().getTypeName().c_str());
-            functionName->append(".");
-        } else if (baseType != nullptr) {
-            functionName->append(baseType->getType().getTypeName());
-            functionName->append("::");
-        }
+        functionName->append(baseType->getType().getTypeName());
+        parseContext.addScopeMangler(*functionName);
         functionName->append(*callToken.string);
     }
 
@@ -2795,7 +2793,6 @@
     TFunction* function = new TFunction(functionName, TType(EbtVoid));
 
     // arguments
-    // Non-static member functions have an implicit first argument of the base object.
     TIntermTyped* arguments = nullptr;
     if (baseObject != nullptr)
         parseContext.handleFunctionArgument(function, arguments, baseObject);