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 {