Addition of TranslationUnitDecl to the AST:

-Added TranslationUnitDecl class to serve as top declaration context
-ASTContext gets a TUDecl member and a getTranslationUnitDecl() function
-All ScopedDecls get the TUDecl as DeclContext when declared at global scope


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49855 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e4b48e2..7220ce4 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1175,7 +1175,7 @@
 QualType ASTContext::getCFConstantStringType() {
   if (!CFConstantStringTypeDecl) {
     CFConstantStringTypeDecl = 
-      RecordDecl::Create(*this, Decl::Struct, NULL, SourceLocation(), 
+      RecordDecl::Create(*this, Decl::Struct, TUDecl, SourceLocation(), 
                          &Idents.get("NSConstantString"), 0);
     QualType FieldTypes[4];
   
@@ -1727,6 +1727,8 @@
                                           I!=E;++I)    
     (*I)->Emit(S);
 
+  S.EmitOwnedPtr(TUDecl);
+
   // FIXME: S.EmitOwnedPtr(CFConstantStringTypeDecl);
 }
 
@@ -1743,6 +1745,8 @@
   for (unsigned i = 0; i < size_reserve; ++i)
     Type::Create(*A,i,D);
   
+  A->TUDecl = cast<TranslationUnitDecl>(D.ReadOwnedPtr<Decl>(*A));
+
   // FIXME: A->CFConstantStringTypeDecl = D.ReadOwnedPtr<RecordDecl>();
   
   return A;
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 900096f..6ebaac5 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -198,6 +198,7 @@
   case ObjCPropertyImpl:    nObjCPropertyImplDecl++; break;
   case LinkageSpec:         nLinkageSpecDecl++; break;
   case FileScopeAsm:        nFileScopeAsmDecl++; break;
+  case TranslationUnit:     break;
   }
 }
 
@@ -205,6 +206,11 @@
 // Decl Allocation/Deallocation Method Implementations
 //===----------------------------------------------------------------------===//
 
+TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
+  void *Mem = C.getAllocator().Allocate<TranslationUnitDecl>();
+  return new (Mem) TranslationUnitDecl();
+}
+
 VarDecl *VarDecl::Create(ASTContext &C, DeclContext *CD,
                          SourceLocation L,
                          IdentifierInfo *Id, QualType T,
@@ -213,7 +219,6 @@
   return new (Mem) VarDecl(Var, CD, L, Id, T, S, PrevDecl);
 }
 
-
 ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *CD,
                                  SourceLocation L, IdentifierInfo *Id,
                                  QualType T, StorageClass S,
@@ -329,6 +334,7 @@
 
 void Decl::Destroy(ASTContext& C) const {
   switch (getKind()) {
+  CASE(TranslationUnit);
   CASE(Field);
   CASE(ObjCIvar);
   CASE(ObjCCategory);
diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp
index 96df1b7..e7442ff 100644
--- a/lib/AST/DeclSerialization.cpp
+++ b/lib/AST/DeclSerialization.cpp
@@ -41,6 +41,9 @@
       assert (false && "Not implemented.");
       break;
 
+    case TranslationUnit:
+      return TranslationUnitDecl::CreateImpl(D, C);
+
     case Var:
       return VarDecl::CreateImpl(D, C);
       
@@ -192,6 +195,26 @@
 }
 
 //===----------------------------------------------------------------------===//
+//      TranslationUnitDecl Serialization.
+//===----------------------------------------------------------------------===//
+
+void TranslationUnitDecl::EmitImpl(llvm::Serializer& S) const
+{
+  Decl::EmitInRec(S);
+}
+
+TranslationUnitDecl* TranslationUnitDecl::CreateImpl(Deserializer& D,
+                                                     ASTContext& C) {  
+  void *Mem = C.getAllocator().Allocate<TranslationUnitDecl>();
+  TranslationUnitDecl* decl =
+    new (Mem) TranslationUnitDecl();
+ 
+  decl->Decl::ReadInRec(D, C);
+  
+  return decl;
+}
+
+//===----------------------------------------------------------------------===//
 //      VarDecl Serialization.
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index c6a862b..bb5316a 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -42,6 +42,7 @@
 
 void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
   TUScope = S;
+  CurContext = Context.getTranslationUnitDecl();
   if (!PP.getLangOptions().ObjC1) return;
   
   TypedefType *t;
@@ -93,14 +94,16 @@
   // FIXME: Move this initialization up to Sema::ActOnTranslationUnitScope()
   // and make sure the decls get inserted into TUScope!
   if (PP.getLangOptions().ObjC1) {
+    TranslationUnitDecl *TUDecl = Context.getTranslationUnitDecl();
+
     // Synthesize "typedef struct objc_class *Class;"
     RecordDecl *ClassTag = RecordDecl::Create(Context, Decl::Struct,
-                                              NULL,
+                                              TUDecl,
                                               SourceLocation(),
                                               &IT.get("objc_class"), 0);
     QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
     TypedefDecl *ClassTypedef = 
-      TypedefDecl::Create(Context, NULL, SourceLocation(),
+      TypedefDecl::Create(Context, TUDecl, SourceLocation(),
                           &Context.Idents.get("Class"), ClassT, 0);
     Context.setObjCClassType(ClassTypedef);
     
@@ -113,14 +116,14 @@
     
     // Synthesize "typedef struct objc_object { Class isa; } *id;"
     RecordDecl *ObjectTag = 
-      RecordDecl::Create(Context, Decl::Struct, NULL,
+      RecordDecl::Create(Context, Decl::Struct, TUDecl,
                          SourceLocation(),
                          &IT.get("objc_object"), 0);
     FieldDecl *IsaDecl = FieldDecl::Create(Context, SourceLocation(), 0,
                                            Context.getObjCClassType());
     ObjectTag->defineBody(&IsaDecl, 1);
     QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
-    TypedefDecl *IdTypedef = TypedefDecl::Create(Context, NULL,
+    TypedefDecl *IdTypedef = TypedefDecl::Create(Context, TUDecl,
                                                  SourceLocation(),
                                                  &Context.Idents.get("id"),
                                                  ObjT, 0);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 6d41fce..f0e4697 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -43,14 +43,18 @@
 }
 
 void Sema::PushDeclContext(DeclContext *CD) {
-  assert(CD->getParent() == CurContext &&
+  assert( ( (CD->isFunctionOrMethod() && isa<TranslationUnitDecl>(CurContext))
+            || CD->getParent() == CurContext ) &&
       "The next DeclContext should be directly contained in the current one.");
   CurContext = CD;
 }
 
 void Sema::PopDeclContext() {
   assert(CurContext && "DeclContext imbalance!");
-  CurContext = CurContext->getParent();
+  // If CurContext is a ObjC method, getParent() will return NULL.
+  CurContext = CurContext->isFunctionOrMethod()
+               ? Context.getTranslationUnitDecl()
+                 :  CurContext->getParent();
 }
 
 /// Add this decl to the scope shadowed decl chains.