Introduce ContextDecl, patch by Argiris Kirtzidis!
-Added ContextDecl (no TranslationUnitDecl)
-ScopedDecl class has a ContextDecl member
-FieldDecl class has a ContextDecl member, so that a Field or a ObjCIvar can be traced back to their RecordDecl/ObjCInterfaceDecl easily
-FunctionDecl, ObjCMethodDecl, TagDecl, ObjCInterfaceDecl inherit from ContextDecl. With TagDecl as ContextDecl, enum constants have a EnumDecl as their context.
-Moved Decl class to a "DeclBase.h" along with ContextDecl class
-CurContext is handled by Sema
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49208 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index ce75122..9e51b29 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1115,7 +1115,7 @@
QualType ASTContext::getCFConstantStringType() {
if (!CFConstantStringTypeDecl) {
CFConstantStringTypeDecl =
- RecordDecl::Create(*this, Decl::Struct, SourceLocation(),
+ RecordDecl::Create(*this, Decl::Struct, NULL, SourceLocation(),
&Idents.get("NSConstantString"), 0);
QualType FieldTypes[4];
@@ -1131,7 +1131,8 @@
FieldDecl *FieldDecls[4];
for (unsigned i = 0; i < 4; ++i)
- FieldDecls[i] = FieldDecl::Create(*this, SourceLocation(), 0,
+ FieldDecls[i] = FieldDecl::Create(*this, CFConstantStringTypeDecl,
+ SourceLocation(), 0,
FieldTypes[i]);
CFConstantStringTypeDecl->defineBody(FieldDecls, 4);
@@ -1907,14 +1908,14 @@
TargetInfo &t = D.ReadRef<TargetInfo>();
IdentifierTable &idents = D.ReadRef<IdentifierTable>();
SelectorTable &sels = D.ReadRef<SelectorTable>();
-
+
unsigned size_reserve = D.ReadInt();
ASTContext* A = new ASTContext(SM,t,idents,sels,size_reserve);
for (unsigned i = 0; i < size_reserve; ++i)
Type::Create(*A,i,D);
-
+
// FIXME: A->CFConstantStringTypeDecl = D.ReadOwnedPtr<RecordDecl>();
return A;
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 3e7d838..38a20c1 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -204,77 +204,87 @@
// Decl Allocation/Deallocation Method Implementations
//===----------------------------------------------------------------------===//
-BlockVarDecl *BlockVarDecl::Create(ASTContext &C, SourceLocation L,
+BlockVarDecl *BlockVarDecl::Create(ASTContext &C, ContextDecl *CD,
+ SourceLocation L,
IdentifierInfo *Id, QualType T,
StorageClass S, ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<BlockVarDecl>();
- return new (Mem) BlockVarDecl(L, Id, T, S, PrevDecl);
+ return new (Mem) BlockVarDecl(CD, L, Id, T, S, PrevDecl);
}
-FileVarDecl *FileVarDecl::Create(ASTContext &C, SourceLocation L,
- IdentifierInfo *Id, QualType T, StorageClass S,
+FileVarDecl *FileVarDecl::Create(ASTContext &C, ContextDecl *CD,
+ SourceLocation L, IdentifierInfo *Id,
+ QualType T, StorageClass S,
ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<FileVarDecl>();
- return new (Mem) FileVarDecl(L, Id, T, S, PrevDecl);
+ return new (Mem) FileVarDecl(CD, L, Id, T, S, PrevDecl);
}
-ParmVarDecl *ParmVarDecl::Create(ASTContext &C, SourceLocation L,
- IdentifierInfo *Id, QualType T, StorageClass S,
+ParmVarDecl *ParmVarDecl::Create(ASTContext &C, ContextDecl *CD,
+ SourceLocation L, IdentifierInfo *Id,
+ QualType T, StorageClass S,
ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<ParmVarDecl>();
- return new (Mem) ParmVarDecl(L, Id, T, S, PrevDecl);
+ return new (Mem) ParmVarDecl(CD, L, Id, T, S, PrevDecl);
}
-FunctionDecl *FunctionDecl::Create(ASTContext &C, SourceLocation L,
+FunctionDecl *FunctionDecl::Create(ASTContext &C, ContextDecl *CD,
+ SourceLocation L,
IdentifierInfo *Id, QualType T,
StorageClass S, bool isInline,
ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<FunctionDecl>();
- return new (Mem) FunctionDecl(L, Id, T, S, isInline, PrevDecl);
+ return new (Mem) FunctionDecl(CD, L, Id, T, S, isInline, PrevDecl);
}
-FieldDecl *FieldDecl::Create(ASTContext &C, SourceLocation L,
+FieldDecl *FieldDecl::Create(ASTContext &C, RecordDecl *CD, SourceLocation L,
IdentifierInfo *Id, QualType T, Expr *BW) {
void *Mem = C.getAllocator().Allocate<FieldDecl>();
- return new (Mem) FieldDecl(L, Id, T, BW);
+ return new (Mem) FieldDecl(CD, L, Id, T, BW);
}
-EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, SourceLocation L,
+EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
+ SourceLocation L,
IdentifierInfo *Id, QualType T,
Expr *E, const llvm::APSInt &V,
ScopedDecl *PrevDecl){
void *Mem = C.getAllocator().Allocate<EnumConstantDecl>();
- return new (Mem) EnumConstantDecl(L, Id, T, E, V, PrevDecl);
+ return new (Mem) EnumConstantDecl(CD, L, Id, T, E, V, PrevDecl);
}
-TypedefDecl *TypedefDecl::Create(ASTContext &C, SourceLocation L,
+TypedefDecl *TypedefDecl::Create(ASTContext &C, ContextDecl *CD,
+ SourceLocation L,
IdentifierInfo *Id, QualType T,
ScopedDecl *PD) {
void *Mem = C.getAllocator().Allocate<TypedefDecl>();
- return new (Mem) TypedefDecl(L, Id, T, PD);
+ return new (Mem) TypedefDecl(CD, L, Id, T, PD);
}
-EnumDecl *EnumDecl::Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id,
+EnumDecl *EnumDecl::Create(ASTContext &C, ContextDecl *CD, SourceLocation L,
+ IdentifierInfo *Id,
ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<EnumDecl>();
- return new (Mem) EnumDecl(L, Id, PrevDecl);
+ return new (Mem) EnumDecl(CD, L, Id, PrevDecl);
}
-RecordDecl *RecordDecl::Create(ASTContext &C, Kind DK, SourceLocation L,
- IdentifierInfo *Id, ScopedDecl *PrevDecl) {
+RecordDecl *RecordDecl::Create(ASTContext &C, Kind DK, ContextDecl *CD,
+ SourceLocation L, IdentifierInfo *Id,
+ ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<RecordDecl>();
- return new (Mem) RecordDecl(DK, L, Id, PrevDecl);
+ return new (Mem) RecordDecl(DK, CD, L, Id, PrevDecl);
}
-FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, SourceLocation L,
+FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C,
+ SourceLocation L,
StringLiteral *Str) {
void *Mem = C.getAllocator().Allocate<FileScopeAsmDecl>();
return new (Mem) FileScopeAsmDecl(L, Str);
}
-LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, SourceLocation L,
+LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
+ SourceLocation L,
LanguageIDs Lang, Decl *D) {
void *Mem = C.getAllocator().Allocate<LinkageSpecDecl>();
return new (Mem) LinkageSpecDecl(L, Lang, D);
@@ -320,6 +330,25 @@
}
//===----------------------------------------------------------------------===//
+// ContextDecl Implementation
+//===----------------------------------------------------------------------===//
+
+ContextDecl *ContextDecl::getParent() const {
+ if (ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
+ return SD->getContext();
+ else
+ return NULL;
+}
+
+Decl *ContextDecl::ToDecl (const ContextDecl *D) {
+ return CastTo<Decl>(D);
+}
+
+ContextDecl *ContextDecl::FromDecl (const Decl *D) {
+ return CastTo<ContextDecl>(D);
+}
+
+//===----------------------------------------------------------------------===//
// NamedDecl Implementation
//===----------------------------------------------------------------------===//
@@ -330,28 +359,6 @@
}
//===----------------------------------------------------------------------===//
-// ScopedDecl Implementation
-//===----------------------------------------------------------------------===//
-
-// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
-// scoped decl is defined outside the current function or method. This is
-// roughly global variables and functions, but also handles enums (which could
-// be defined inside or outside a function etc).
-bool ScopedDecl::isDefinedOutsideFunctionOrMethod() const {
- if (const VarDecl *VD = dyn_cast<VarDecl>(this))
- return VD->hasGlobalStorage();
- if (isa<FunctionDecl>(this))
- return true;
-
- // FIXME: This needs to check the context the decl was defined in!
- if (isa<TypeDecl>(this) || isa<EnumConstantDecl>(this))
- return true;
-
- assert(0 && "Unknown ScopedDecl!");
- return false;
-}
-
-//===----------------------------------------------------------------------===//
// FunctionDecl Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 2e3a06a..a01c304 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -19,7 +19,8 @@
// ObjC Decl Allocation/Deallocation Method Implementations
//===----------------------------------------------------------------------===//
-ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, SourceLocation beginLoc,
+ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
+ SourceLocation beginLoc,
SourceLocation endLoc,
Selector SelInfo, QualType T,
Decl *contextDecl,
@@ -27,61 +28,71 @@
bool isVariadic,
ImplementationControl impControl) {
void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
- return new (Mem) ObjCMethodDecl(beginLoc, endLoc, SelInfo, T, contextDecl,
+ return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
+ SelInfo, T, contextDecl,
M, isInstance,
isVariadic, impControl);
}
-ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,SourceLocation atLoc,
+ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
+ SourceLocation atLoc,
unsigned numRefProtos,
IdentifierInfo *Id,
bool ForwardDecl, bool isInternal){
void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
- return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos, Id, ForwardDecl,
+ return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos,
+ Id, ForwardDecl,
isInternal);
}
-ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
+ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCInterfaceDecl *CD,
+ SourceLocation L,
IdentifierInfo *Id, QualType T) {
void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
- return new (Mem) ObjCIvarDecl(L, Id, T);
+ return new (Mem) ObjCIvarDecl(CD, L, Id, T);
}
-ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, SourceLocation L,
+ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
+ SourceLocation L,
unsigned numRefProtos,
IdentifierInfo *Id) {
void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
}
-ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, SourceLocation L,
+ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
+ SourceLocation L,
ObjCInterfaceDecl **Elts, unsigned nElts) {
void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
return new (Mem) ObjCClassDecl(L, Elts, nElts);
}
ObjCForwardProtocolDecl *
-ObjCForwardProtocolDecl::Create(ASTContext &C, SourceLocation L,
+ObjCForwardProtocolDecl::Create(ASTContext &C,
+ SourceLocation L,
ObjCProtocolDecl **Elts, unsigned NumElts) {
void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
}
-ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, SourceLocation L,
+ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
+ SourceLocation L,
IdentifierInfo *Id) {
void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
return new (Mem) ObjCCategoryDecl(L, Id);
}
ObjCCategoryImplDecl *
-ObjCCategoryImplDecl::Create(ASTContext &C, SourceLocation L,IdentifierInfo *Id,
+ObjCCategoryImplDecl::Create(ASTContext &C,
+ SourceLocation L,IdentifierInfo *Id,
ObjCInterfaceDecl *ClassInterface) {
void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
}
ObjCImplementationDecl *
-ObjCImplementationDecl::Create(ASTContext &C, SourceLocation L,
+ObjCImplementationDecl::Create(ASTContext &C,
+ SourceLocation L,
IdentifierInfo *Id,
ObjCInterfaceDecl *ClassInterface,
ObjCInterfaceDecl *SuperDecl) {
@@ -90,14 +101,16 @@
}
ObjCCompatibleAliasDecl *
-ObjCCompatibleAliasDecl::Create(ASTContext &C, SourceLocation L,
+ObjCCompatibleAliasDecl::Create(ASTContext &C,
+ SourceLocation L,
IdentifierInfo *Id,
ObjCInterfaceDecl* AliasedClass) {
void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
}
-ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, SourceLocation L) {
+ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
+ SourceLocation L) {
void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
return new (Mem) ObjCPropertyDecl(L);
}
@@ -431,3 +444,4 @@
}
+
diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp
index fe2ccef..3a79b9e 100644
--- a/lib/AST/DeclSerialization.cpp
+++ b/lib/AST/DeclSerialization.cpp
@@ -39,7 +39,7 @@
default:
assert (false && "Not implemented.");
break;
-
+
case BlockVar:
return BlockVarDecl::CreateImpl(D);
@@ -106,11 +106,15 @@
void ScopedDecl::EmitInRec(Serializer& S) const {
NamedDecl::EmitInRec(S);
S.EmitPtr(getNext()); // From ScopedDecl.
+ S.EmitPtr(cast_or_null<Decl>(getContext())); // From ScopedDecl.
}
void ScopedDecl::ReadInRec(Deserializer& D) {
NamedDecl::ReadInRec(D);
D.ReadPtr(Next); // From ScopedDecl.
+ Decl *TmpD;
+ D.ReadPtr(TmpD); // From ScopedDecl.
+ CtxDecl = cast_or_null<ContextDecl>(TmpD);
}
//===------------------------------------------------------------===//
@@ -194,7 +198,7 @@
BlockVarDecl* BlockVarDecl::CreateImpl(Deserializer& D) {
BlockVarDecl* decl =
- new BlockVarDecl(SourceLocation(),NULL,QualType(),None,NULL);
+ new BlockVarDecl(0, SourceLocation(),NULL,QualType(),None,NULL);
decl->VarDecl::ReadImpl(D);
@@ -207,7 +211,7 @@
FileVarDecl* FileVarDecl::CreateImpl(Deserializer& D) {
FileVarDecl* decl =
- new FileVarDecl(SourceLocation(),NULL,QualType(),None,NULL);
+ new FileVarDecl(0, SourceLocation(),NULL,QualType(),None,NULL);
decl->VarDecl::ReadImpl(D);
@@ -225,7 +229,7 @@
ParmVarDecl* ParmVarDecl::CreateImpl(Deserializer& D) {
ParmVarDecl* decl =
- new ParmVarDecl(SourceLocation(),NULL,QualType(),None,NULL);
+ new ParmVarDecl(0, SourceLocation(),NULL,QualType(),None,NULL);
decl->VarDecl::ReadImpl(D);
decl->objcDeclQualifier = static_cast<ObjCDeclQualifier>(D.ReadInt());
@@ -245,7 +249,7 @@
}
EnumDecl* EnumDecl::CreateImpl(Deserializer& D) {
- EnumDecl* decl = new EnumDecl(SourceLocation(),NULL,NULL);
+ EnumDecl* decl = new EnumDecl(0, SourceLocation(),NULL,NULL);
decl->ScopedDecl::ReadInRec(D);
decl->setDefinition(D.ReadBool());
@@ -277,7 +281,7 @@
D.Read(val);
EnumConstantDecl* decl =
- new EnumConstantDecl(SourceLocation(),NULL,QualType(),NULL,
+ new EnumConstantDecl(0, SourceLocation(),NULL,QualType(),NULL,
val,NULL);
decl->ValueDecl::ReadInRec(D);
@@ -302,7 +306,7 @@
}
FieldDecl* FieldDecl::CreateImpl(Deserializer& D) {
- FieldDecl* decl = new FieldDecl(SourceLocation(), NULL, QualType(), 0);
+ FieldDecl* decl = new FieldDecl(0, SourceLocation(), NULL, QualType(), 0);
decl->DeclType.ReadBackpatch(D);
decl->ReadInRec(D);
decl->BitWidth = D.ReadOwnedPtr<Expr>();
@@ -338,7 +342,7 @@
bool IsInline = D.ReadBool();
FunctionDecl* decl =
- new FunctionDecl(SourceLocation(),NULL,QualType(),SClass, IsInline, 0);
+ new FunctionDecl(0, SourceLocation(),NULL,QualType(),SClass, IsInline, 0);
decl->ValueDecl::ReadInRec(D);
D.ReadPtr(decl->DeclChain);
@@ -382,7 +386,7 @@
}
RecordDecl* RecordDecl::CreateImpl(Decl::Kind DK, Deserializer& D) {
- RecordDecl* decl = new RecordDecl(DK,SourceLocation(),NULL,NULL);
+ RecordDecl* decl = new RecordDecl(DK,0,SourceLocation(),NULL,NULL);
decl->ScopedDecl::ReadInRec(D);
decl->setDefinition(D.ReadBool());
@@ -418,7 +422,7 @@
TypedefDecl* TypedefDecl::CreateImpl(Deserializer& D) {
QualType T = QualType::ReadVal(D);
- TypedefDecl* decl = new TypedefDecl(SourceLocation(),NULL,T,NULL);
+ TypedefDecl* decl = new TypedefDecl(0, SourceLocation(),NULL,T,NULL);
decl->ScopedDecl::ReadInRec(D);
decl->ScopedDecl::ReadOutRec(D);
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index da78ec0..9e379e4 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -59,7 +59,7 @@
TUScope->AddDecl(IDecl);
// Synthesize "typedef struct objc_selector *SEL;"
- RecordDecl *SelTag = RecordDecl::Create(Context, Decl::Struct,
+ RecordDecl *SelTag = RecordDecl::Create(Context, Decl::Struct, CurContext,
SourceLocation(),
&Context.Idents.get("objc_selector"),
0);
@@ -67,7 +67,8 @@
TUScope->AddDecl(SelTag);
QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag));
- TypedefDecl *SelTypedef = TypedefDecl::Create(Context, SourceLocation(),
+ TypedefDecl *SelTypedef = TypedefDecl::Create(Context, CurContext,
+ SourceLocation(),
&Context.Idents.get("SEL"),
SelT, 0);
SelTypedef->getIdentifier()->setFETokenInfo(SelTypedef);
@@ -77,7 +78,7 @@
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
: PP(pp), Context(ctxt), Consumer(consumer),
- CurFunctionDecl(0), CurMethodDecl(0) {
+ CurFunctionDecl(0), CurMethodDecl(0), CurContext(0) {
// Get IdentifierInfo objects for known functions for which we
// do extra checking.
@@ -99,11 +100,12 @@
if (PP.getLangOptions().ObjC1) {
// Synthesize "typedef struct objc_class *Class;"
RecordDecl *ClassTag = RecordDecl::Create(Context, Decl::Struct,
- SourceLocation(),
+ NULL,
+ SourceLocation(),
&IT.get("objc_class"), 0);
QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
TypedefDecl *ClassTypedef =
- TypedefDecl::Create(Context, SourceLocation(),
+ TypedefDecl::Create(Context, NULL, SourceLocation(),
&Context.Idents.get("Class"), ClassT, 0);
Context.setObjCClassType(ClassTypedef);
@@ -115,13 +117,16 @@
// Synthesize "typedef struct objc_object { Class isa; } *id;"
RecordDecl *ObjectTag =
- RecordDecl::Create(Context, Decl::Struct, SourceLocation(),
+ RecordDecl::Create(Context, Decl::Struct, NULL,
+ SourceLocation(),
&IT.get("objc_object"), 0);
- FieldDecl *IsaDecl = FieldDecl::Create(Context, SourceLocation(), 0,
+ FieldDecl *IsaDecl = FieldDecl::Create(Context, ObjectTag,
+ SourceLocation(), 0,
Context.getObjCClassType());
ObjectTag->defineBody(&IsaDecl, 1);
QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
- TypedefDecl *IdTypedef = TypedefDecl::Create(Context, SourceLocation(),
+ TypedefDecl *IdTypedef = TypedefDecl::Create(Context, NULL,
+ SourceLocation(),
&Context.Idents.get("id"),
ObjT, 0);
Context.setObjCIdType(IdTypedef);
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index d2ad5c5..b1d0499 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -32,6 +32,7 @@
class ASTConsumer;
class Preprocessor;
class Decl;
+ class ContextDecl;
class NamedDecl;
class ScopedDecl;
class Expr;
@@ -73,7 +74,9 @@
/// CurMethodDecl - If inside of a method body, this contains a pointer to
/// the method decl for the method being parsed.
ObjCMethodDecl *CurMethodDecl;
-
+
+ ContextDecl *CurContext;
+
/// LabelMap - This is a mapping from label identifiers to the LabelStmt for
/// it (which acts like the label decl in some ways). Forward referenced
/// labels have a LabelStmt created for them with a null location & SubStmt.
@@ -246,6 +249,10 @@
virtual void ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl,
DeclTy **Elements, unsigned NumElements);
private:
+ /// Set the current declaration context until it gets popped.
+ void PushContextDecl(ContextDecl *CD);
+ void PopContextDecl();
+
/// Subroutines of ActOnDeclarator().
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
ScopedDecl *LastDecl);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c9ea54f..6f0f351 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -40,6 +40,17 @@
return 0;
}
+void Sema::PushContextDecl(ContextDecl *CD) {
+ assert(CD->getParent() == CurContext &&
+ "The next ContextDecl should be directly contained in the current one.");
+ CurContext = CD;
+}
+
+void Sema::PopContextDecl() {
+ assert(CurContext && "ContextDecl imbalance!");
+ CurContext = CurContext->getParent();
+}
+
void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
if (S->decl_empty()) return;
assert((S->getFlags() & Scope::DeclScope) &&"Scope shouldn't contain decls!");
@@ -156,7 +167,8 @@
InitBuiltinVaListType();
QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context);
- FunctionDecl *New = FunctionDecl::Create(Context, SourceLocation(), II, R,
+ FunctionDecl *New = FunctionDecl::Create(Context, CurContext,
+ SourceLocation(), II, R,
FunctionDecl::Extern, false, 0);
// Find translation-unit scope to insert this function into.
@@ -744,7 +756,8 @@
}
bool isInline = D.getDeclSpec().isInlineSpecified();
- FunctionDecl *NewFD = FunctionDecl::Create(Context, D.getIdentifierLoc(),
+ FunctionDecl *NewFD = FunctionDecl::Create(Context, CurContext,
+ D.getIdentifierLoc(),
II, R, SC, isInline,
LastDeclarator);
// Handle attributes.
@@ -784,10 +797,12 @@
R.getAsString());
InvalidDecl = true;
}
- NewVD = FileVarDecl::Create(Context, D.getIdentifierLoc(), II, R, SC,
+ NewVD = FileVarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
+ II, R, SC,
LastDeclarator);
} else {
- NewVD = BlockVarDecl::Create(Context, D.getIdentifierLoc(), II, R, SC,
+ NewVD = BlockVarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
+ II, R, SC,
LastDeclarator);
}
// Handle attributes prior to checking for duplicates in MergeVarDecl
@@ -1000,7 +1015,8 @@
} else if (parmDeclType->isFunctionType())
parmDeclType = Context.getPointerType(parmDeclType);
- ParmVarDecl *New = ParmVarDecl::Create(Context, PI.IdentLoc, II, parmDeclType,
+ ParmVarDecl *New = ParmVarDecl::Create(Context, CurContext, PI.IdentLoc, II,
+ parmDeclType,
VarDecl::None, 0);
if (PI.InvalidType)
@@ -1060,6 +1076,7 @@
Decl *decl = static_cast<Decl*>(ActOnDeclarator(GlobalScope, D, 0));
FunctionDecl *FD = cast<FunctionDecl>(decl);
CurFunctionDecl = FD;
+ PushContextDecl(FD);
// Create Decl objects for each parameter, adding them to the FunctionDecl.
llvm::SmallVector<ParmVarDecl*, 16> Params;
@@ -1104,6 +1121,7 @@
MD->setBody((Stmt*)Body);
CurMethodDecl = 0;
}
+ PopContextDecl();
// Verify and clean out per-function state.
// Check goto/label use.
@@ -1173,7 +1191,8 @@
assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
// Scope manipulation handled by caller.
- TypedefDecl *NewTD = TypedefDecl::Create(Context, D.getIdentifierLoc(),
+ TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext,
+ D.getIdentifierLoc(),
D.getIdentifier(),
T, LastDeclarator);
if (D.getInvalidType())
@@ -1253,7 +1272,7 @@
case Decl::Enum:
// FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
// enum X { A, B, C } D; D should chain to X.
- New = EnumDecl::Create(Context, Loc, Name, 0);
+ New = EnumDecl::Create(Context, CurContext, Loc, Name, 0);
// If this is an undefined enum, warn.
if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum);
break;
@@ -1262,7 +1281,7 @@
case Decl::Class:
// FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
// struct X { int A; } D; D should chain to X.
- New = RecordDecl::Create(Context, Kind, Loc, Name, 0);
+ New = RecordDecl::Create(Context, Kind, CurContext, Loc, Name, 0);
break;
}
@@ -1326,8 +1345,8 @@
// FIXME: Chain fielddecls together.
FieldDecl *NewFD;
- if (isa<RecordDecl>(TagDecl))
- NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth);
+ if (RecordDecl *RD = dyn_cast<RecordDecl>(TagDecl))
+ NewFD = FieldDecl::Create(Context, RD, Loc, II, T, BitWidth);
else if (isa<ObjCInterfaceDecl>(TagDecl) ||
isa<ObjCImplementationDecl>(TagDecl) ||
isa<ObjCCategoryDecl>(TagDecl) ||
@@ -1335,7 +1354,7 @@
// properties can appear within a protocol.
// See corresponding FIXME in DeclObjC.h:ObjCPropertyDecl.
isa<ObjCProtocolDecl>(TagDecl))
- NewFD = ObjCIvarDecl::Create(Context, Loc, II, T);
+ NewFD = ObjCIvarDecl::Create(Context, dyn_cast<ObjCInterfaceDecl>(TagDecl), Loc, II, T);
else
assert(0 && "Sema::ActOnField(): Unknown TagDecl");
@@ -1515,7 +1534,7 @@
DeclTy *lastEnumConst,
SourceLocation IdLoc, IdentifierInfo *Id,
SourceLocation EqualLoc, ExprTy *val) {
- theEnumDecl = theEnumDecl; // silence unused warning.
+ EnumDecl *TheEnumDecl = cast<EnumDecl>(static_cast<Decl*>(theEnumDecl));
EnumConstantDecl *LastEnumConst =
cast_or_null<EnumConstantDecl>(static_cast<Decl*>(lastEnumConst));
Expr *Val = static_cast<Expr*>(val);
@@ -1576,7 +1595,8 @@
}
EnumConstantDecl *New =
- EnumConstantDecl::Create(Context, IdLoc, Id, EltTy, Val, EnumVal,
+ EnumConstantDecl::Create(Context, TheEnumDecl, IdLoc, Id, EltTy,
+ Val, EnumVal,
LastEnumConst);
// Register this decl in the current scope stack.
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 69a1022..6b9b9e2 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -33,6 +33,7 @@
// Allow all of Sema to see that we are entering a method definition.
CurMethodDecl = MDecl;
+ PushContextDecl(MDecl);
// Create Decl objects for each parameter, entrring them in the scope for
// binding to their use.
@@ -813,23 +814,6 @@
Diag(MethodLoc, diag::error_missing_method_context);
return 0;
}
- llvm::SmallVector<ParmVarDecl*, 16> Params;
-
- for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
- // FIXME: arg->AttrList must be stored too!
- QualType argType;
-
- if (ArgTypes[i])
- argType = QualType::getFromOpaquePtr(ArgTypes[i]);
- else
- argType = Context.getObjCIdType();
- ParmVarDecl* Param = ParmVarDecl::Create(Context, SourceLocation(/*FIXME*/),
- ArgNames[i], argType,
- VarDecl::None, 0);
- Param->setObjCDeclQualifier(
- CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
- Params.push_back(Param);
- }
QualType resultDeclType;
if (ReturnType)
@@ -845,6 +829,25 @@
ObjCMethodDecl::Optional :
ObjCMethodDecl::Required);
+ llvm::SmallVector<ParmVarDecl*, 16> Params;
+
+ for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
+ // FIXME: arg->AttrList must be stored too!
+ QualType argType;
+
+ if (ArgTypes[i])
+ argType = QualType::getFromOpaquePtr(ArgTypes[i]);
+ else
+ argType = Context.getObjCIdType();
+ ParmVarDecl* Param = ParmVarDecl::Create(Context, ObjCMethod,
+ SourceLocation(/*FIXME*/),
+ ArgNames[i], argType,
+ VarDecl::None, 0);
+ Param->setObjCDeclQualifier(
+ CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
+ Params.push_back(Param);
+ }
+
ObjCMethod->setMethodParams(&Params[0], Sel.getNumArgs());
ObjCMethod->setObjCDeclQualifier(
CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));