Remove ScopedDecl, collapsing all of its functionality into Decl, so
that every declaration lives inside a DeclContext.

Moved several things that don't have names but were ScopedDecls (and,
therefore, NamedDecls) to inherit from Decl rather than NamedDecl,
including ObjCImplementationDecl and LinkageSpecDecl. Now, we don't
store empty DeclarationNames for these things, nor do we try to insert
them into DeclContext's lookup structure.

The serialization tests are temporarily disabled. We'll re-enable them
once we've sorted out the remaining ownership/serialiazation issues
between DeclContexts and TranslationUnion, DeclGroups, etc.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62562 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 192c068..057dfb7 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -537,7 +537,7 @@
                                           RecFields[i]->getLocation(), 
                                           RecFields[i]->getIdentifier(),
                                           RecFields[i]->getType(), 
-                                          RecFields[i]->getBitWidth(), false, 0);
+                                          RecFields[i]->getBitWidth(), false);
     NewRD->addDecl(Field);
   }
   NewRD->completeDefinition(*this);
@@ -1586,7 +1586,7 @@
       FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl, 
                                            SourceLocation(), 0,
                                            FieldTypes[i], /*BitWidth=*/0, 
-                                           /*Mutable=*/false, /*PrevDecl=*/0);
+                                           /*Mutable=*/false);
       CFConstantStringTypeDecl->addDecl(Field);
     }
 
@@ -1616,7 +1616,7 @@
                                            ObjCFastEnumerationStateTypeDecl, 
                                            SourceLocation(), 0, 
                                            FieldTypes[i], /*BitWidth=*/0, 
-                                           /*Mutable=*/false, /*PrevDecl=*/0);
+                                           /*Mutable=*/false);
       ObjCFastEnumerationStateTypeDecl->addDecl(Field);
     }
     
diff --git a/lib/AST/CFG.cpp b/lib/AST/CFG.cpp
index b84ead7..2ea8388 100644
--- a/lib/AST/CFG.cpp
+++ b/lib/AST/CFG.cpp
@@ -42,7 +42,7 @@
   T old_value;
 };
   
-static SourceLocation GetEndLoc(ScopedDecl* D) {
+static SourceLocation GetEndLoc(Decl* D) {
   if (VarDecl* VD = dyn_cast<VarDecl>(D))
     if (Expr* Ex = VD->getInit())
       return Ex->getSourceRange().getEnd();
@@ -150,7 +150,7 @@
   CFGBlock* addStmt(Stmt* Terminator);
   CFGBlock* WalkAST(Stmt* Terminator, bool AlwaysAddStmt);
   CFGBlock* WalkAST_VisitChildren(Stmt* Terminator);
-  CFGBlock* WalkAST_VisitDeclSubExpr(ScopedDecl* D);
+  CFGBlock* WalkAST_VisitDeclSubExpr(Decl* D);
   CFGBlock* WalkAST_VisitStmtExpr(StmtExpr* Terminator);
   void FinishBlock(CFGBlock* B);
   
@@ -363,7 +363,7 @@
         return WalkAST_VisitDeclSubExpr(DS->getSolitaryDecl());
       }
       else {
-        typedef llvm::SmallVector<ScopedDecl*,10> BufTy;
+        typedef llvm::SmallVector<Decl*,10> BufTy;
         BufTy Buf;        
         CFGBlock* B = 0;
 
@@ -384,7 +384,7 @@
           // that Decl* will not get deallocated because the destroy method
           // of DG is never called.
           DeclGroupOwningRef DG(*I);
-          ScopedDecl* D = *I;
+          Decl* D = *I;
           void* Mem = cfg->getAllocator().Allocate(sizeof(DeclStmt), A);
           
           DeclStmt* DS = new (Mem) DeclStmt(DG, D->getLocation(),
@@ -486,7 +486,7 @@
   
 /// WalkAST_VisitDeclSubExpr - Utility method to add block-level expressions
 ///  for initializers in Decls.
-CFGBlock* CFGBuilder::WalkAST_VisitDeclSubExpr(ScopedDecl* D) {
+CFGBlock* CFGBuilder::WalkAST_VisitDeclSubExpr(Decl* D) {
   VarDecl* VD = dyn_cast<VarDecl>(D);
 
   if (!VD)
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 5ec6aff..9ddc62a 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -44,17 +44,17 @@
 
 
 ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC,
-    SourceLocation L, IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl) {
+    SourceLocation L, IdentifierInfo *Id, QualType T) {
   void *Mem = C.getAllocator().Allocate<ImplicitParamDecl>();
-  return new (Mem) ImplicitParamDecl(ImplicitParam, DC, L, Id, T, PrevDecl);
+  return new (Mem) ImplicitParamDecl(ImplicitParam, DC, L, Id, T);
 }
 
 ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
                                  SourceLocation L, IdentifierInfo *Id,
                                  QualType T, StorageClass S,
-                                 Expr *DefArg, ScopedDecl *PrevDecl) {
+                                 Expr *DefArg) {
   void *Mem = C.getAllocator().Allocate<ParmVarDecl>();
-  return new (Mem) ParmVarDecl(ParmVar, DC, L, Id, T, S, DefArg, PrevDecl);
+  return new (Mem) ParmVarDecl(ParmVar, DC, L, Id, T, S, DefArg);
 }
 
 QualType ParmVarDecl::getOriginalType() const {
@@ -68,20 +68,18 @@
                                  ASTContext &C, DeclContext *DC,
                                  SourceLocation L, IdentifierInfo *Id,
                                  QualType T, QualType OT, StorageClass S,
-                                 Expr *DefArg, ScopedDecl *PrevDecl) {
+                                 Expr *DefArg) {
   void *Mem = C.getAllocator().Allocate<ParmVarWithOriginalTypeDecl>();
-  return new (Mem) ParmVarWithOriginalTypeDecl(DC, L, Id, T, OT, S, 
-                                               DefArg, PrevDecl);
+  return new (Mem) ParmVarWithOriginalTypeDecl(DC, L, Id, T, OT, S, DefArg);
 }
 
 FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
                                    SourceLocation L, 
                                    DeclarationName N, QualType T, 
                                    StorageClass S, bool isInline, 
-                                   ScopedDecl *PrevDecl,
                                    SourceLocation TypeSpecStartLoc) {
   void *Mem = C.getAllocator().Allocate<FunctionDecl>();
-  return new (Mem) FunctionDecl(Function, DC, L, N, T, S, isInline, PrevDecl,
+  return new (Mem) FunctionDecl(Function, DC, L, N, T, S, isInline,
                                 TypeSpecStartLoc);
 }
 
@@ -92,9 +90,9 @@
 
 FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
                              IdentifierInfo *Id, QualType T, Expr *BW,
-                             bool Mutable, ScopedDecl *PrevDecl) {
+                             bool Mutable) {
   void *Mem = C.getAllocator().Allocate<FieldDecl>();
-  return new (Mem) FieldDecl(Decl::Field, DC, L, Id, T, BW, Mutable, PrevDecl);
+  return new (Mem) FieldDecl(Decl::Field, DC, L, Id, T, BW, Mutable);
 }
 
 bool FieldDecl::isAnonymousStructOrUnion() const {
@@ -110,10 +108,9 @@
 EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
                                            SourceLocation L,
                                            IdentifierInfo *Id, QualType T,
-                                           Expr *E, const llvm::APSInt &V, 
-                                           ScopedDecl *PrevDecl){
+                                           Expr *E, const llvm::APSInt &V) {
   void *Mem = C.getAllocator().Allocate<EnumConstantDecl>();
-  return new (Mem) EnumConstantDecl(CD, L, Id, T, E, V, PrevDecl);
+  return new (Mem) EnumConstantDecl(CD, L, Id, T, E, V);
 }
 
 void EnumConstantDecl::Destroy(ASTContext& C) {
@@ -123,17 +120,16 @@
 
 TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
                                  SourceLocation L,
-                                 IdentifierInfo *Id, QualType T,
-                                 ScopedDecl *PD) {
+                                 IdentifierInfo *Id, QualType T) {
   void *Mem = C.getAllocator().Allocate<TypedefDecl>();
-  return new (Mem) TypedefDecl(DC, L, Id, T, PD);
+  return new (Mem) TypedefDecl(DC, L, Id, T);
 }
 
 EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
                            IdentifierInfo *Id,
                            EnumDecl *PrevDecl) {
   void *Mem = C.getAllocator().Allocate<EnumDecl>();
-  EnumDecl *Enum = new (Mem) EnumDecl(DC, L, Id, 0);
+  EnumDecl *Enum = new (Mem) EnumDecl(DC, L, Id);
   C.getTypeDeclType(Enum, PrevDecl);
   return Enum;
 }
@@ -148,44 +144,18 @@
   TagDecl::completeDefinition();
 }
 
-FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C,
+FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
                                            SourceLocation L,
                                            StringLiteral *Str) {
   void *Mem = C.getAllocator().Allocate<FileScopeAsmDecl>();
-  return new (Mem) FileScopeAsmDecl(L, Str);
+  return new (Mem) FileScopeAsmDecl(DC, L, Str);
 }
 
 //===----------------------------------------------------------------------===//
-// ScopedDecl Implementation
+// NamedDecl Implementation
 //===----------------------------------------------------------------------===//
 
-void ScopedDecl::setDeclContext(DeclContext *DC) {
-  if (isOutOfSemaDC())
-    delete getMultipleDC();
-  
-  DeclCtx = reinterpret_cast<uintptr_t>(DC);
-}
-
-void ScopedDecl::setLexicalDeclContext(DeclContext *DC) {
-  if (DC == getLexicalDeclContext())
-    return;
-
-  if (isInSemaDC()) {
-    MultipleDC *MDC = new MultipleDC();
-    MDC->SemanticDC = getDeclContext();
-    MDC->LexicalDC = DC;
-    DeclCtx = reinterpret_cast<uintptr_t>(MDC) | 0x1;
-  } else {
-    getMultipleDC()->LexicalDC = DC;
-  }
-}
-
-ScopedDecl::~ScopedDecl() {
-  if (isOutOfSemaDC())
-    delete getMultipleDC();
-}
-
-bool ScopedDecl::declarationReplaces(NamedDecl *OldD) const {
+bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
   assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch");
 
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
@@ -198,17 +168,16 @@
   return this->getKind() == OldD->getKind();
 }
 
+
 //===----------------------------------------------------------------------===//
 // VarDecl Implementation
 //===----------------------------------------------------------------------===//
 
-VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC,
-                         SourceLocation L,
-                         IdentifierInfo *Id, QualType T,
-                         StorageClass S, ScopedDecl *PrevDecl,
+VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+                         IdentifierInfo *Id, QualType T, StorageClass S, 
                          SourceLocation TypeSpecStartLoc) {
   void *Mem = C.getAllocator().Allocate<VarDecl>();
-  return new (Mem) VarDecl(Var, DC, L, Id, T, S, PrevDecl, TypeSpecStartLoc);
+  return new (Mem) VarDecl(Var, DC, L, Id, T, S, TypeSpecStartLoc);
 }
 
 void VarDecl::Destroy(ASTContext& C) {
@@ -330,7 +299,7 @@
 
 RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
                        IdentifierInfo *Id)
-  : TagDecl(DK, TK, DC, L, Id, 0) {
+  : TagDecl(DK, TK, DC, L, Id) {
   HasFlexibleArrayMember = false;
   AnonymousStructOrUnion = false;
   assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 2865687..70792c4 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -262,8 +262,32 @@
 // Decl Implementation
 //===----------------------------------------------------------------------===//
 
+void Decl::setDeclContext(DeclContext *DC) {
+  if (isOutOfSemaDC())
+    delete getMultipleDC();
+  
+  DeclCtx = reinterpret_cast<uintptr_t>(DC);
+}
+
+void Decl::setLexicalDeclContext(DeclContext *DC) {
+  if (DC == getLexicalDeclContext())
+    return;
+
+  if (isInSemaDC()) {
+    MultipleDC *MDC = new MultipleDC();
+    MDC->SemanticDC = getDeclContext();
+    MDC->LexicalDC = DC;
+    DeclCtx = reinterpret_cast<uintptr_t>(MDC) | 0x1;
+  } else {
+    getMultipleDC()->LexicalDC = DC;
+  }
+}
+
 // Out-of-line virtual method providing a home for Decl.
 Decl::~Decl() {
+  if (isOutOfSemaDC())
+    delete getMultipleDC();
+
   if (!HasAttrs)
     return;
   
@@ -336,20 +360,18 @@
 #if 0
   // FIXME: This causes double-destroys in some cases, so it is
   // disabled at the moment.
-  if (ScopedDecl* SD = dyn_cast<ScopedDecl>(this)) {    
 
-    // Observe the unrolled recursion.  By setting N->NextDeclarator = 0x0
-    // within the loop, only the Destroy method for the first ScopedDecl
-    // will deallocate all of the ScopedDecls in a chain.
-    
-    ScopedDecl* N = SD->getNextDeclarator();
-    
-    while (N) {
-      ScopedDecl* Tmp = N->getNextDeclarator();
-      N->NextDeclarator = 0x0;
-      N->Destroy(C);
-      N = Tmp;
-    }
+  // Observe the unrolled recursion.  By setting N->NextDeclarator = 0x0
+  // within the loop, only the Destroy method for the first Decl
+  // will deallocate all of the Decls in a chain.
+  
+  Decl* N = SD->getNextDeclarator();
+  
+  while (N) {
+    Decl* Tmp = N->getNextDeclarator();
+    N->NextDeclarator = 0x0;
+    N->Destroy(C);
+    N = Tmp;
   }  
 #endif
 
@@ -370,17 +392,16 @@
 //===----------------------------------------------------------------------===//
 
 const DeclContext *DeclContext::getParent() const {
-  if (const ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
-    return SD->getDeclContext();
-  else if (const BlockDecl *BD = dyn_cast<BlockDecl>(this))
-    return BD->getParentContext();
-  else
-    return NULL;
+  if (const Decl *D = dyn_cast<Decl>(this))
+    return D->getDeclContext();
+
+  return NULL;
 }
 
 const DeclContext *DeclContext::getLexicalParent() const {
-  if (const ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
-    return SD->getLexicalDeclContext();
+  if (const Decl *D = dyn_cast<Decl>(this))
+    return D->getLexicalDeclContext();
+
   return getParent();
 }
 
@@ -391,7 +412,7 @@
 // implemented in terms of DenseMap anyway. However, this data
 // structure is really space-inefficient, so we'll have to do
 // something.
-typedef llvm::DenseMap<DeclarationName, std::vector<ScopedDecl*> >
+typedef llvm::DenseMap<DeclarationName, std::vector<NamedDecl*> >
   StoredDeclsMap;
 
 DeclContext::~DeclContext() {
@@ -400,7 +421,7 @@
     StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
     delete Map;
   } else {
-    ScopedDecl **Array = static_cast<ScopedDecl**>(LookupPtr.getPointer());
+    NamedDecl **Array = static_cast<NamedDecl**>(LookupPtr.getPointer());
     delete [] Array;
   }
 }
@@ -500,7 +521,7 @@
   }
 }
 
-void DeclContext::addDecl(ScopedDecl *D) {
+void DeclContext::addDecl(Decl *D) {
   assert(D->getLexicalDeclContext() == this && "Decl inserted into wrong lexical context");
   assert(!D->NextDeclInScope && D != LastDecl && 
          "Decl already inserted into a DeclContext");
@@ -511,7 +532,9 @@
   } else {
     FirstDecl = LastDecl = D;
   }
-  D->getDeclContext()->insert(D);
+
+  if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
+    ND->getDeclContext()->insert(ND);
 }
 
 /// buildLookup - Build the lookup data structure with all of the
@@ -522,7 +545,8 @@
     for (decl_iterator D = DCtx->decls_begin(), DEnd = DCtx->decls_end(); 
          D != DEnd; ++D) {
       // Insert this declaration into the lookup structure
-      insertImpl(*D);
+      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
+        insertImpl(ND);
 
       // If this declaration is itself a transparent declaration context,
       // add its members (recursively).
@@ -556,7 +580,7 @@
 
   // We have a small array. Look into it.
   unsigned Size = LookupPtr.getInt();
-  ScopedDecl **Array = static_cast<ScopedDecl**>(LookupPtr.getPointer());
+  NamedDecl **Array = static_cast<NamedDecl**>(LookupPtr.getPointer());
   for (unsigned Idx = 0; Idx != Size; ++Idx)
     if (Array[Idx]->getDeclName() == Name) {
       unsigned Last = Idx + 1;
@@ -581,7 +605,7 @@
   return Ctx;
 }
 
-void DeclContext::insert(ScopedDecl *D) {
+void DeclContext::insert(NamedDecl *D) {
   DeclContext *PrimaryContext = getPrimaryContext();
   if (PrimaryContext != this) {
     PrimaryContext->insert(D);
@@ -600,7 +624,7 @@
     getParent()->insert(D);
 }
 
-void DeclContext::insertImpl(ScopedDecl *D) {
+void DeclContext::insertImpl(NamedDecl *D) {
   // Skip unnamed declarations.
   if (!D->getDeclName())
     return;
@@ -612,12 +636,12 @@
 
     // The lookup data is stored as an array. Search through the array
     // to find the insertion location.
-    ScopedDecl **Array;
+    NamedDecl **Array;
     if (Size == 0) {
-      Array = new ScopedDecl*[LookupIsMap - 1];
+      Array = new NamedDecl*[LookupIsMap - 1];
       LookupPtr.setPointer(Array);
     } else {
-      Array = static_cast<ScopedDecl **>(LookupPtr.getPointer());
+      Array = static_cast<NamedDecl **>(LookupPtr.getPointer());
     }
 
     // We always keep declarations of the same name next to each other
@@ -688,9 +712,9 @@
   if (Pos != Map->end()) {
     if (MayBeRedeclaration) {
       // Determine if this declaration is actually a redeclaration.
-      std::vector<ScopedDecl *>::iterator Redecl
+      std::vector<NamedDecl *>::iterator Redecl
         = std::find_if(Pos->second.begin(), Pos->second.end(),
-                     std::bind1st(std::mem_fun(&ScopedDecl::declarationReplaces),
+                     std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces),
                                   D));
       if (Redecl != Pos->second.end()) {
         *Redecl = D;
@@ -702,7 +726,7 @@
     if (D->getIdentifierNamespace() == Decl::IDNS_Tag || Pos->second.empty())
       Pos->second.push_back(D);
     else if (Pos->second.back()->getIdentifierNamespace() == Decl::IDNS_Tag) {
-      ScopedDecl *TagD = Pos->second.back();
+      NamedDecl *TagD = Pos->second.back();
       Pos->second.back() = D;
       Pos->second.push_back(TagD);
     } else
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index e3d7534..a9c129b 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -210,11 +210,9 @@
 CXXMethodDecl *
 CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
                       SourceLocation L, DeclarationName N,
-                      QualType T, bool isStatic, bool isInline,
-                      ScopedDecl *PrevDecl) {
+                      QualType T, bool isStatic, bool isInline) {
   void *Mem = C.getAllocator().Allocate<CXXMethodDecl>();
-  return new (Mem) CXXMethodDecl(CXXMethod, RD, L, N, T, isStatic, isInline, 
-                                 PrevDecl);
+  return new (Mem) CXXMethodDecl(CXXMethod, RD, L, N, T, isStatic, isInline);
 }
 
 QualType CXXMethodDecl::getThisType(ASTContext &C) const {
@@ -355,9 +353,9 @@
 
 CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD,
                                    SourceLocation L, IdentifierInfo *Id,
-                                   QualType T, ScopedDecl *PrevDecl) {
+                                   QualType T) {
   void *Mem = C.getAllocator().Allocate<CXXClassVarDecl>();
-  return new (Mem) CXXClassVarDecl(RD, L, Id, T, PrevDecl);
+  return new (Mem) CXXClassVarDecl(RD, L, Id, T);
 }
 
 OverloadedFunctionDecl *
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 90962e6..bbbcc5f 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -166,11 +166,10 @@
 ObjCImplementationDecl *
 ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, 
                                SourceLocation L,
-                               IdentifierInfo *Id,
                                ObjCInterfaceDecl *ClassInterface,
                                ObjCInterfaceDecl *SuperDecl) {
   void *Mem = C.getAllocator().Allocate<ObjCImplementationDecl>();
-  return new (Mem) ObjCImplementationDecl(DC, L, Id, ClassInterface, SuperDecl);
+  return new (Mem) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl);
 }
 
 ObjCCompatibleAliasDecl *
@@ -213,12 +212,12 @@
   SelfDecl = ImplicitParamDecl::Create(Context, this, 
                                        SourceLocation(), 
                                        &Context.Idents.get("self"),
-                                       selfTy, 0);
+                                       selfTy);
 
   CmdDecl = ImplicitParamDecl::Create(Context, this, 
                                       SourceLocation(), 
                                       &Context.Idents.get("_cmd"), 
-                                      Context.getObjCSelType(), 0);
+                                      Context.getObjCSelType());
 }
 
 void ObjCMethodDecl::setMethodParams(ParmVarDecl **NewParamInfo,
diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp
index 11577cd..b37e7b4 100644
--- a/lib/AST/DeclSerialization.cpp
+++ b/lib/AST/DeclSerialization.cpp
@@ -31,8 +31,25 @@
 void Decl::Emit(Serializer& S) const {
   S.EmitInt(getKind());
   EmitImpl(S);
+  S.Emit(getLocation());
+  S.EmitBool(InvalidDecl);
+  // FIXME: HasAttrs?
+  S.EmitBool(Implicit);
+  S.EmitInt(Access);
+  S.EmitPtr(cast_or_null<Decl>(getDeclContext()));  // From Decl.
+  S.EmitPtr(cast_or_null<Decl>(getLexicalDeclContext()));  // From Decl.
+  S.EmitPtr(NextDeclarator);
   if (const DeclContext *DC = dyn_cast<const DeclContext>(this))
     DC->EmitOutRec(S);
+  
+  if (getDeclContext() && 
+      !getDeclContext()->isFunctionOrMethod()) {
+    S.EmitBool(true);
+    S.EmitOwnedPtr(NextDeclInScope);
+  } else {
+    S.EmitBool(false);
+    S.EmitPtr(NextDeclInScope);
+  }
 }
 
 Decl* Decl::Create(Deserializer& D, ASTContext& C) {
@@ -101,59 +118,62 @@
       break;
   }
 
+  Dcl->Loc = SourceLocation::ReadVal(D);                 // From Decl.
+  Dcl->InvalidDecl = D.ReadBool();
+  // FIXME: HasAttrs?
+  Dcl->Implicit = D.ReadBool();
+  Dcl->Access = D.ReadInt();
+
+  assert(Dcl->DeclCtx == 0);
+
+  const SerializedPtrID &SemaDCPtrID = D.ReadPtrID();
+  const SerializedPtrID &LexicalDCPtrID = D.ReadPtrID();
+
+  if (SemaDCPtrID == LexicalDCPtrID) {
+    // Allow back-patching.  Observe that we register the variable of the
+    // *object* for back-patching. Its actual value will get filled in later.
+    D.ReadUIntPtr(Dcl->DeclCtx, SemaDCPtrID); 
+  }
+  else {
+    MultipleDC *MDC = new MultipleDC();
+    Dcl->DeclCtx = reinterpret_cast<uintptr_t>(MDC) | 0x1;
+    // Allow back-patching.  Observe that we register the variable of the
+    // *object* for back-patching. Its actual value will get filled in later.
+    D.ReadPtr(MDC->SemanticDC, SemaDCPtrID);
+    D.ReadPtr(MDC->LexicalDC, LexicalDCPtrID);
+  }
+  D.ReadPtr(Dcl->NextDeclarator);
   if (DeclContext *DC = dyn_cast<DeclContext>(Dcl))
     DC->ReadOutRec(D, C);
-
+  bool OwnsNext = D.ReadBool();
+  if (OwnsNext)
+    Dcl->NextDeclInScope = D.ReadOwnedPtr<Decl>(C);
+  else 
+    D.ReadPtr(Dcl->NextDeclInScope);
   return Dcl;
 }
 
 //===----------------------------------------------------------------------===//
-//      Common serialization logic for subclasses of Decl.
-//===----------------------------------------------------------------------===//
-
-void Decl::EmitInRec(Serializer& S) const {
-  S.Emit(getLocation());                    // From Decl.
-}
-
-void Decl::ReadInRec(Deserializer& D, ASTContext& C) {
-  Loc = SourceLocation::ReadVal(D);                 // From Decl.
-}
-
-//===----------------------------------------------------------------------===//
 //      Common serialization logic for subclasses of DeclContext.
 //===----------------------------------------------------------------------===//
 
 void DeclContext::EmitOutRec(Serializer& S) const {
-#if 0
-  // FIXME: it would be far easier to just serialize FirstDecl and let
-  // ScopedDecl do the work of serializing NextDeclInScope.
-  S.EmitInt(Decls.size());
-  for (decl_iterator D = decls_begin(); D != decls_end(); ++D) {
-    bool Owned = ((*D)->getLexicalDeclContext() == this &&
-                  DeclKind != Decl::TranslationUnit &&
-                  !isFunctionOrMethod());
-    S.EmitBool(Owned);
-    if (Owned)
-      S.EmitOwnedPtr(*D);
-    else
-      S.EmitPtr(*D);
-  }
-#endif
+  bool Owned = !isFunctionOrMethod();
+  S.EmitBool(Owned);
+  if (Owned)
+    S.EmitOwnedPtr(FirstDecl);
+  else
+    S.EmitPtr(FirstDecl);
+  S.EmitPtr(LastDecl);
 }
 
 void DeclContext::ReadOutRec(Deserializer& D, ASTContext& C) {
-#if 0
-  // FIXME: See comment in DeclContext::EmitOutRec
-  unsigned NumDecls = D.ReadInt();
-  Decls.resize(NumDecls);
-  for (unsigned Idx = 0; Idx < NumDecls; ++Idx) {
-    bool Owned = D.ReadBool();
-    if (Owned)
-      Decls[Idx] = cast_or_null<ScopedDecl>(D.ReadOwnedPtr<Decl>(C));
-    else
-      D.ReadPtr<ScopedDecl>(Decls[Idx]);
-  }
-#endif
+  bool Owned = D.ReadBool();
+  if (Owned)
+    FirstDecl = cast_or_null<Decl>(D.ReadOwnedPtr<Decl>(C));
+  else
+    D.ReadPtr(FirstDecl);
+  D.ReadPtr(LastDecl);
 }
 
 //===----------------------------------------------------------------------===//
@@ -161,7 +181,6 @@
 //===----------------------------------------------------------------------===//
 
 void NamedDecl::EmitInRec(Serializer& S) const {
-  Decl::EmitInRec(S);
   S.EmitInt(Name.getNameKind());
 
   switch (Name.getNameKind()) {
@@ -188,8 +207,6 @@
 }
 
 void NamedDecl::ReadInRec(Deserializer& D, ASTContext& C) {
-  Decl::ReadInRec(D, C);
-
   DeclarationName::NameKind Kind 
     = static_cast<DeclarationName::NameKind>(D.ReadInt());
   switch (Kind) {
@@ -229,64 +246,16 @@
 }
 
 //===----------------------------------------------------------------------===//
-//      Common serialization logic for subclasses of ScopedDecl.
-//===----------------------------------------------------------------------===//
-
-void ScopedDecl::EmitInRec(Serializer& S) const {
-  NamedDecl::EmitInRec(S);
-  S.EmitPtr(cast_or_null<Decl>(getDeclContext()));  // From ScopedDecl.
-  S.EmitPtr(cast_or_null<Decl>(getLexicalDeclContext()));  // From ScopedDecl.
-}
-
-void ScopedDecl::ReadInRec(Deserializer& D, ASTContext& C) {
-  NamedDecl::ReadInRec(D, C);
-
-  assert(DeclCtx == 0);
-
-  const SerializedPtrID &SemaDCPtrID = D.ReadPtrID();
-  const SerializedPtrID &LexicalDCPtrID = D.ReadPtrID();
-
-  if (SemaDCPtrID == LexicalDCPtrID) {
-    // Allow back-patching.  Observe that we register the variable of the
-    // *object* for back-patching. Its actual value will get filled in later.
-    D.ReadUIntPtr(DeclCtx, SemaDCPtrID); 
-  }
-  else {
-    MultipleDC *MDC = new MultipleDC();
-    DeclCtx = reinterpret_cast<uintptr_t>(MDC) | 0x1;
-    // Allow back-patching.  Observe that we register the variable of the
-    // *object* for back-patching. Its actual value will get filled in later.
-    D.ReadPtr(MDC->SemanticDC, SemaDCPtrID);
-    D.ReadPtr(MDC->LexicalDC, LexicalDCPtrID);
-  }
-}
-    
-  //===------------------------------------------------------------===//
-  // NOTE: Not all subclasses of ScopedDecl will use the "OutRec"     //
-  //   methods.  This is because owned pointers are usually "batched" //
-  //   together for efficiency.                                       //
-  //===------------------------------------------------------------===//
-
-void ScopedDecl::EmitOutRec(Serializer& S) const {
-  S.EmitOwnedPtr(getNextDeclarator());   // From ScopedDecl.
-}
-
-void ScopedDecl::ReadOutRec(Deserializer& D, ASTContext& C) {
-  NextDeclarator = 
-    cast_or_null<ScopedDecl>(D.ReadOwnedPtr<Decl>(C)); // From ScopedDecl.
-}
-
-//===----------------------------------------------------------------------===//
 //      Common serialization logic for subclasses of ValueDecl.
 //===----------------------------------------------------------------------===//
 
 void ValueDecl::EmitInRec(Serializer& S) const {
-  ScopedDecl::EmitInRec(S);
+  NamedDecl::EmitInRec(S);
   S.Emit(getType());                        // From ValueDecl.
 }
 
 void ValueDecl::ReadInRec(Deserializer& D, ASTContext& C) {
-  ScopedDecl::ReadInRec(D, C);
+  NamedDecl::ReadInRec(D, C);
   DeclType = QualType::ReadVal(D);          // From ValueDecl.
 }
 
@@ -304,26 +273,13 @@
   SClass = static_cast<StorageClass>(D.ReadInt());  // From VarDecl. 
 }
 
-    //===------------------------------------------------------------===//
-    // NOTE: VarDecl has its own "OutRec" methods that doesn't use      //
-    //  the one define in ScopedDecl.  This is to batch emit the        //
-    //  owned pointers, which results in a smaller output.
-    //===------------------------------------------------------------===//
-
 void VarDecl::EmitOutRec(Serializer& S) const {
-  // Emit these last because they will create records of their own.
-  S.BatchEmitOwnedPtrs(getInit(),            // From VarDecl.
-                       getNextDeclarator()); // From ScopedDecl.  
+  // Emit this last because it will create a record of its own.
+  S.EmitOwnedPtr(getInit());
 }
 
 void VarDecl::ReadOutRec(Deserializer& D, ASTContext& C) {
-  Decl* next_declarator;
-  
-  D.BatchReadOwnedPtrs(Init,             // From VarDecl.
-                       next_declarator,  // From ScopedDecl.
-                       C);
-  
-  setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
+  Init = D.ReadOwnedPtr<Stmt>(C);
 }
 
 
@@ -343,7 +299,6 @@
 
 void TranslationUnitDecl::EmitImpl(llvm::Serializer& S) const
 {
-  Decl::EmitInRec(S);
 }
 
 TranslationUnitDecl* TranslationUnitDecl::CreateImpl(Deserializer& D,
@@ -351,8 +306,6 @@
   void *Mem = C.getAllocator().Allocate<TranslationUnitDecl>();
   TranslationUnitDecl* decl = new (Mem) TranslationUnitDecl();
  
-  decl->Decl::ReadInRec(D, C);
-  
   return decl;
 }
 
@@ -362,20 +315,18 @@
 
 void NamespaceDecl::EmitImpl(llvm::Serializer& S) const
 {
-  ScopedDecl::EmitInRec(S);
+  NamedDecl::EmitInRec(S);
   S.Emit(getLBracLoc());
   S.Emit(getRBracLoc());
-  ScopedDecl::EmitOutRec(S);
 }
 
 NamespaceDecl* NamespaceDecl::CreateImpl(Deserializer& D, ASTContext& C) {  
   void *Mem = C.getAllocator().Allocate<NamespaceDecl>();
   NamespaceDecl* decl = new (Mem) NamespaceDecl(0, SourceLocation(), 0);
  
-  decl->ScopedDecl::ReadInRec(D, C);
+  decl->NamedDecl::ReadInRec(D, C);
   decl->LBracLoc = SourceLocation::ReadVal(D);
   decl->RBracLoc = SourceLocation::ReadVal(D);
-  decl->ScopedDecl::ReadOutRec(D, C);
   
   return decl;
 }
@@ -387,7 +338,7 @@
 VarDecl* VarDecl::CreateImpl(Deserializer& D, ASTContext& C) {  
   void *Mem = C.getAllocator().Allocate<VarDecl>();
   VarDecl* decl =
-    new (Mem) VarDecl(Var, 0, SourceLocation(), NULL, QualType(), None, NULL);
+    new (Mem) VarDecl(Var, 0, SourceLocation(), NULL, QualType(), None);
  
   decl->VarDecl::ReadImpl(D, C);
   return decl;
@@ -407,7 +358,7 @@
   void *Mem = C.getAllocator().Allocate<ParmVarDecl>();
   ParmVarDecl* decl = new (Mem)
     ParmVarDecl(ParmVar,
-                0, SourceLocation(), NULL, QualType(), None, NULL, NULL);
+                0, SourceLocation(), NULL, QualType(), None, NULL);
   
   decl->VarDecl::ReadImpl(D, C);
   decl->objcDeclQualifier = static_cast<ObjCDeclQualifier>(D.ReadInt());
@@ -429,7 +380,7 @@
   void *Mem = C.getAllocator().Allocate<ParmVarWithOriginalTypeDecl>();
   ParmVarWithOriginalTypeDecl* decl = new (Mem)
     ParmVarWithOriginalTypeDecl(0, SourceLocation(), NULL, QualType(), 
-                                QualType(), None, NULL, NULL);
+                                QualType(), None, NULL);
   
   decl->ParmVarDecl::ReadImpl(D, C);
   decl->OriginalType = QualType::ReadVal(D);
@@ -440,23 +391,19 @@
 //===----------------------------------------------------------------------===//
 
 void EnumDecl::EmitImpl(Serializer& S) const {
-  ScopedDecl::EmitInRec(S);
+  NamedDecl::EmitInRec(S);
   S.EmitBool(isDefinition());
   S.Emit(IntegerType);
-  S.EmitOwnedPtr(getNextDeclarator());
 }
 
 EnumDecl* EnumDecl::CreateImpl(Deserializer& D, ASTContext& C) {
   void *Mem = C.getAllocator().Allocate<EnumDecl>();
-  EnumDecl* decl = new (Mem) EnumDecl(0, SourceLocation(), NULL, NULL);
+  EnumDecl* decl = new (Mem) EnumDecl(0, SourceLocation(), NULL);
   
-  decl->ScopedDecl::ReadInRec(D, C);
+  decl->NamedDecl::ReadInRec(D, C);
   decl->setDefinition(D.ReadBool());
   decl->IntegerType = QualType::ReadVal(D);
   
-  Decl* next_declarator = D.ReadOwnedPtr<Decl>(C);
-  decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
-  
   return decl;
 }
 
@@ -467,7 +414,7 @@
 void EnumConstantDecl::EmitImpl(Serializer& S) const {
   S.Emit(Val);
   ValueDecl::EmitInRec(S);
-  S.BatchEmitOwnedPtrs(getNextDeclarator(),Init);
+  S.EmitOwnedPtr(Init);
 }
  
 EnumConstantDecl* EnumConstantDecl::CreateImpl(Deserializer& D, ASTContext& C) {
@@ -476,16 +423,10 @@
   
   void *Mem = C.getAllocator().Allocate<EnumConstantDecl>();
   EnumConstantDecl* decl = new (Mem)
-    EnumConstantDecl(0, SourceLocation(), NULL, QualType(), NULL, val, NULL);
+    EnumConstantDecl(0, SourceLocation(), NULL, QualType(), NULL, val);
   
   decl->ValueDecl::ReadInRec(D, C);
-  
-  Decl* next_declarator;
-  
-  D.BatchReadOwnedPtrs(next_declarator, decl->Init, C);
-  
-  decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
-
+  decl->Init = D.ReadOwnedPtr<Stmt>(C);
   return decl;    
 }
 
@@ -496,14 +437,14 @@
 void FieldDecl::EmitImpl(Serializer& S) const {
   S.EmitBool(Mutable);
   S.Emit(getType());
-  ScopedDecl::EmitInRec(S);
+  NamedDecl::EmitInRec(S);
   S.EmitOwnedPtr(BitWidth);  
 }
 
 FieldDecl* FieldDecl::CreateImpl(Deserializer& D, ASTContext& C) {
   void *Mem = C.getAllocator().Allocate<FieldDecl>();
   FieldDecl* decl = new (Mem) FieldDecl(Field, 0, SourceLocation(), NULL, 
-                                        QualType(), 0, false, 0);
+                                        QualType(), 0, false);
   decl->Mutable = D.ReadBool();
   decl->DeclType.ReadBackpatch(D);  
   decl->ReadInRec(D, C);
@@ -527,12 +468,11 @@
   if (ParamInfo != NULL) {
     S.EmitBool(true);
     S.EmitInt(getNumParams());
-    S.BatchEmitOwnedPtrs(getNumParams(),&ParamInfo[0], Body,
-                         getNextDeclarator());
+    S.BatchEmitOwnedPtrs(getNumParams(),&ParamInfo[0], Body);
   }
   else {
     S.EmitBool(false);
-    S.BatchEmitOwnedPtrs(Body,getNextDeclarator());  
+    S.EmitOwnedPtr(Body);
   }
 }
 
@@ -543,13 +483,11 @@
   void *Mem = C.getAllocator().Allocate<FunctionDecl>();
   FunctionDecl* decl = new (Mem)
     FunctionDecl(Function, 0, SourceLocation(), DeclarationName(),
-                 QualType(), SClass, IsInline, 0);
+                 QualType(), SClass, IsInline);
   
   decl->ValueDecl::ReadInRec(D, C);
   D.ReadPtr(decl->PreviousDeclaration);
 
-  Decl* next_declarator;
-  
   int numParams = 0;
   bool hasParamDecls = D.ReadBool();
   if (hasParamDecls)
@@ -562,11 +500,9 @@
   if (hasParamDecls)
     D.BatchReadOwnedPtrs(numParams,
                          reinterpret_cast<Decl**>(&decl->ParamInfo[0]),
-                         decl->Body, next_declarator, C);
+                         decl->Body, C);
   else
-    D.BatchReadOwnedPtrs(decl->Body, next_declarator, C);
-  
-  decl->setNextDeclarator(cast_or_null<ScopedDecl>(next_declarator));
+    decl->Body = D.ReadOwnedPtr<Stmt>(C);
   
   return decl;
 }
@@ -622,11 +558,10 @@
 void RecordDecl::EmitImpl(Serializer& S) const {
   S.EmitInt(getTagKind());
 
-  ScopedDecl::EmitInRec(S);
+  NamedDecl::EmitInRec(S);
   S.EmitBool(isDefinition());
   S.EmitBool(hasFlexibleArrayMember());
   S.EmitBool(isAnonymousStructOrUnion());
-  ScopedDecl::EmitOutRec(S);
 }
 
 RecordDecl* RecordDecl::CreateImpl(Deserializer& D, ASTContext& C) {
@@ -635,11 +570,10 @@
   void *Mem = C.getAllocator().Allocate<RecordDecl>();
   RecordDecl* decl = new (Mem) RecordDecl(Record, TK, 0, SourceLocation(), NULL);
     
-  decl->ScopedDecl::ReadInRec(D, C);
+  decl->NamedDecl::ReadInRec(D, C);
   decl->setDefinition(D.ReadBool());
   decl->setHasFlexibleArrayMember(D.ReadBool());
   decl->setAnonymousStructOrUnion(D.ReadBool());
-  decl->ScopedDecl::ReadOutRec(D, C);
     
   return decl;
 }
@@ -650,18 +584,16 @@
 
 void TypedefDecl::EmitImpl(Serializer& S) const {
   S.Emit(UnderlyingType);
-  ScopedDecl::EmitInRec(S);
-  ScopedDecl::EmitOutRec(S);
+  NamedDecl::EmitInRec(S);
 }
 
 TypedefDecl* TypedefDecl::CreateImpl(Deserializer& D, ASTContext& C) {
   QualType T = QualType::ReadVal(D);
   
   void *Mem = C.getAllocator().Allocate<TypedefDecl>();
-  TypedefDecl* decl = new (Mem) TypedefDecl(0, SourceLocation(), NULL, T, NULL);
+  TypedefDecl* decl = new (Mem) TypedefDecl(0, SourceLocation(), NULL, T);
   
-  decl->ScopedDecl::ReadInRec(D, C);
-  decl->ScopedDecl::ReadOutRec(D, C);
+  decl->NamedDecl::ReadInRec(D, C);
 
   return decl;
 }
@@ -672,8 +604,7 @@
 
 void TemplateTypeParmDecl::EmitImpl(Serializer& S) const {
   S.EmitBool(Typename);
-  ScopedDecl::EmitInRec(S);
-  ScopedDecl::EmitOutRec(S);
+  NamedDecl::EmitInRec(S);
 }
 
 TemplateTypeParmDecl *
@@ -682,8 +613,7 @@
   void *Mem = C.getAllocator().Allocate<TemplateTypeParmDecl>();
   TemplateTypeParmDecl *decl
     = new (Mem) TemplateTypeParmDecl(0, SourceLocation(), NULL, Typename);
-  decl->ScopedDecl::ReadInRec(D, C);
-  decl->ScopedDecl::ReadOutRec(D, C);
+  decl->NamedDecl::ReadInRec(D, C);
   return decl;
 }
 
@@ -692,13 +622,11 @@
 //===----------------------------------------------------------------------===//
 
 void LinkageSpecDecl::EmitInRec(Serializer& S) const {
-  Decl::EmitInRec(S);
   S.EmitInt(getLanguage());
   S.EmitBool(HadBraces);
 }
 
 void LinkageSpecDecl::ReadInRec(Deserializer& D, ASTContext& C) {
-  Decl::ReadInRec(D, C);
   Language = static_cast<LanguageIDs>(D.ReadInt());
   HadBraces = D.ReadBool();
 }
@@ -709,15 +637,13 @@
 
 void FileScopeAsmDecl::EmitImpl(llvm::Serializer& S) const
 {
-  Decl::EmitInRec(S);
   S.EmitOwnedPtr(AsmString);
 }
 
 FileScopeAsmDecl* FileScopeAsmDecl::CreateImpl(Deserializer& D, ASTContext& C) { 
   void *Mem = C.getAllocator().Allocate<FileScopeAsmDecl>();
-  FileScopeAsmDecl* decl = new (Mem) FileScopeAsmDecl(SourceLocation(), 0);
+  FileScopeAsmDecl* decl = new (Mem) FileScopeAsmDecl(0, SourceLocation(), 0);
 
-  decl->Decl::ReadInRec(D, C);
   decl->AsmString = cast<StringLiteral>(D.ReadOwnedPtr<Expr>(C));
 //  D.ReadOwnedPtr(D.ReadOwnedPtr<StringLiteral>())<#T * * Ptr#>, <#bool AutoRegister#>)(decl->AsmString);
   
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index 1ee3efa..0a7de35 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -252,7 +252,7 @@
   fprintf(F,"\n");
   for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end();
        DI != DE; ++DI) {
-    ScopedDecl* D = *DI;
+    Decl* D = *DI;
     ++IndentLevel;
     Indent();
     fprintf(F, "%p ", (void*) D);
diff --git a/lib/AST/StmtIterator.cpp b/lib/AST/StmtIterator.cpp
index 4800345..5e42e31 100644
--- a/lib/AST/StmtIterator.cpp
+++ b/lib/AST/StmtIterator.cpp
@@ -114,7 +114,7 @@
   return false;  
 }
 
-StmtIteratorBase::StmtIteratorBase(ScopedDecl* d)
+StmtIteratorBase::StmtIteratorBase(Decl* d)
   : decl(d), RawVAPtr(DeclMode) {
   assert (decl);
   NextDecl(false);
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 96f5403..a3a16ae 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -522,11 +522,7 @@
   NamedDecl *D = Node->getDecl();
 
   // Build up a stack of contexts.
-  DeclContext *Ctx = 0;
-  if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D))
-    Ctx = SD->getDeclContext();
-  else if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D))
-    Ctx = Ovl->getDeclContext();
+  DeclContext *Ctx = D->getDeclContext();
   for (; Ctx; Ctx = Ctx->getParent())
     if (!Ctx->isTransparentContext())
       Contexts.push_back(Ctx);
@@ -535,8 +531,8 @@
     DeclContext *Ctx = Contexts.back();
     if (isa<TranslationUnitDecl>(Ctx))
       OS << "::";
-    else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(Ctx))
-      OS << SD->getNameAsString() << "::";
+    else if (NamedDecl *ND = dyn_cast<NamedDecl>(Ctx))
+      OS << ND->getNameAsString() << "::";
     Contexts.pop_back();
   }
 
diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp
index 39330ce..8599a7a 100644
--- a/lib/AST/StmtSerialization.cpp
+++ b/lib/AST/StmtSerialization.cpp
@@ -547,45 +547,15 @@
 void DeclRefExpr::EmitImpl(Serializer& S) const {
   S.Emit(Loc);
   S.Emit(getType());
-  
-  // Some DeclRefExprs can actually hold the owning reference to a FunctionDecl.
-  // This occurs when an implicitly defined function is called, and
-  // the decl does not appear in the source file.  We thus check if the
-  // decl pointer has been registered, and if not, emit an owned pointer.
-
-  // FIXME: While this will work for serialization, it won't work for
-  //  memory management.  The only reason this works for serialization is
-  //  because we are tracking all serialized pointers.  Either DeclRefExpr
-  //  needs an explicit bit indicating that it owns the the object,
-  //  or we need a different ownership model.
-  
-  const Decl* d = getDecl();
-  
-  if (!S.isRegistered(d)) {
-    assert (isa<FunctionDecl>(d) 
-     && "DeclRefExpr can only own FunctionDecls for implicitly def. funcs.");
-
-    S.EmitBool(true);
-    S.EmitOwnedPtr(d);
-  }
-  else {
-    S.EmitBool(false);
-    S.EmitPtr(d);
-  }
+  S.EmitPtr(getDecl());
 }
 
 DeclRefExpr* DeclRefExpr::CreateImpl(Deserializer& D, ASTContext& C) {
   SourceLocation Loc = SourceLocation::ReadVal(D);
   QualType T = QualType::ReadVal(D);  
-  bool OwnsDecl = D.ReadBool();
-  NamedDecl* decl;
-  
-  if (!OwnsDecl)
-    D.ReadPtr(decl,false); // No backpatching.
-  else
-    decl = cast<NamedDecl>(D.ReadOwnedPtr<Decl>(C));
-  
-  return new DeclRefExpr(decl,T,Loc);
+  DeclRefExpr *DRE = new DeclRefExpr(0, T, Loc);
+  D.ReadPtr(DRE->D);
+  return DRE;
 }
 
 void DefaultStmt::EmitImpl(Serializer& S) const {
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 8656ef4..80215f3 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -1813,7 +1813,7 @@
 void GRExprEngine::VisitDeclStmt(DeclStmt* DS, NodeTy* Pred, NodeSet& Dst) {  
 
   // The CFG has one DeclStmt per Decl.  
-  ScopedDecl* D = *DS->decl_begin();
+  Decl* D = *DS->decl_begin();
   
   if (!D || !isa<VarDecl>(D))
     return;
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 1dcf1be..eafb858 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -349,7 +349,7 @@
   if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
     EmitStmt(SD);
     assert(HaveInsertPoint() && "DeclStmt destroyed insert point!");
-    const ScopedDecl* D = SD->getSolitaryDecl();
+    const Decl* D = SD->getSolitaryDecl();
     ElementTy = cast<ValueDecl>(D)->getType();
     DeclAddress = LocalDeclMap[D];    
   } else {
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 447b3d0..cd5ae64 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -2397,9 +2397,9 @@
                                       SourceLocation(),
                                       &Ctx.Idents.get("_objc_super"));  
   RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0, 
-                                Ctx.getObjCIdType(), 0, false, 0));
+                                Ctx.getObjCIdType(), 0, false));
   RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
-                                Ctx.getObjCClassType(), 0, false, 0));
+                                Ctx.getObjCClassType(), 0, false));
   RD->completeDefinition(Ctx);
 
   SuperCTy = Ctx.getTagDeclType(RD);
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index be6e171..9afdc03 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -67,8 +67,8 @@
     }
     
     virtual void HandleTopLevelDecl(Decl *D) {
-      // Make sure to emit all elements of a ScopedDecl.
-      if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
+      // Make sure to emit all elements of a Decl.
+      if (Decl *SD = dyn_cast<Decl>(D)) {
         for (; SD; SD = SD->getNextDeclarator())
           Builder->EmitTopLevelDecl(SD);
       } else {
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index 762885e..4e9d085 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -46,19 +46,10 @@
 // LookupContext Implementation
 //===----------------------------------------------------------------------===//
 
-/// getContext - Returns translation unit context for non ScopedDecls and
+/// getContext - Returns translation unit context for non Decls and
 /// for EnumConstantDecls returns the parent context of their EnumDecl.
 DeclContext *IdentifierResolver::LookupContext::getContext(Decl *D) {
-  DeclContext *Ctx;
-
-  if (EnumConstantDecl *EnumD = dyn_cast<EnumConstantDecl>(D)) {
-    Ctx = EnumD->getDeclContext()->getParent();
-  } else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D))
-    Ctx = SD->getDeclContext(); 
-  else if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D))
-    Ctx = Ovl->getDeclContext();
-  else
-    return TUCtx();
+  DeclContext *Ctx = D->getDeclContext();
 
   if (!Ctx) // FIXME: HACK! We shouldn't end up with a NULL context here.
     return TUCtx();
diff --git a/lib/Sema/IdentifierResolver.h b/lib/Sema/IdentifierResolver.h
index c29fffb..a44323e 100644
--- a/lib/Sema/IdentifierResolver.h
+++ b/lib/Sema/IdentifierResolver.h
@@ -29,8 +29,8 @@
 class IdentifierResolver {
 
   /// LookupContext - A wrapper for DeclContext. DeclContext is only part of
-  /// ScopedDecls, LookupContext can be used with all decls (assumes
-  /// translation unit context for non ScopedDecls).
+  /// Decls, LookupContext can be used with all decls (assumes
+  /// translation unit context for non Decls).
   class LookupContext {
     const DeclContext *Ctx;
 
@@ -42,7 +42,7 @@
       return reinterpret_cast<DeclContext*>(-1);
     }
 
-    /// getContext - Returns translation unit context for non ScopedDecls and
+    /// getContext - Returns translation unit context for non Decls and
     /// for EnumConstantDecls returns the parent context of their EnumDecl.
     static DeclContext *getContext(Decl *D);
 
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index ea42dbf..423b049 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -79,7 +79,7 @@
   TypedefDecl *SelTypedef = TypedefDecl::Create(Context, CurContext,
                                                 SourceLocation(),
                                                 &Context.Idents.get("SEL"),
-                                                SelT, 0);
+                                                SelT);
   PushOnScopeChains(SelTypedef, TUScope);
   Context.setObjCSelType(SelTypedef);
 
@@ -88,7 +88,7 @@
   QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
   TypedefDecl *ClassTypedef = 
     TypedefDecl::Create(Context, CurContext, SourceLocation(),
-                        &Context.Idents.get("Class"), ClassT, 0);
+                        &Context.Idents.get("Class"), ClassT);
   PushOnScopeChains(ClassTag, TUScope);
   PushOnScopeChains(ClassTypedef, TUScope);
   Context.setObjCClassType(ClassTypedef);
@@ -108,7 +108,7 @@
   TypedefDecl *IdTypedef = TypedefDecl::Create(Context, CurContext,
                                                SourceLocation(),
                                                &Context.Idents.get("id"),
-                                               ObjT, 0);
+                                               ObjT);
   PushOnScopeChains(IdTypedef, TUScope);
   Context.setObjCIdType(IdTypedef);
 }
@@ -223,7 +223,7 @@
   while (isa<BlockDecl>(DC))
     DC = DC->getParent();
   if (isa<ObjCMethodDecl>(DC) || isa<FunctionDecl>(DC))
-    return cast<ScopedDecl>(DC);
+    return cast<NamedDecl>(DC);
   return 0;
 }
 
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 053a323..8016854 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -40,7 +40,6 @@
   class DeclContext;
   class DeclSpec;
   class NamedDecl;
-  class ScopedDecl;
   class Stmt;
   class Expr;
   class InitListExpr;
@@ -285,16 +284,16 @@
   }
   DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup,
                           bool IsFunctionDefinition);
-  ScopedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                                     QualType R, ScopedDecl* LastDeclarator,
-                                     Decl* PrevDecl, bool& InvalidDecl);
-  ScopedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                                      QualType R, ScopedDecl* LastDeclarator,
+  NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
+                                    QualType R, Decl* LastDeclarator,
+                                    Decl* PrevDecl, bool& InvalidDecl);
+  NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
+                                      QualType R, Decl* LastDeclarator,
                                       Decl* PrevDecl, bool& InvalidDecl);
-  ScopedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                                      QualType R, ScopedDecl *LastDeclarator,
-                                      Decl* PrevDecl, bool IsFunctionDefinition,
-                                      bool& InvalidDecl);
+  NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
+                                     QualType R, Decl *LastDeclarator,
+                                     Decl* PrevDecl, bool IsFunctionDefinition,
+                                     bool& InvalidDecl);
   virtual DeclTy *ActOnParamDeclarator(Scope *S, Declarator &D);
   virtual void ActOnParamDefaultArgument(DeclTy *param, 
                                          SourceLocation EqualLoc,
@@ -399,7 +398,7 @@
 
   /// Subroutines of ActOnDeclarator().
   TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
-                                ScopedDecl *LastDecl);
+                                Decl *LastDecl);
   TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
   FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old, 
                                   bool &Redeclaration);
@@ -786,10 +785,10 @@
   //@}
   
   ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
-  ScopedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, 
-                                  Scope *S);
-  ScopedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
+  NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, 
                                  Scope *S);
+  NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
+                                      Scope *S);
 
   // More parsing and symbol table subroutines.
 
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index fe60496..ec769a1 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -88,8 +88,8 @@
   if (isa<ObjCMethodDecl>(DC))
     return Context.getTranslationUnitDecl();
 
-  if (ScopedDecl *SD = dyn_cast<ScopedDecl>(DC))
-    return SD->getLexicalDeclContext();
+  if (Decl *D = dyn_cast<Decl>(DC))
+    return D->getLexicalDeclContext();
 
   return DC->getLexicalParent();
 }
@@ -121,8 +121,7 @@
   // Add scoped declarations into their context, so that they can be
   // found later. Declarations without a context won't be inserted
   // into any context.
-  if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D))
-    CurContext->addDecl(SD);
+  CurContext->addDecl(D);
 
   // C++ [basic.scope]p4:
   //   -- exactly one declaration shall declare a class name or
@@ -178,7 +177,7 @@
       = std::find_if(IdResolver.begin(FD->getDeclName(), DC, 
                                       false/*LookInParentCtx*/),
                      IdResolver.end(),
-                     std::bind1st(std::mem_fun(&ScopedDecl::declarationReplaces),
+                     std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces),
                                   FD));
     if (Redecl != IdResolver.end()) {
       // There is already a declaration of a function on our
@@ -303,8 +302,8 @@
 
 /// LazilyCreateBuiltin - The specified Builtin-ID was first used at file scope.
 /// lazily create a decl for it.
-ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
-                                      Scope *S) {
+NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
+                                     Scope *S) {
   Builtin::ID BID = (Builtin::ID)bid;
 
   if (Context.BuiltinInfo.hasVAListUse(BID))
@@ -314,7 +313,7 @@
   FunctionDecl *New = FunctionDecl::Create(Context,
                                            Context.getTranslationUnitDecl(),
                                            SourceLocation(), II, R,
-                                           FunctionDecl::Extern, false, 0);
+                                           FunctionDecl::Extern, false);
   
   // Create Decl objects for each parameter, adding them to the
   // FunctionDecl.
@@ -322,8 +321,7 @@
     llvm::SmallVector<ParmVarDecl*, 16> Params;
     for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i)
       Params.push_back(ParmVarDecl::Create(Context, New, SourceLocation(), 0,
-                                           FT->getArgType(i), VarDecl::None, 0,
-                                           0));
+                                           FT->getArgType(i), VarDecl::None, 0));
     New->setParams(Context, &Params[0], Params.size());
   }
   
@@ -921,13 +919,12 @@
   }
 
   // Create a declaration for this anonymous struct/union. 
-  ScopedDecl *Anon = 0;
+  NamedDecl *Anon = 0;
   if (RecordDecl *OwningClass = dyn_cast<RecordDecl>(Owner)) {
     Anon = FieldDecl::Create(Context, OwningClass, Record->getLocation(),
                              /*IdentifierInfo=*/0, 
                              Context.getTypeDeclType(Record),
-                             /*BitWidth=*/0, /*Mutable=*/false,
-                             /*PrevDecl=*/0);
+                             /*BitWidth=*/0, /*Mutable=*/false);
     Anon->setAccess(AS_public);
     if (getLangOptions().CPlusPlus)
       FieldCollector->Add(cast<FieldDecl>(Anon));
@@ -953,8 +950,7 @@
     Anon = VarDecl::Create(Context, Owner, Record->getLocation(),
                            /*IdentifierInfo=*/0, 
                            Context.getTypeDeclType(Record),
-                           SC, /*FIXME:LastDeclarator=*/0,
-                           DS.getSourceRange().getBegin());
+                           SC, DS.getSourceRange().getBegin());
   }
   Anon->setImplicit();
 
@@ -1206,7 +1202,7 @@
 Sema::DeclTy *
 Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
                       bool IsFunctionDefinition) {
-  ScopedDecl *LastDeclarator = dyn_cast_or_null<ScopedDecl>((Decl *)lastDecl);
+  NamedDecl *LastDeclarator = dyn_cast_or_null<NamedDecl>((Decl *)lastDecl);
   DeclarationName Name = GetNameForDeclarator(D);
 
   // All of these full declarators require an identifier.  If it doesn't have
@@ -1227,7 +1223,7 @@
   
   DeclContext *DC;
   Decl *PrevDecl;
-  ScopedDecl *New;
+  NamedDecl *New;
   bool InvalidDecl = false;
  
   // See if this is a redefinition of a variable in the same scope.
@@ -1320,9 +1316,9 @@
   return New;
 }
 
-ScopedDecl*
+NamedDecl*
 Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                             QualType R, ScopedDecl* LastDeclarator,
+                             QualType R, Decl* LastDeclarator,
                              Decl* PrevDecl, bool& InvalidDecl) {
   // Typedef declarators cannot be qualified (C++ [dcl.meaning]p1).
   if (D.getCXXScopeSpec().isSet()) {
@@ -1364,9 +1360,9 @@
   return NewTD;
 }
 
-ScopedDecl*
+NamedDecl*
 Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                              QualType R, ScopedDecl* LastDeclarator,
+                              QualType R, Decl* LastDeclarator,
                               Decl* PrevDecl, bool& InvalidDecl) {
   DeclarationName Name = GetNameForDeclarator(D);
 
@@ -1410,7 +1406,7 @@
     // This is a static data member for a C++ class.
     NewVD = CXXClassVarDecl::Create(Context, cast<CXXRecordDecl>(DC),
                                     D.getIdentifierLoc(), II,
-                                    R, LastDeclarator);
+                                    R);
   } else {
     bool ThreadSpecified = D.getDeclSpec().isThreadSpecified();
     if (S->getFnParent() == 0) {
@@ -1422,11 +1418,13 @@
       }
     }
     NewVD = VarDecl::Create(Context, DC, D.getIdentifierLoc(), 
-                            II, R, SC, LastDeclarator,
+                            II, R, SC, 
                             // FIXME: Move to DeclGroup...
                             D.getDeclSpec().getSourceRange().getBegin());
     NewVD->setThreadSpecified(ThreadSpecified);
   }
+  NewVD->setNextDeclarator(LastDeclarator);
+
   // Handle attributes prior to checking for duplicates in MergeVarDecl
   ProcessDeclAttributes(NewVD, D);
 
@@ -1471,9 +1469,9 @@
   return NewVD;
 }
 
-ScopedDecl* 
+NamedDecl* 
 Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                              QualType R, ScopedDecl *LastDeclarator,
+                              QualType R, Decl *LastDeclarator,
                               Decl* PrevDecl, bool IsFunctionDefinition,
                               bool& InvalidDecl) {
   assert(R.getTypePtr()->isFunctionType());
@@ -1534,7 +1532,7 @@
       // Create a FunctionDecl to satisfy the function definition parsing
       // code path.
       NewFD = FunctionDecl::Create(Context, DC, D.getIdentifierLoc(),
-                                   Name, R, SC, isInline, LastDeclarator,
+                                   Name, R, SC, isInline, 
                                    // FIXME: Move to DeclGroup...
                                    D.getDeclSpec().getSourceRange().getBegin());
       InvalidDecl = true;
@@ -1559,15 +1557,15 @@
     // This is a C++ method declaration.
     NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(DC),
                                   D.getIdentifierLoc(), Name, R,
-                                  (SC == FunctionDecl::Static), isInline,
-                                  LastDeclarator);
+                                  (SC == FunctionDecl::Static), isInline);
   } else {
     NewFD = FunctionDecl::Create(Context, DC,
                                  D.getIdentifierLoc(),
-                                 Name, R, SC, isInline, LastDeclarator,
+                                 Name, R, SC, isInline, 
                                  // FIXME: Move to DeclGroup...
                                  D.getDeclSpec().getSourceRange().getBegin());
   }
+  NewFD->setNextDeclarator(LastDeclarator);
 
   // Set the lexical context. If the declarator has a C++
   // scope specifier, the lexical context will be different
@@ -1639,7 +1637,7 @@
         Params.push_back(ParmVarDecl::Create(Context, DC,
                                              SourceLocation(), 0,
                                              *ArgType, VarDecl::None,
-                                             0, 0));
+                                             0));
       }
 
       NewFD->setParams(Context, &Params[0], Params.size());
@@ -2299,8 +2297,7 @@
   
   VarDecl *VDecl = dyn_cast<VarDecl>(RealDecl);
   if (!VDecl) {
-    Diag(dyn_cast<ScopedDecl>(RealDecl)->getLocation(), 
-         diag::err_illegal_initializer);
+    Diag(RealDecl->getLocation(), diag::err_illegal_initializer);
     RealDecl->setInvalidDecl();
     return;
   }  
@@ -2442,13 +2439,13 @@
   if (GroupDecl == 0)
     return 0;
   
-  ScopedDecl *Group = dyn_cast<ScopedDecl>(GroupDecl);
-  ScopedDecl *NewGroup = 0;
+  Decl *Group = dyn_cast<Decl>(GroupDecl);
+  Decl *NewGroup = 0;
   if (Group->getNextDeclarator() == 0) 
     NewGroup = Group;
   else { // reverse the list.
     while (Group) {
-      ScopedDecl *Next = Group->getNextDeclarator();
+      Decl *Next = Group->getNextDeclarator();
       Group->setNextDeclarator(NewGroup);
       NewGroup = Group;
       Group = Next;
@@ -2456,7 +2453,7 @@
   }
   // Perform semantic analysis that depends on having fully processed both
   // the declarator and initializer.
-  for (ScopedDecl *ID = NewGroup; ID; ID = ID->getNextDeclarator()) {
+  for (Decl *ID = NewGroup; ID; ID = ID->getNextDeclarator()) {
     VarDecl *IDecl = dyn_cast<VarDecl>(ID);
     if (!IDecl)
       continue;
@@ -2608,7 +2605,7 @@
   ParmVarDecl *New = ParmVarDecl::Create(Context, CurContext, 
                                          D.getIdentifierLoc(), II,
                                          parmDeclType, StorageClass, 
-                                         0, 0);
+                                         0);
   
   if (D.getInvalidType())
     New->setInvalidDecl();
@@ -2756,8 +2753,8 @@
 
 /// ImplicitlyDefineFunction - An undeclared identifier was used in a function
 /// call, forming a call to an implicitly defined function (per C99 6.5.1p2).
-ScopedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, 
-                                           IdentifierInfo &II, Scope *S) {
+NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, 
+                                          IdentifierInfo &II, Scope *S) {
   // Extension in C99.  Legal in C90, but warn about it.
   if (getLangOptions().C99)
     Diag(Loc, diag::ext_implicit_function_decl) << &II;
@@ -2794,7 +2791,7 @@
 
 
 TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
-                                    ScopedDecl *LastDeclarator) {
+                                    Decl *LastDeclarator) {
   assert(D.getIdentifier() && "Wrong callback for declspec without declarator");
   assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
   
@@ -2802,7 +2799,8 @@
   TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext,
                                            D.getIdentifierLoc(),
                                            D.getIdentifier(), 
-                                           T, LastDeclarator);
+                                           T);
+  NewTD->setNextDeclarator(LastDeclarator);
   if (D.getInvalidType())
     NewTD->setInvalidDecl();
   return NewTD;
@@ -2833,7 +2831,7 @@
   DeclContext *SearchDC = CurContext;
   DeclContext *DC = CurContext;
   DeclContext *LexicalContext = CurContext;
-  ScopedDecl *PrevDecl = 0;
+  Decl *PrevDecl = 0;
 
   bool Invalid = false;
 
@@ -2860,9 +2858,8 @@
   } else {
     // If this is a named struct, check to see if there was a previous forward
     // declaration or definition.
-    // Use ScopedDecl instead of TagDecl, because a NamespaceDecl may come up.
-    PrevDecl = dyn_cast_or_null<ScopedDecl>(LookupDecl(Name, Decl::IDNS_Tag,S)
-                                              .getAsDecl());
+    PrevDecl = dyn_cast_or_null<NamedDecl>(LookupDecl(Name, Decl::IDNS_Tag,S)
+                                             .getAsDecl());
 
     if (!getLangOptions().CPlusPlus && TK != TK_Reference) {
       // FIXME: This makes sure that we ignore the contexts associated
@@ -3222,8 +3219,7 @@
   NewFD = FieldDecl::Create(Context, Record,
                             Loc, II, T, BitWidth,
                             D.getDeclSpec().getStorageClassSpec() ==
-                              DeclSpec::SCS_mutable,
-                            /*PrevDecl=*/0);
+                              DeclSpec::SCS_mutable);
 
   if (II) {
     Decl *PrevDecl 
@@ -3556,8 +3552,7 @@
   
   EnumConstantDecl *New = 
     EnumConstantDecl::Create(Context, TheEnumDecl, IdLoc, Id, EltTy,
-                             Val, EnumVal,
-                             LastEnumConst);
+                             Val, EnumVal);
   
   // Register this decl in the current scope stack.
   PushOnScopeChains(New, S);
@@ -3739,7 +3734,7 @@
                                           ExprArg expr) {
   StringLiteral *AsmString = cast<StringLiteral>((Expr*)expr.release());
 
-  return FileScopeAsmDecl::Create(Context, Loc, AsmString);
+  return FileScopeAsmDecl::Create(Context, CurContext, Loc, AsmString);
 }
 
 
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 95f9200..a582540 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -421,13 +421,6 @@
 /// bitfield width if there is one and 'InitExpr' specifies the initializer if
 /// any. 'LastInGroup' is non-null for cases where one declspec has multiple
 /// declarators on it.
-///
-/// FIXME: The note below is out-of-date.
-/// NOTE: Because of CXXFieldDecl's inability to be chained like ScopedDecls, if
-/// an instance field is declared, a new CXXFieldDecl is created but the method
-/// does *not* return it; it returns LastInGroup instead. The other C++ members
-/// (which are all ScopedDecls) are returned after appending them to
-/// LastInGroup.
 Sema::DeclTy *
 Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
                                ExprTy *BW, ExprTy *InitExpr,
@@ -876,7 +869,7 @@
     ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyConstructor,
                                                  ClassDecl->getLocation(),
                                                  /*IdentifierInfo=*/0,
-                                                 ArgType, VarDecl::None, 0, 0);
+                                                 ArgType, VarDecl::None, 0);
     CopyConstructor->setParams(Context, &FromParam, 1);
 
     ClassDecl->addedConstructor(Context, CopyConstructor);
@@ -945,7 +938,7 @@
       CXXMethodDecl::Create(Context, ClassDecl, ClassDecl->getLocation(), Name,
                             Context.getFunctionType(RetType, &ArgType, 1,
                                                     false, 0),
-                            /*isStatic=*/false, /*isInline=*/true, 0);
+                            /*isStatic=*/false, /*isInline=*/true);
     CopyAssignment->setAccess(AS_public);
     CopyAssignment->setImplicit();
 
@@ -953,7 +946,7 @@
     ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyAssignment,
                                                  ClassDecl->getLocation(),
                                                  /*IdentifierInfo=*/0,
-                                                 ArgType, VarDecl::None, 0, 0);
+                                                 ArgType, VarDecl::None, 0);
     CopyAssignment->setParams(Context, &FromParam, 1);
 
     // Don't call addedAssignmentOperator. There is no way to distinguish an
@@ -2211,7 +2204,7 @@
   }
 
   VarDecl *ExDecl = VarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
-                                    II, ExDeclType, VarDecl::None, 0, Begin);
+                                    II, ExDeclType, VarDecl::None, Begin);
   if (D.getInvalidType() || Invalid)
     ExDecl->setInvalidDecl();
 
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index c4fccc7..2653887 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -592,7 +592,7 @@
   
   ObjCImplementationDecl* IMPDecl = 
     ObjCImplementationDecl::Create(Context, CurContext, AtClassImplLoc, 
-                                   ClassName, IDecl, SDecl);
+                                   IDecl, SDecl);
   
   // FIXME: PushOnScopeChains?
   CurContext->addDecl(IMPDecl);
@@ -613,7 +613,7 @@
                                     ObjCIvarDecl **ivars, unsigned numIvars,
                                     SourceLocation RBrace) {
   assert(ImpDecl && "missing implementation decl");
-  ObjCInterfaceDecl* IDecl = getObjCInterfaceDecl(ImpDecl->getIdentifier());
+  ObjCInterfaceDecl* IDecl = ImpDecl->getClassInterface();
   if (!IDecl)
     return;
   /// Check case of non-existing @interface decl.
@@ -1143,7 +1143,7 @@
                                                   property->getIdentifier(),
                                                   property->getType(),
                                                   VarDecl::None,
-                                                  0, 0);
+                                                  0);
       SetterMethod->setMethodParams(&Argument, 1);
       CD->addDecl(SetterMethod);
     } else
@@ -1258,7 +1258,7 @@
   }
   if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
     IC->setLocEnd(AtEndLoc);
-    if (ObjCInterfaceDecl* IDecl = getObjCInterfaceDecl(IC->getIdentifier()))
+    if (ObjCInterfaceDecl* IDecl = IC->getClassInterface())
       ImplMethodsVsClassMethods(IC, IDecl);
   } else if (ObjCCategoryImplDecl* CatImplClass = 
                                    dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
@@ -1361,12 +1361,12 @@
       Param = ParmVarDecl::Create(Context, ObjCMethod,
                                   SourceLocation(/*FIXME*/),
                                   ArgNames[i], argType,
-                                  VarDecl::None, 0, 0);
+                                  VarDecl::None, 0);
     else
       Param = ParmVarWithOriginalTypeDecl::Create(Context, ObjCMethod,
                                   SourceLocation(/*FIXME*/),
                                   ArgNames[i], argType, originalArgType,
-                                  VarDecl::None, 0, 0);
+                                  VarDecl::None, 0);
     
     Param->setObjCDeclQualifier(
       CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
@@ -1544,7 +1544,7 @@
                                                         FD.D.getIdentifier(),
                                                         T,
                                                         VarDecl::None,
-                                                        0, 0);
+                                                        0);
             SetterDecl->setMethodParams(&Argument, 1);
             PIDecl->setSetterMethodDecl(SetterDecl);
           }
@@ -1634,7 +1634,7 @@
   ObjCImplementationDecl *IC = 0;
   ObjCCategoryImplDecl* CatImplClass = 0;
   if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
-    IDecl = getObjCInterfaceDecl(IC->getIdentifier());
+    IDecl = IC->getClassInterface();
     // We always synthesize an interface for an implementation
     // without an interface decl. So, IDecl is always non-zero.
     assert(IDecl && 
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index f6623b0..5b6b00c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -383,11 +383,11 @@
 /// getObjectForAnonymousRecordDecl - Retrieve the (unnamed) field or
 /// variable corresponding to the anonymous union or struct whose type
 /// is Record.
-static ScopedDecl *getObjectForAnonymousRecordDecl(RecordDecl *Record) {
+static Decl *getObjectForAnonymousRecordDecl(RecordDecl *Record) {
   assert(Record->isAnonymousStructOrUnion() && 
          "Record must be an anonymous struct or union!");
   
-  // FIXME: Once ScopedDecls are directly linked together, this will
+  // FIXME: Once Decls are directly linked together, this will
   // be an O(1) operation rather than a slow walk through DeclContext's
   // vector (which itself will be eliminated). DeclGroups might make
   // this even better.
@@ -400,7 +400,7 @@
       // follows its type in the list of declarations.
       ++D;
       assert(D != DEnd && "Missing object for anonymous record");
-      assert(!cast<ScopedDecl>(*D)->getDeclName() && "Decl should be unnamed");
+      assert(!cast<NamedDecl>(*D)->getDeclName() && "Decl should be unnamed");
       return *D;
     }
   }
@@ -429,7 +429,7 @@
   DeclContext *Ctx = Field->getDeclContext();
   do {
     RecordDecl *Record = cast<RecordDecl>(Ctx);
-    ScopedDecl *AnonObject = getObjectForAnonymousRecordDecl(Record);
+    Decl *AnonObject = getObjectForAnonymousRecordDecl(Record);
     if (FieldDecl *AnonField = dyn_cast<FieldDecl>(AnonObject))
       AnonFields.push_back(AnonField);
     else {
@@ -576,13 +576,12 @@
   // well.
   IdentifierInfo *II = Name.getAsIdentifierInfo();
   if (II && getCurMethodDecl()) {
-    ScopedDecl *SD = dyn_cast_or_null<ScopedDecl>(D);
     // There are two cases to handle here.  1) scoped lookup could have failed,
     // in which case we should look for an ivar.  2) scoped lookup could have
     // found a decl, but that decl is outside the current method (i.e. a global
     // variable).  In these two cases, we do a lookup for an ivar with this
     // name, if the lookup suceeds, we replace it our current decl.
-    if (SD == 0 || SD->isDefinedOutsideFunctionOrMethod()) {
+    if (D == 0 || D->isDefinedOutsideFunctionOrMethod()) {
       ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
       if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II)) {
         // FIXME: This should use a new expr for a direct reference, don't turn
@@ -597,7 +596,7 @@
       }
     }
     // Needed to implement property "super.method" notation.
-    if (SD == 0 && II->isStr("super")) {
+    if (D == 0 && II->isStr("super")) {
       QualType T = Context.getPointerType(Context.getObjCInterfaceType(
                      getCurMethodDecl()->getClassInterface()));
       return Owned(new ObjCSuperExpr(Loc, T));
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 8958221..1266d32 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -540,11 +540,11 @@
   QualType FnType = Context.getFunctionType(Return, &Argument, 1, false, 0);
   FunctionDecl *Alloc =
     FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name,
-                         FnType, FunctionDecl::None, false, 0,
+                         FnType, FunctionDecl::None, false,
                          SourceLocation());
   Alloc->setImplicit();
   ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
-                                           0, Argument, VarDecl::None, 0, 0);
+                                           0, Argument, VarDecl::None, 0);
   Alloc->setParams(Context, &Param, 1);
 
   // FIXME: Also add this declaration to the IdentifierResolver, but
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 5f8f3f5..7353bc3 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -53,8 +53,7 @@
         // FIXME: We leak this overload set. Eventually, we want to
         // stop building the declarations for these overload sets, so
         // there will be nothing to leak.
-        Ovl = OverloadedFunctionDecl::Create(Context, 
-                                         cast<ScopedDecl>(*I)->getDeclContext(),
+        Ovl = OverloadedFunctionDecl::Create(Context, (*I)->getDeclContext(),
                                              (*I)->getDeclName());
         Ovl->addOverload(cast<FunctionDecl>(*I));
       }
@@ -491,7 +490,7 @@
       //   A static member, a nested type or an enumerator defined in
       //   a base class T can unambiguously be found even if an object
       //   has more than one base class subobject of type T. 
-      ScopedDecl *FirstDecl = *Path->Decls.first;
+      Decl *FirstDecl = *Path->Decls.first;
       if (isa<VarDecl>(FirstDecl) ||
           isa<TypeDecl>(FirstDecl) ||
           isa<EnumConstantDecl>(FirstDecl))
@@ -610,10 +609,10 @@
   Diag(NameLoc, diag::err_ambiguous_member_multiple_subobject_types)
     << Name << LookupRange;
 
-  std::set<ScopedDecl *> DeclsPrinted;
+  std::set<Decl *> DeclsPrinted;
   for (BasePaths::paths_iterator Path = Paths->begin(), PathEnd = Paths->end();
        Path != PathEnd; ++Path) {
-    ScopedDecl *D = *Path->Decls.first;
+    Decl *D = *Path->Decls.first;
     if (DeclsPrinted.insert(D).second)
       Diag(D->getLocation(), diag::note_ambiguous_member_found);
   }
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 61c22d4..9441ea5 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2193,20 +2193,17 @@
       // operator names can only be ordinary identifiers.
 
       // Ignore member functions. 
-      if (ScopedDecl *SD = dyn_cast<ScopedDecl>(*I)) {
-        if (SD->getDeclContext()->isRecord())
-          continue;
-      } 
+      if ((*I)->getDeclContext()->isRecord())
+        continue;
 
       // We found something with this name. We're done.
       break;
     }
 
-    if (I != IEnd && isa<ScopedDecl>(*I)) {
-      ScopedDecl *FirstDecl = cast<ScopedDecl>(*I);
+    if (I != IEnd) {
+      Decl *FirstDecl = *I;
       for (; I != IEnd; ++I) {
-        ScopedDecl *SD = cast<ScopedDecl>(*I);
-        if (FirstDecl->getDeclContext() != SD->getDeclContext())
+        if (FirstDecl->getDeclContext() != (*I)->getDeclContext())
           break;
 
         if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I))
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 8b72514..9e15c21 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -43,14 +43,14 @@
   if (decl == 0)
     return StmtError();
 
-  ScopedDecl *SD = cast<ScopedDecl>(static_cast<Decl *>(decl));
+  Decl *D = static_cast<Decl *>(decl);
 
   // This is a temporary hack until we are always passing around
   // DeclGroupRefs.
   llvm::SmallVector<Decl*, 10> decls;
-  while (SD) { 
-    ScopedDecl* d = SD;
-    SD = SD->getNextDeclarator();
+  while (D) { 
+    Decl* d = D;
+    D = D->getNextDeclarator();
     d->setNextDeclarator(0);
     decls.push_back(d);
   }
@@ -86,7 +86,7 @@
       /*empty*/;
     
     if (i != NumElts) {
-      ScopedDecl *D = *cast<DeclStmt>(Elts[i])->decl_begin();
+      Decl *D = *cast<DeclStmt>(Elts[i])->decl_begin();
       Diag(D->getLocation(), diag::ext_mixed_decls_code);
     }
   }
@@ -633,7 +633,7 @@
         return StmtError(Diag((*DS->decl_begin())->getLocation(),
                          diag::err_toomany_element_decls));
 
-      ScopedDecl *D = DS->getSolitaryDecl();
+      Decl *D = DS->getSolitaryDecl();
       FirstType = cast<ValueDecl>(D)->getType();
       // C99 6.8.5p3: The declaration part of a 'for' statement shall only
       // declare identifiers for objects having storage class 'auto' or