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.