Introduce ScopedDecl::getLexicalDeclContext() which is different from ScopedDecl::getDeclContext() when there are nested-names.
e.g.:
  namespace A {
    void f(); // SemanticDC (getDeclContext) == LexicalDC (getLexicalDeclContext) == 'namespace A'
  }
  void A::f(); // SemanticDC == namespace 'A'
               // LexicalDC == global namespace


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58948 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index cae05a3..6c71d50 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -53,8 +53,8 @@
 DeclContext *Sema::getContainingDC(DeclContext *DC) {
   if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC)) {
     // A C++ out-of-line method will return to the file declaration context.
-    if (!MD->isInlineDefinition())
-      return LexicalFileContext;
+    if (MD->isOutOfLineDefinition())
+      return MD->getLexicalDeclContext();
 
     // A C++ inline method is parsed *after* the topmost class it was declared in
     // is fully parsed (it's "complete").
@@ -70,25 +70,24 @@
     return DC;
   }
 
-  if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC))
-    return LexicalFileContext;
+  if (isa<ObjCMethodDecl>(DC))
+    return Context.getTranslationUnitDecl();
+
+  if (ScopedDecl *SD = dyn_cast<ScopedDecl>(DC))
+    return SD->getLexicalDeclContext();
 
   return DC->getParent();
 }
 
 void Sema::PushDeclContext(DeclContext *DC) {
   assert(getContainingDC(DC) == CurContext &&
-       "The next DeclContext should be directly contained in the current one.");
+       "The next DeclContext should be lexically contained in the current one.");
   CurContext = DC;
-  if (CurContext->isFileContext())
-    LexicalFileContext = CurContext;
 }
 
 void Sema::PopDeclContext() {
   assert(CurContext && "DeclContext imbalance!");
   CurContext = getContainingDC(CurContext);
-  if (CurContext->isFileContext())
-    LexicalFileContext = CurContext;
 }
 
 /// Add this decl to the scope shadowed decl chains.
@@ -1147,6 +1146,10 @@
     New = NewVD;
   }
   
+  // Set the lexical context. If the declarator has a C++ scope specifier, the
+  // lexical context will be different from the semantic context.
+  New->setLexicalDeclContext(CurContext);
+
   // If this has an identifier, add it to the scope stack.
   if (II)
     PushOnScopeChains(New, S);
@@ -2004,10 +2007,6 @@
     Diag(Definition->getLocation(), diag::err_previous_definition);
   }
 
-  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
-    if (isa<CXXRecordDecl>(CurContext))
-      MD->setInlineDefinition(true);
-
   PushDeclContext(FD);
     
   // Check the validity of our function parameters
@@ -2267,6 +2266,11 @@
   
   if (Attr)
     ProcessDeclAttributeList(New, Attr);
+
+  // Set the lexical context. If the tag has a C++ scope specifier, the
+  // lexical context will be different from the semantic context.
+  New->setLexicalDeclContext(CurContext);
+
   return New;
 }
 
@@ -2421,6 +2425,10 @@
   if (Attr)
     ProcessDeclAttributeList(New, Attr);
 
+  // Set the lexical context. If the tag has a C++ scope specifier, the
+  // lexical context will be different from the semantic context.
+  New->setLexicalDeclContext(CurContext);
+
   return New;
 }