-Add DeclChain member to DeclContext.
-ScopedDecls get chained to their DeclContext.
-DeclContext's DeclChain replaces FunctionDecl's DeclChain and EnumDecl's ElementList.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52164 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 47334f5..949d100 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -116,7 +116,7 @@
 }
 
 void EnumDecl::Destroy(ASTContext& C) {
-  if (ElementList) ElementList->Destroy(C);
+  if (getEnumConstantList()) getEnumConstantList()->Destroy(C);
   Decl::Destroy(C);
 }
 
diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp
index ca9a152..2ba8910 100644
--- a/lib/AST/DeclSerialization.cpp
+++ b/lib/AST/DeclSerialization.cpp
@@ -30,10 +30,13 @@
 void Decl::Emit(Serializer& S) const {
   S.EmitInt(getKind());
   EmitImpl(S);
+  if (const DeclContext *DC = dyn_cast<const DeclContext>(this))
+    DC->EmitOutRec(S);
 }
 
 Decl* Decl::Create(Deserializer& D, ASTContext& C) {
 
+  Decl *Dcl;
   Kind k = static_cast<Kind>(D.ReadInt());
 
   switch (k) {
@@ -42,39 +45,56 @@
       break;
 
     case TranslationUnit:
-      return TranslationUnitDecl::CreateImpl(D, C);
+      Dcl = TranslationUnitDecl::CreateImpl(D, C);
+      break;
 
     case Namespace:
-      return NamespaceDecl::CreateImpl(D, C);
+      Dcl = NamespaceDecl::CreateImpl(D, C);
+      break;
 
     case Var:
-      return VarDecl::CreateImpl(D, C);
+      Dcl = VarDecl::CreateImpl(D, C);
+      break;
       
     case Enum:
-      return EnumDecl::CreateImpl(D, C);
+      Dcl = EnumDecl::CreateImpl(D, C);
+      break;
       
     case EnumConstant:
-      return EnumConstantDecl::CreateImpl(D, C);
+      Dcl = EnumConstantDecl::CreateImpl(D, C);
+      break;
       
     case Field:
-      return FieldDecl::CreateImpl(D, C);
+      Dcl = FieldDecl::CreateImpl(D, C);
+      break;
       
     case ParmVar:
-      return ParmVarDecl::CreateImpl(D, C);
+      Dcl = ParmVarDecl::CreateImpl(D, C);
+      break;
       
     case Function:
-      return FunctionDecl::CreateImpl(D, C);
-     
+      Dcl = FunctionDecl::CreateImpl(D, C);
+      break;
+    
+    case Class:
     case Union:
     case Struct:
-      return RecordDecl::CreateImpl(k, D, C);
+      Dcl = RecordDecl::CreateImpl(k, D, C);
+      break;
       
     case Typedef:
-      return TypedefDecl::CreateImpl(D, C);
+      Dcl = TypedefDecl::CreateImpl(D, C);
+      break;
       
     case FileScopeAsm:
-      return FileScopeAsmDecl::CreateImpl(D, C);
+      Dcl = FileScopeAsmDecl::CreateImpl(D, C);
+      break;
   }
+
+  if (DeclContext *DC = dyn_cast<DeclContext>(Dcl))
+    DC->ReadOutRec(D, C);
+
+  return Dcl;
 }
 
 //===----------------------------------------------------------------------===//
@@ -90,6 +110,18 @@
 }
 
 //===----------------------------------------------------------------------===//
+//      Common serialization logic for subclasses of DeclContext.
+//===----------------------------------------------------------------------===//
+
+void DeclContext::EmitOutRec(Serializer& S) const {
+  S.EmitPtr(DeclChain);
+}
+
+void DeclContext::ReadOutRec(Deserializer& D, ASTContext& C) {
+  D.ReadPtr(DeclChain);
+}
+
+//===----------------------------------------------------------------------===//
 //      Common serialization logic for subclasses of NamedDecl.
 //===----------------------------------------------------------------------===//
 
@@ -283,7 +315,7 @@
   ScopedDecl::EmitInRec(S);
   S.EmitBool(isDefinition());
   S.Emit(IntegerType);  
-  S.BatchEmitOwnedPtrs(ElementList,getNextDeclarator());
+  S.BatchEmitOwnedPtrs(getEnumConstantList(),getNextDeclarator());
 }
 
 EnumDecl* EnumDecl::CreateImpl(Deserializer& D, ASTContext& C) {
@@ -299,7 +331,7 @@
   
   D.BatchReadOwnedPtrs(Elist, next_declarator, C);
   
-  decl->ElementList = cast_or_null<EnumConstantDecl>(Elist);
+  decl->setDeclChain(cast_or_null<EnumConstantDecl>(Elist));
   decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
   
   return decl;
@@ -361,7 +393,6 @@
   S.EmitInt(SClass);           // From FunctionDecl.
   S.EmitBool(IsInline);        // From FunctionDecl.
   ValueDecl::EmitInRec(S);
-  S.EmitPtr(DeclChain);
   S.EmitPtr(PreviousDeclaration);
   
   // NOTE: We do not need to serialize out the number of parameters, because
@@ -388,7 +419,6 @@
                  QualType(), SClass, IsInline, 0);
   
   decl->ValueDecl::ReadInRec(D, C);
-  D.ReadPtr(decl->DeclChain);
   D.ReadPtr(decl->PreviousDeclaration);
 
   Decl* next_declarator;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index ba005b2..2d6422f 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/Attr.h"
 #include "clang/AST/Builtins.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Type.h"
 #include "clang/Parse/DeclSpec.h"
@@ -90,34 +91,27 @@
   if (S->decl_empty()) return;
   assert((S->getFlags() & Scope::DeclScope) &&"Scope shouldn't contain decls!");
 
-  // We only want to remove the decls from the identifier decl chains for local
-  // scopes, when inside a function/method.
-  if (S->getFnParent() == 0)
-    return;
-         
   for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
        I != E; ++I) {
     Decl *TmpD = static_cast<Decl*>(*I);
     assert(TmpD && "This decl didn't get pushed??");
-    ScopedDecl *D = dyn_cast<ScopedDecl>(TmpD);
-    assert(D && "This decl isn't a ScopedDecl?");
+
+    if (isa<CXXFieldDecl>(TmpD)) continue;
+
+    assert(isa<ScopedDecl>(TmpD) && "Decl isn't ScopedDecl?");
+    ScopedDecl *D = cast<ScopedDecl>(TmpD);
     
     IdentifierInfo *II = D->getIdentifier();
     if (!II) continue;
     
-    // Unlink this decl from the identifier.
-    IdResolver.RemoveDecl(D);
+    // We only want to remove the decls from the identifier decl chains for local
+    // scopes, when inside a function/method.
+    if (S->getFnParent() != 0)
+      IdResolver.RemoveDecl(D);
 
-    // This will have to be revisited for C++: there we want to nest stuff in
-    // namespace decls etc.  Even for C, we might want a top-level translation
-    // unit decl or something.
-    if (!CurFunctionDecl)
-      continue;
-
-    // Chain this decl to the containing function, it now owns the memory for
-    // the decl.
-    D->setNext(CurFunctionDecl->getDeclChain());
-    CurFunctionDecl->setDeclChain(D);
+    // Chain this decl to the containing DeclContext.
+    D->setNext(CurContext->getDeclChain());
+    CurContext->setDeclChain(D);
   }
 }