Switch NamespaceDecl from its own hand-rolled redeclaration chain over
to Redeclarable<NamespaceDecl>, so that we benefit from the improveed
redeclaration deserialization and merging logic provided by
Redeclarable<T>. Otherwise, no functionality change.

As a drive-by fix, collapse the "inline" bit into the low bit of the
original namespace/anonymous namespace, saving 8 bytes per
NamespaceDecl on x86_64.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147729 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 82307e8..10f5a20 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -2083,8 +2083,10 @@
   NamespaceDecl *ToNamespace = MergeWithNamespace;
   if (!ToNamespace) {
     ToNamespace = NamespaceDecl::Create(Importer.getToContext(), DC,
+                                        D->isInline(),
                                         Importer.Import(D->getLocStart()),
-                                        Loc, Name.getAsIdentifierInfo());
+                                        Loc, Name.getAsIdentifierInfo(),
+                                        /*PrevDecl=*/0);
     ToNamespace->setLexicalDeclContext(LexicalDC);
     LexicalDC->addDeclInternal(ToNamespace);
     
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 3fc507e..0312cfb 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -839,15 +839,21 @@
   }
 }
 
-DeclContext *DeclContext::getNextContext() {
-  switch (DeclKind) {
-  case Decl::Namespace:
-    // Return the next namespace
-    return static_cast<NamespaceDecl*>(this)->getNextNamespace();
-
-  default:
-    return 0;
+void 
+DeclContext::collectAllContexts(llvm::SmallVectorImpl<DeclContext *> &Contexts){
+  Contexts.clear();
+  
+  if (DeclKind != Decl::Namespace) {
+    Contexts.push_back(this);
+    return;
   }
+  
+  NamespaceDecl *Self = static_cast<NamespaceDecl *>(this);
+  for (NamespaceDecl *N = Self->getMostRecentDeclaration(); N;
+       N = N->getPreviousDeclaration())
+    Contexts.push_back(N);
+  
+  std::reverse(Contexts.begin(), Contexts.end());
 }
 
 std::pair<Decl *, Decl *>
@@ -1067,15 +1073,17 @@
 /// declarations in DCtx (and any other contexts linked to it or
 /// transparent contexts nested within it).
 void DeclContext::buildLookup(DeclContext *DCtx) {
-  for (; DCtx; DCtx = DCtx->getNextContext()) {
-    for (decl_iterator D = DCtx->decls_begin(),
-                    DEnd = DCtx->decls_end();
+  llvm::SmallVector<DeclContext *, 2> Contexts;
+  DCtx->collectAllContexts(Contexts);
+  for (unsigned I = 0, N = Contexts.size(); I != N; ++I) {
+    for (decl_iterator D = Contexts[I]->decls_begin(),
+                    DEnd = Contexts[I]->decls_end();
          D != DEnd; ++D) {
       // Insert this declaration into the lookup structure, but only
       // if it's semantically in its decl context.  During non-lazy
       // lookup building, this is implicitly enforced by addDecl.
       if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
-        if (D->getDeclContext() == DCtx)
+        if (D->getDeclContext() == Contexts[I])
           makeDeclVisibleInContextImpl(ND, false);
 
       // If this declaration is itself a transparent declaration context or
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index ba369bb..f820e9b 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -1767,20 +1767,30 @@
 
 void NamespaceDecl::anchor() { }
 
+NamespaceDecl::NamespaceDecl(DeclContext *DC, bool Inline, 
+                             SourceLocation StartLoc,
+                             SourceLocation IdLoc, IdentifierInfo *Id,
+                             NamespaceDecl *PrevDecl)
+  : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
+    LocStart(StartLoc), RBraceLoc(), AnonOrFirstNamespaceAndInline(0, Inline) 
+{
+  setPreviousDeclaration(PrevDecl);
+  
+  if (PrevDecl)
+    AnonOrFirstNamespaceAndInline.setPointer(PrevDecl->getOriginalNamespace());
+}
+
 NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
-                                     SourceLocation StartLoc,
-                                     SourceLocation IdLoc, IdentifierInfo *Id) {
-  return new (C) NamespaceDecl(DC, StartLoc, IdLoc, Id);
+                                     bool Inline, SourceLocation StartLoc,
+                                     SourceLocation IdLoc, IdentifierInfo *Id,
+                                     NamespaceDecl *PrevDecl) {
+  return new (C) NamespaceDecl(DC, Inline, StartLoc, IdLoc, Id, PrevDecl);
 }
 
 NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NamespaceDecl));
-  return new (Mem) NamespaceDecl(0, SourceLocation(), SourceLocation(), 0);
-}
-
-NamespaceDecl *NamespaceDecl::getNextNamespace() {
-  return dyn_cast_or_null<NamespaceDecl>(
-                                         NextNamespace.get(getASTContext().getExternalSource()));
+  return new (Mem) NamespaceDecl(0, false, SourceLocation(), SourceLocation(), 
+                                 0, 0);
 }
 
 void NamespaceAliasDecl::anchor() { }