From 0ed844b04ea4387caa4e1cf3dc375d269657536b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 4 Apr 2008 06:12:32 +0000 Subject: [PATCH] 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 --- Driver/RewriteTest.cpp | 49 +++-- include/clang/AST/Decl.h | 299 ++++++++---------------------- include/clang/AST/DeclBase.h | 330 ++++++++++++++++++++++++++++++++++ include/clang/AST/DeclObjC.h | 43 +++-- lib/AST/ASTContext.cpp | 9 +- lib/AST/Decl.cpp | 97 +++++----- lib/AST/DeclObjC.cpp | 42 +++-- lib/AST/DeclSerialization.cpp | 24 +-- lib/Sema/Sema.cpp | 21 ++- lib/Sema/Sema.h | 9 +- lib/Sema/SemaDecl.cpp | 46 +++-- lib/Sema/SemaDeclObjC.cpp | 37 ++-- 12 files changed, 636 insertions(+), 370 deletions(-) create mode 100644 include/clang/AST/DeclBase.h diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp index c564576248..b7c65a5e2b 100644 --- a/Driver/RewriteTest.cpp +++ b/Driver/RewriteTest.cpp @@ -822,7 +822,7 @@ Stmt *RewriteTest::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { std::string RecName = clsDeclared->getIdentifier()->getName(); RecName += "_IMPL"; IdentifierInfo *II = &Context->Idents.get(RecName.c_str()); - RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, + RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, NULL, SourceLocation(), II, 0); assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); @@ -1581,7 +1581,8 @@ void RewriteTest::SynthSelGetUidFunctionDecl() { QualType getFuncType = Context->getFunctionType(Context->getObjCSelType(), &ArgTys[0], ArgTys.size(), false /*isVariadic*/); - SelGetUidFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), + SelGetUidFunctionDecl = FunctionDecl::Create(*Context, NULL, + SourceLocation(), SelGetUidIdent, getFuncType, FunctionDecl::Extern, false, 0); } @@ -1595,7 +1596,8 @@ void RewriteTest::SynthGetProtocolFunctionDecl() { QualType getFuncType = Context->getFunctionType(Context->getObjCProtoType(), &ArgTys[0], ArgTys.size(), false /*isVariadic*/); - GetProtocolFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), + GetProtocolFunctionDecl = FunctionDecl::Create(*Context, NULL, + SourceLocation(), SelGetProtoIdent, getFuncType, FunctionDecl::Extern, false, 0); } @@ -1622,7 +1624,8 @@ void RewriteTest::SynthSuperContructorFunctionDecl() { QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), false); - SuperContructorFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), + SuperContructorFunctionDecl = FunctionDecl::Create(*Context, NULL, + SourceLocation(), msgSendIdent, msgSendType, FunctionDecl::Extern, false, 0); } @@ -1640,7 +1643,8 @@ void RewriteTest::SynthMsgSendFunctionDecl() { QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), true /*isVariadic*/); - MsgSendFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), + MsgSendFunctionDecl = FunctionDecl::Create(*Context, NULL, + SourceLocation(), msgSendIdent, msgSendType, FunctionDecl::Extern, false, 0); } @@ -1649,7 +1653,8 @@ void RewriteTest::SynthMsgSendFunctionDecl() { void RewriteTest::SynthMsgSendSuperFunctionDecl() { IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper"); llvm::SmallVector ArgTys; - RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, SourceLocation(), + RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, NULL, + SourceLocation(), &Context->Idents.get("objc_super"), 0); QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); @@ -1660,7 +1665,8 @@ void RewriteTest::SynthMsgSendSuperFunctionDecl() { QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), true /*isVariadic*/); - MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), + MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, NULL, + SourceLocation(), msgSendIdent, msgSendType, FunctionDecl::Extern, false, 0); } @@ -1678,7 +1684,8 @@ void RewriteTest::SynthMsgSendStretFunctionDecl() { QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), true /*isVariadic*/); - MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), + MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, NULL, + SourceLocation(), msgSendIdent, msgSendType, FunctionDecl::Extern, false, 0); } @@ -1689,7 +1696,8 @@ void RewriteTest::SynthMsgSendSuperStretFunctionDecl() { IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper_stret"); llvm::SmallVector ArgTys; - RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, SourceLocation(), + RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, NULL, + SourceLocation(), &Context->Idents.get("objc_super"), 0); QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); @@ -1700,7 +1708,7 @@ void RewriteTest::SynthMsgSendSuperStretFunctionDecl() { QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), true /*isVariadic*/); - MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, + MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, NULL, SourceLocation(), msgSendIdent, msgSendType, FunctionDecl::Extern, false, 0); @@ -1719,7 +1727,8 @@ void RewriteTest::SynthMsgSendFpretFunctionDecl() { QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), true /*isVariadic*/); - MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), + MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, NULL, + SourceLocation(), msgSendIdent, msgSendType, FunctionDecl::Extern, false, 0); } @@ -1733,7 +1742,8 @@ void RewriteTest::SynthGetClassFunctionDecl() { QualType getClassType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), false /*isVariadic*/); - GetClassFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), + GetClassFunctionDecl = FunctionDecl::Create(*Context, NULL, + SourceLocation(), getClassIdent, getClassType, FunctionDecl::Extern, false, 0); } @@ -1747,7 +1757,8 @@ void RewriteTest::SynthGetMetaClassFunctionDecl() { QualType getClassType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), false /*isVariadic*/); - GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), + GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, NULL, + SourceLocation(), getClassIdent, getClassType, FunctionDecl::Extern, false, 0); } @@ -1769,7 +1780,7 @@ Stmt *RewriteTest::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { // The minus 2 removes the begin/end double quotes. Preamble += utostr(prettyBuf.str().size()-2) + "};\n"; - FileVarDecl *NewVD = FileVarDecl::Create(*Context, SourceLocation(), + FileVarDecl *NewVD = FileVarDecl::Create(*Context, NULL, SourceLocation(), &Context->Idents.get(S.c_str()), strType, VarDecl::Static, NULL); DeclRefExpr *DRE = new DeclRefExpr(NewVD, strType, SourceLocation()); @@ -1817,7 +1828,7 @@ ObjCInterfaceDecl *RewriteTest::isSuperReceiver(Expr *recExpr) { // struct objc_super { struct objc_object *receiver; struct objc_class *super; }; QualType RewriteTest::getSuperStructType() { if (!SuperStructDecl) { - SuperStructDecl = RecordDecl::Create(*Context, Decl::Struct, + SuperStructDecl = RecordDecl::Create(*Context, Decl::Struct, NULL, SourceLocation(), &Context->Idents.get("objc_super"), 0); QualType FieldTypes[2]; @@ -1830,7 +1841,8 @@ QualType RewriteTest::getSuperStructType() { FieldDecl *FieldDecls[2]; for (unsigned i = 0; i < 2; ++i) - FieldDecls[i] = FieldDecl::Create(*Context, SourceLocation(), 0, + FieldDecls[i] = FieldDecl::Create(*Context, SuperStructDecl, + SourceLocation(), 0, FieldTypes[i]); SuperStructDecl->defineBody(FieldDecls, 4); @@ -1840,7 +1852,7 @@ QualType RewriteTest::getSuperStructType() { QualType RewriteTest::getConstantStringStructType() { if (!ConstantStringDecl) { - ConstantStringDecl = RecordDecl::Create(*Context, Decl::Struct, + ConstantStringDecl = RecordDecl::Create(*Context, Decl::Struct, NULL, SourceLocation(), &Context->Idents.get("__NSConstantStringImpl"), 0); QualType FieldTypes[4]; @@ -1857,7 +1869,8 @@ QualType RewriteTest::getConstantStringStructType() { FieldDecl *FieldDecls[4]; for (unsigned i = 0; i < 4; ++i) - FieldDecls[i] = FieldDecl::Create(*Context, SourceLocation(), 0, + FieldDecls[i] = FieldDecl::Create(*Context, ConstantStringDecl, + SourceLocation(), 0, FieldTypes[i]); ConstantStringDecl->defineBody(FieldDecls, 4); diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 75b3ff7040..557a4a25c0 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -14,190 +14,14 @@ #ifndef LLVM_CLANG_AST_DECL_H #define LLVM_CLANG_AST_DECL_H -#include "clang/AST/Attr.h" -#include "clang/AST/Type.h" -#include "clang/Basic/SourceLocation.h" -#include "llvm/ADT/APSInt.h" -#include "llvm/Bitcode/SerializationFwd.h" - -namespace clang { -class Decl; -} +#include "clang/AST/DeclBase.h" namespace clang { class Expr; class Stmt; class StringLiteral; -class FunctionDecl; class IdentifierInfo; -/// Decl - This represents one declaration (or definition), e.g. a variable, -/// typedef, function, struct, etc. -/// -class Decl { -public: - enum Kind { - // This lists the concrete classes of Decl in order of the inheritance - // hierarchy. This allows us to do efficient classof tests based on the - // enums below. The commented out names are abstract class names. - - // Decl - // NamedDecl - Field, - ObjCIvar, - ObjCCategory, - ObjCCategoryImpl, - ObjCImplementation, - ObjCProtocol, - PropertyDecl, - // ScopedDecl - // TypeDecl - Typedef, - // TagDecl - Enum, - // RecordDecl - Struct, - Union, - Class, - // ValueDecl - EnumConstant, - Function, - // VarDecl - BlockVar, - FileVar, - ParmVar, - ObjCInterface, - ObjCCompatibleAlias, - ObjCMethod, - ObjCClass, - ObjCForwardProtocol, - LinkageSpec, - FileScopeAsm, - - // For each non-leaf class, we now define a mapping to the first/last member - // of the class, to allow efficient classof. - NamedFirst = Field, NamedLast = ParmVar, - FieldFirst = Field, FieldLast = ObjCIvar, - ScopedFirst = Typedef, ScopedLast = ParmVar, - TypeFirst = Typedef, TypeLast = Class, - TagFirst = Enum , TagLast = Class, - RecordFirst = Struct , RecordLast = Class, - ValueFirst = EnumConstant , ValueLast = ParmVar, - VarFirst = BlockVar , VarLast = ParmVar - }; - - /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces, - /// labels, tags, members and ordinary identifiers. - enum IdentifierNamespace { - IDNS_Label, - IDNS_Tag, - IDNS_Member, - IDNS_Ordinary - }; - - /// ObjCDeclQualifier - Qualifier used on types in method declarations - /// for remote messaging. They are meant for the arguments though and - /// applied to the Decls (ObjCMethodDecl and ParmVarDecl). - enum ObjCDeclQualifier { - OBJC_TQ_None = 0x0, - OBJC_TQ_In = 0x1, - OBJC_TQ_Inout = 0x2, - OBJC_TQ_Out = 0x4, - OBJC_TQ_Bycopy = 0x8, - OBJC_TQ_Byref = 0x10, - OBJC_TQ_Oneway = 0x20 - }; - -private: - /// Loc - The location that this decl. - SourceLocation Loc; - - /// DeclKind - This indicates which class this is. - Kind DeclKind : 8; - - /// InvalidDecl - This indicates a semantic error occurred. - unsigned int InvalidDecl : 1; - - /// HasAttrs - This indicates whether the decl has attributes or not. - unsigned int HasAttrs : 1; -protected: - Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0), - HasAttrs(false) { - if (Decl::CollectingStats()) addDeclKind(DK); - } - -public: - // TODO: This should probably be made protected once derived classes have - // destructors. - virtual ~Decl(); - - SourceLocation getLocation() const { return Loc; } - void setLocation(SourceLocation L) { Loc = L; } - - Kind getKind() const { return DeclKind; } - const char *getDeclKindName() const; - - void addAttr(Attr *attr); - const Attr *getAttrs() const; - - template const T *getAttr() const { - for (const Attr *attr = getAttrs(); attr; attr = attr->getNext()) - if (const T *V = dyn_cast(attr)) - return V; - - return 0; - } - - /// setInvalidDecl - Indicates the Decl had a semantic error. This - /// allows for graceful error recovery. - void setInvalidDecl() { InvalidDecl = 1; } - bool isInvalidDecl() const { return (bool) InvalidDecl; } - - IdentifierNamespace getIdentifierNamespace() const { - switch (DeclKind) { - default: assert(0 && "Unknown decl kind!"); - case Typedef: - case Function: - case BlockVar: - case FileVar: - case ParmVar: - case EnumConstant: - case ObjCInterface: - case ObjCCompatibleAlias: - return IDNS_Ordinary; - case Struct: - case Union: - case Class: - case Enum: - return IDNS_Tag; - } - } - // global temp stats (until we have a per-module visitor) - static void addDeclKind(Kind k); - static bool CollectingStats(bool Enable = false); - static void PrintStats(); - - // Implement isa/cast/dyncast/etc. - static bool classof(const Decl *) { return true; } - - /// Emit - Serialize this Decl to Bitcode. - void Emit(llvm::Serializer& S) const; - - /// Create - Deserialize a Decl from Bitcode. - static Decl* Create(llvm::Deserializer& D); - -protected: - /// EmitImpl - Provides the subclass-specific serialization logic for - /// serializing out a decl. - virtual void EmitImpl(llvm::Serializer& S) const { - // FIXME: This will eventually be a pure virtual function. - assert (false && "Not implemented."); - } - - void EmitInRec(llvm::Serializer& S) const; - void ReadInRec(llvm::Deserializer& D); -}; - /// NamedDecl - This represents a decl with an identifier for a name. Many /// decls have names, but not ObjCMethodDecl, @class, etc. class NamedDecl : public Decl { @@ -234,11 +58,16 @@ class ScopedDecl : public NamedDecl { /// ScopedDecl *Next; + ContextDecl *CtxDecl; + protected: - ScopedDecl(Kind DK, SourceLocation L, IdentifierInfo *Id,ScopedDecl *PrevDecl) - : NamedDecl(DK, L, Id), NextDeclarator(PrevDecl), Next(0) {} + ScopedDecl(Kind DK, ContextDecl *CD, SourceLocation L, + IdentifierInfo *Id, ScopedDecl *PrevDecl) + : NamedDecl(DK, L, Id), NextDeclarator(PrevDecl), Next(0), CtxDecl(CD) {} public: + ContextDecl *getContext() const { return CtxDecl; } + ScopedDecl *getNext() const { return Next; } void setNext(ScopedDecl *N) { Next = N; } @@ -253,8 +82,13 @@ public: // 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 isDefinedOutsideFunctionOrMethod() const; - + bool isDefinedOutsideFunctionOrMethod() const { + if (getContext()) + return !getContext()->isFunctionOrMethod(); + else + return true; + } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() >= ScopedFirst && D->getKind() <= ScopedLast; @@ -276,9 +110,9 @@ class ValueDecl : public ScopedDecl { QualType DeclType; protected: - ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T, - ScopedDecl *PrevDecl) - : ScopedDecl(DK, L, Id, PrevDecl), DeclType(T) {} + ValueDecl(Kind DK, ContextDecl *CD, SourceLocation L, + IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl) + : ScopedDecl(DK, CD, L, Id, PrevDecl), DeclType(T) {} public: QualType getType() const { return DeclType; } void setType(QualType newType) { DeclType = newType; } @@ -309,9 +143,9 @@ private: friend class StmtIteratorBase; protected: - VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T, + VarDecl(Kind DK, ContextDecl *CD, SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass SC, ScopedDecl *PrevDecl) - : ValueDecl(DK, L, Id, T, PrevDecl), Init(0) { SClass = SC; } + : ValueDecl(DK, CD, L, Id, T, PrevDecl), Init(0) { SClass = SC; } public: StorageClass getStorageClass() const { return (StorageClass)SClass; } @@ -362,11 +196,12 @@ protected: /// void foo() { int x; static int y; extern int z; } /// class BlockVarDecl : public VarDecl { - BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, + BlockVarDecl(ContextDecl *CD, SourceLocation L, + IdentifierInfo *Id, QualType T, StorageClass S, ScopedDecl *PrevDecl) - : VarDecl(BlockVar, L, Id, T, S, PrevDecl) {} + : VarDecl(BlockVar, CD, L, Id, T, S, PrevDecl) {} public: - static BlockVarDecl *Create(ASTContext &C, SourceLocation L, + static BlockVarDecl *Create(ASTContext &C, ContextDecl *CD, SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, ScopedDecl *PrevDecl); // Implement isa/cast/dyncast/etc. @@ -385,11 +220,13 @@ protected: /// definitions (C99 6.9.2p2) using our type system (without storing a /// pointer to the decl's scope, which is transient). class FileVarDecl : public VarDecl { - FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, + FileVarDecl(ContextDecl *CD, SourceLocation L, + IdentifierInfo *Id, QualType T, StorageClass S, ScopedDecl *PrevDecl) - : VarDecl(FileVar, L, Id, T, S, PrevDecl) {} + : VarDecl(FileVar, CD, L, Id, T, S, PrevDecl) {} public: - static FileVarDecl *Create(ASTContext &C, SourceLocation L,IdentifierInfo *Id, + static FileVarDecl *Create(ASTContext &C, ContextDecl *CD, + SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, ScopedDecl *PrevDecl); // Implement isa/cast/dyncast/etc. @@ -410,12 +247,14 @@ class ParmVarDecl : public VarDecl { /// in, inout, etc. unsigned objcDeclQualifier : 6; - ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, + ParmVarDecl(ContextDecl *CD, SourceLocation L, + IdentifierInfo *Id, QualType T, StorageClass S, ScopedDecl *PrevDecl) - : VarDecl(ParmVar, L, Id, T, S, PrevDecl), + : VarDecl(ParmVar, CD, L, Id, T, S, PrevDecl), objcDeclQualifier(OBJC_TQ_None) {} public: - static ParmVarDecl *Create(ASTContext &C, SourceLocation L,IdentifierInfo *Id, + static ParmVarDecl *Create(ASTContext &C, ContextDecl *CD, + SourceLocation L,IdentifierInfo *Id, QualType T, StorageClass S, ScopedDecl *PrevDecl); ObjCDeclQualifier getObjCDeclQualifier() const { @@ -440,7 +279,7 @@ protected: /// FunctionDecl - An instance of this class is created to represent a function /// declaration or definition. -class FunctionDecl : public ValueDecl { +class FunctionDecl : public ValueDecl, public ContextDecl { public: enum StorageClass { None, Extern, Static, PrivateExtern @@ -462,13 +301,15 @@ private: unsigned SClass : 2; bool IsInline : 1; - FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T, + FunctionDecl(ContextDecl *CD, SourceLocation L, + IdentifierInfo *Id, QualType T, StorageClass S, bool isInline, ScopedDecl *PrevDecl) - : ValueDecl(Function, L, Id, T, PrevDecl), + : ValueDecl(Function, CD, L, Id, T, PrevDecl), + ContextDecl(Function), ParamInfo(0), Body(0), DeclChain(0), SClass(S), IsInline(isInline) {} virtual ~FunctionDecl(); public: - static FunctionDecl *Create(ASTContext &C, SourceLocation L, + static FunctionDecl *Create(ASTContext &C, ContextDecl *CD, SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S = None, bool isInline = false, ScopedDecl *PrevDecl = 0); @@ -525,14 +366,18 @@ protected: class FieldDecl : public NamedDecl { QualType DeclType; Expr *BitWidth; + ContextDecl *CtxDecl; protected: - FieldDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T, + FieldDecl(Kind DK, ContextDecl *CD, + SourceLocation L, IdentifierInfo *Id, QualType T, Expr *BW = NULL) - : NamedDecl(DK, L, Id), DeclType(T), BitWidth(BW) {} - FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *BW) + : NamedDecl(DK, L, Id), DeclType(T), BitWidth(BW), CtxDecl(CD) {} + FieldDecl(RecordDecl *CD, SourceLocation L, + IdentifierInfo *Id, QualType T, Expr *BW) : NamedDecl(Field, L, Id), DeclType(T), BitWidth(BW) {} public: - static FieldDecl *Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id, + static FieldDecl *Create(ASTContext &C, RecordDecl *CD, + SourceLocation L, IdentifierInfo *Id, QualType T, Expr *BW = NULL); QualType getType() const { return DeclType; } @@ -540,6 +385,7 @@ public: bool isBitField() const { return BitWidth != NULL; } Expr *getBitWidth() const { return BitWidth; } + ContextDecl *getContextDecl() const { return CtxDecl; } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() >= FieldFirst && D->getKind() <= FieldLast; @@ -564,14 +410,16 @@ class EnumConstantDecl : public ValueDecl { Expr *Init; // an integer constant expression llvm::APSInt Val; // The value. protected: - EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, + EnumConstantDecl(ContextDecl *CD, SourceLocation L, + IdentifierInfo *Id, QualType T, Expr *E, const llvm::APSInt &V, ScopedDecl *PrevDecl) - : ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E), Val(V) {} + : ValueDecl(EnumConstant, CD, L, Id, T, PrevDecl), Init(E), Val(V) {} ~EnumConstantDecl() {} public: - static EnumConstantDecl *Create(ASTContext &C, SourceLocation L, - IdentifierInfo *Id, QualType T, Expr *E, + static EnumConstantDecl *Create(ASTContext &C, EnumDecl *CD, + SourceLocation L, IdentifierInfo *Id, + QualType T, Expr *E, const llvm::APSInt &V, ScopedDecl *PrevDecl); const Expr *getInitExpr() const { return Init; } @@ -607,8 +455,9 @@ class TypeDecl : public ScopedDecl { Type *TypeForDecl; friend class ASTContext; protected: - TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) - : ScopedDecl(DK, L, Id, PrevDecl), TypeForDecl(0) {} + TypeDecl(Kind DK, ContextDecl *CD, SourceLocation L, + IdentifierInfo *Id, ScopedDecl *PrevDecl) + : ScopedDecl(DK, CD, L, Id, PrevDecl), TypeForDecl(0) {} public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { @@ -621,12 +470,14 @@ public: class TypedefDecl : public TypeDecl { /// UnderlyingType - This is the type the typedef is set to. QualType UnderlyingType; - TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T, ScopedDecl *PD) - : TypeDecl(Typedef, L, Id, PD), UnderlyingType(T) {} + TypedefDecl(ContextDecl *CD, SourceLocation L, + IdentifierInfo *Id, QualType T, ScopedDecl *PD) + : TypeDecl(Typedef, CD, L, Id, PD), UnderlyingType(T) {} ~TypedefDecl() {} public: - static TypedefDecl *Create(ASTContext &C, SourceLocation L,IdentifierInfo *Id, + static TypedefDecl *Create(ASTContext &C, ContextDecl *CD, + SourceLocation L,IdentifierInfo *Id, QualType T, ScopedDecl *PD); QualType getUnderlyingType() const { return UnderlyingType; } @@ -648,13 +499,14 @@ protected: /// TagDecl - Represents the declaration of a struct/union/class/enum. -class TagDecl : public TypeDecl { +class TagDecl : public TypeDecl, public ContextDecl { /// IsDefinition - True if this is a definition ("struct foo {};"), false if /// it is a declaration ("struct foo;"). bool IsDefinition : 1; protected: - TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) - : TypeDecl(DK, L, Id, PrevDecl) { + TagDecl(Kind DK, ContextDecl *CD, SourceLocation L, + IdentifierInfo *Id, ScopedDecl *PrevDecl) + : TypeDecl(DK, CD, L, Id, PrevDecl), ContextDecl(DK) { IsDefinition = false; } public: @@ -695,13 +547,15 @@ class EnumDecl : public TagDecl { /// have a different type than this does. QualType IntegerType; - EnumDecl(SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) - : TagDecl(Enum, L, Id, PrevDecl) { + EnumDecl(ContextDecl *CD, SourceLocation L, + IdentifierInfo *Id, ScopedDecl *PrevDecl) + : TagDecl(Enum, CD, L, Id, PrevDecl) { ElementList = 0; IntegerType = QualType(); } public: - static EnumDecl *Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id, + static EnumDecl *Create(ASTContext &C, ContextDecl *CD, + SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl); /// defineElements - When created, EnumDecl correspond to a forward declared @@ -753,8 +607,8 @@ class RecordDecl : public TagDecl { FieldDecl **Members; // Null if not defined. int NumMembers; // -1 if not defined. - RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, - ScopedDecl *PrevDecl) : TagDecl(DK, L, Id, PrevDecl) { + RecordDecl(Kind DK, ContextDecl *CD, SourceLocation L, IdentifierInfo *Id, + ScopedDecl *PrevDecl) : TagDecl(DK, CD, L, Id, PrevDecl) { HasFlexibleArrayMember = false; assert(classof(static_cast(this)) && "Invalid Kind!"); Members = 0; @@ -762,8 +616,9 @@ class RecordDecl : public TagDecl { } public: - static RecordDecl *Create(ASTContext &C, Kind DK, SourceLocation L, - IdentifierInfo *Id, ScopedDecl *PrevDecl); + static RecordDecl *Create(ASTContext &C, Kind DK, ContextDecl *CD, + SourceLocation L, IdentifierInfo *Id, + ScopedDecl *PrevDecl); bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; } void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; } diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h new file mode 100644 index 0000000000..ae8fdc7d9b --- /dev/null +++ b/include/clang/AST/DeclBase.h @@ -0,0 +1,330 @@ +//===-- DeclBase.h - Base Classes for representing declarations *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the Decl and ContextDecl interfaces. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLBASE_H +#define LLVM_CLANG_AST_DECLBASE_H + +#include "clang/AST/Attr.h" +#include "clang/AST/Type.h" +#include "clang/Basic/SourceLocation.h" + +namespace clang { +class FunctionDecl; +class ObjCMethodDecl; +class TagDecl; +class ObjCInterfaceDecl; + +/// Decl - This represents one declaration (or definition), e.g. a variable, +/// typedef, function, struct, etc. +/// +class Decl { +public: + enum Kind { + // This lists the concrete classes of Decl in order of the inheritance + // hierarchy. This allows us to do efficient classof tests based on the + // enums below. The commented out names are abstract class names. + + // Decl + // NamedDecl + Field, + ObjCIvar, + ObjCCategory, + ObjCCategoryImpl, + ObjCImplementation, + ObjCProtocol, + PropertyDecl, + // ScopedDecl + // TypeDecl + Typedef, + // TagDecl + Enum, + // RecordDecl + Struct, + Union, + Class, + // ValueDecl + EnumConstant, + Function, + // VarDecl + BlockVar, + FileVar, + ParmVar, + ObjCInterface, + ObjCCompatibleAlias, + ObjCMethod, + ObjCClass, + ObjCForwardProtocol, + LinkageSpec, + FileScopeAsm, + + // For each non-leaf class, we now define a mapping to the first/last member + // of the class, to allow efficient classof. + NamedFirst = Field, NamedLast = ParmVar, + FieldFirst = Field, FieldLast = ObjCIvar, + ScopedFirst = Typedef, ScopedLast = ParmVar, + TypeFirst = Typedef, TypeLast = Class, + TagFirst = Enum , TagLast = Class, + RecordFirst = Struct , RecordLast = Class, + ValueFirst = EnumConstant , ValueLast = ParmVar, + VarFirst = BlockVar , VarLast = ParmVar + }; + + /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces, + /// labels, tags, members and ordinary identifiers. + enum IdentifierNamespace { + IDNS_Label, + IDNS_Tag, + IDNS_Member, + IDNS_Ordinary + }; + + /// ObjCDeclQualifier - Qualifier used on types in method declarations + /// for remote messaging. They are meant for the arguments though and + /// applied to the Decls (ObjCMethodDecl and ParmVarDecl). + enum ObjCDeclQualifier { + OBJC_TQ_None = 0x0, + OBJC_TQ_In = 0x1, + OBJC_TQ_Inout = 0x2, + OBJC_TQ_Out = 0x4, + OBJC_TQ_Bycopy = 0x8, + OBJC_TQ_Byref = 0x10, + OBJC_TQ_Oneway = 0x20 + }; + +private: + /// Loc - The location that this decl. + SourceLocation Loc; + + /// DeclKind - This indicates which class this is. + Kind DeclKind : 8; + + /// InvalidDecl - This indicates a semantic error occurred. + unsigned int InvalidDecl : 1; + + /// HasAttrs - This indicates whether the decl has attributes or not. + unsigned int HasAttrs : 1; +protected: + Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0), + HasAttrs(false) { + if (Decl::CollectingStats()) addDeclKind(DK); + } + +public: + // TODO: This should probably be made protected once derived classes have + // destructors. + virtual ~Decl(); + + SourceLocation getLocation() const { return Loc; } + void setLocation(SourceLocation L) { Loc = L; } + + Kind getKind() const { return DeclKind; } + const char *getDeclKindName() const; + + void addAttr(Attr *attr); + const Attr *getAttrs() const; + + template const T *getAttr() const { + for (const Attr *attr = getAttrs(); attr; attr = attr->getNext()) + if (const T *V = dyn_cast(attr)) + return V; + + return 0; + } + + /// setInvalidDecl - Indicates the Decl had a semantic error. This + /// allows for graceful error recovery. + void setInvalidDecl() { InvalidDecl = 1; } + bool isInvalidDecl() const { return (bool) InvalidDecl; } + + IdentifierNamespace getIdentifierNamespace() const { + switch (DeclKind) { + default: assert(0 && "Unknown decl kind!"); + case Typedef: + case Function: + case BlockVar: + case FileVar: + case ParmVar: + case EnumConstant: + case ObjCInterface: + case ObjCCompatibleAlias: + return IDNS_Ordinary; + case Struct: + case Union: + case Class: + case Enum: + return IDNS_Tag; + } + } + // global temp stats (until we have a per-module visitor) + static void addDeclKind(Kind k); + static bool CollectingStats(bool Enable = false); + static void PrintStats(); + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *) { return true; } + + /// Emit - Serialize this Decl to Bitcode. + void Emit(llvm::Serializer& S) const; + + /// Create - Deserialize a Decl from Bitcode. + static Decl* Create(llvm::Deserializer& D); + +protected: + /// EmitImpl - Provides the subclass-specific serialization logic for + /// serializing out a decl. + virtual void EmitImpl(llvm::Serializer& S) const { + // FIXME: This will eventually be a pure virtual function. + assert (false && "Not implemented."); + } + + void EmitInRec(llvm::Serializer& S) const; + void ReadInRec(llvm::Deserializer& D); +}; + +/// ContextDecl - This is used only as base class of specific decl types that +/// can act as declaration contexts. These decls are: +/// +/// FunctionDecl +/// ObjCMethodDecl +/// TagDecl +/// ObjCInterfaceDecl +/// +class ContextDecl { + /// DeclKind - This indicates which class this is. + Decl::Kind DeclKind : 8; + + // Used in the CastTo template to get the DeclKind + // from a Decl or a ContextDecl. ContextDecl doesn't have a getKind() method + // to avoid 'ambiguous access' compiler errors. + template struct KindTrait { + static Decl::Kind getKind(const T *D) { return D->getKind(); } + }; + + // Used only by the ToDecl and FromDecl methods + template + static To *CastTo(const From *D) { + Decl::Kind DK = KindTrait::getKind(D); + switch(DK) { + case Decl::Function: + return static_cast(const_cast(D)); + case Decl::ObjCMethod: + return static_cast(const_cast(D)); + case Decl::ObjCInterface: + return static_cast(const_cast(D)); + default: + // check for TagDecl + if (DK >= Decl::TagFirst && DK <= Decl::TagLast) + return static_cast(const_cast(D)); + + assert(false && "a decl that inherits ContextDecl isn't handled"); + return 0; + } + } + +protected: + ContextDecl(Decl::Kind K) : DeclKind(K) {} + +public: + /// getParent - Returns the containing ContextDecl if this is a ScopedDecl, + /// else returns NULL. + ContextDecl *getParent() const; + + bool isFunctionOrMethod() const { + switch (DeclKind) { + case Decl::Function: + case Decl::ObjCMethod: + return true; + default: + return false; + } + } + + /// ToDecl and FromDecl make Decl <-> ContextDecl castings. + /// They are intended to be used by the simplify_type and cast_convert_val + /// templates. + static Decl *ToDecl (const ContextDecl *D); + static ContextDecl *FromDecl (const Decl *D); + + static bool classof(const Decl *D) { + switch (D->getKind()) { + case Decl::Function: + case Decl::ObjCMethod: + case Decl::ObjCInterface: + return true; + default: + // check for TagDecl + return D->getKind() >= Decl::TagFirst && + D->getKind() <= Decl::TagLast; + } + } + static bool classof(const ContextDecl *D) { return true; } + static bool classof(const FunctionDecl *D) { return true; } + static bool classof(const ObjCMethodDecl *D) { return true; } + static bool classof(const TagDecl *D) { return true; } + static bool classof(const ObjCInterfaceDecl *D) { return true; } +}; + +template<> struct ContextDecl::KindTrait { + static Decl::Kind getKind(const ContextDecl *D) { return D->DeclKind; } +}; + +} // end clang. + +namespace llvm { +/// Implement simplify_type for ContextDecl, so that we can dyn_cast from +/// ContextDecl to a specific Decl class. + template<> struct simplify_type { + typedef ::clang::Decl* SimpleType; + static SimpleType getSimplifiedValue(const ::clang::ContextDecl *Val) { + return ::clang::ContextDecl::ToDecl(Val); + } +}; +template<> struct simplify_type< ::clang::ContextDecl*> + : public simplify_type {}; + +template<> struct simplify_type { + typedef ::clang::Decl SimpleType; + static SimpleType &getSimplifiedValue(const ::clang::ContextDecl &Val) { + return *::clang::ContextDecl::ToDecl(&Val); + } +}; +template<> struct simplify_type< ::clang::ContextDecl> + : public simplify_type {}; + +/// Implement cast_convert_val for ContextDecl, so that we can dyn_cast from +/// a Decl class to ContextDecl. +template +struct cast_convert_val< ::clang::ContextDecl,const FromTy,const FromTy> { + static ::clang::ContextDecl &doit(const FromTy &Val) { + return *::clang::ContextDecl::FromDecl(&Val); + } +}; +template +struct cast_convert_val< ::clang::ContextDecl,FromTy,FromTy> + : public cast_convert_val< ::clang::ContextDecl,const FromTy,const FromTy> + {}; + +template +struct cast_convert_val< ::clang::ContextDecl,const FromTy*,const FromTy*> { + static ::clang::ContextDecl *doit(const FromTy *Val) { + return ::clang::ContextDecl::FromDecl(Val); + } +}; +template +struct cast_convert_val< ::clang::ContextDecl,FromTy*,FromTy*> + : public cast_convert_val< ::clang::ContextDecl,const FromTy*,const FromTy*> + {}; + +} // end namespace llvm + +#endif diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 7f4a9752a5..d225093456 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -48,7 +48,7 @@ class ObjCPropertyDecl; /// A selector represents a unique name for a method. The selector names for /// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu. /// -class ObjCMethodDecl : public Decl { +class ObjCMethodDecl : public Decl, public ContextDecl { public: enum ImplementationControl { None, Required, Optional }; private: @@ -96,6 +96,7 @@ private: bool isVariadic = false, ImplementationControl impControl = None) : Decl(ObjCMethod, beginLoc), + ContextDecl(ObjCMethod), IsInstance(isInstance), IsVariadic(isVariadic), DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), MethodContext(static_cast(contextDecl)), @@ -105,7 +106,8 @@ private: virtual ~ObjCMethodDecl(); public: - static ObjCMethodDecl *Create(ASTContext &C, SourceLocation beginLoc, + static ObjCMethodDecl *Create(ASTContext &C, + SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, Decl *contextDecl, AttributeList *M = 0, bool isInstance = true, @@ -191,7 +193,7 @@ public: /// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes /// typically inherit from NSObject (an exception is NSProxy). /// -class ObjCInterfaceDecl : public NamedDecl { +class ObjCInterfaceDecl : public NamedDecl, public ContextDecl { /// TypeForDecl - This indicates the Type object that represents this /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType Type *TypeForDecl; @@ -229,9 +231,11 @@ class ObjCInterfaceDecl : public NamedDecl { SourceLocation EndLoc; // marks the '>', '}', or identifier. SourceLocation AtEndLoc; // marks the end of the entire interface. - ObjCInterfaceDecl(SourceLocation atLoc, unsigned numRefProtos, + ObjCInterfaceDecl(SourceLocation atLoc, + unsigned numRefProtos, IdentifierInfo *Id, bool FD, bool isInternal) - : NamedDecl(ObjCInterface, atLoc, Id), TypeForDecl(0), SuperClass(0), + : NamedDecl(ObjCInterface, atLoc, Id), ContextDecl(ObjCInterface), + TypeForDecl(0), SuperClass(0), ReferencedProtocols(0), NumReferencedProtocols(0), Ivars(0), NumIvars(0), InstanceMethods(0), NumInstanceMethods(0), @@ -242,7 +246,8 @@ class ObjCInterfaceDecl : public NamedDecl { } public: - static ObjCInterfaceDecl *Create(ASTContext &C, SourceLocation atLoc, + static ObjCInterfaceDecl *Create(ASTContext &C, + SourceLocation atLoc, unsigned numRefProtos, IdentifierInfo *Id, bool ForwardDecl = false, bool isInternal = false); @@ -371,10 +376,12 @@ public: /// } /// class ObjCIvarDecl : public FieldDecl { - ObjCIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T) - : FieldDecl(ObjCIvar, L, Id, T) {} + ObjCIvarDecl(ContextDecl *CD, SourceLocation L, + IdentifierInfo *Id, QualType T) + : FieldDecl(ObjCIvar, CD, L, Id, T) {} public: - static ObjCIvarDecl *Create(ASTContext &C, SourceLocation L, + static ObjCIvarDecl *Create(ASTContext &C, ObjCInterfaceDecl *CD, + SourceLocation L, IdentifierInfo *Id, QualType T); enum AccessControl { @@ -559,7 +566,7 @@ class ObjCForwardProtocolDecl : public Decl { ObjCProtocolDecl **ReferencedProtocols; unsigned NumReferencedProtocols; - ObjCForwardProtocolDecl(SourceLocation L, + ObjCForwardProtocolDecl(SourceLocation L, ObjCProtocolDecl **Elts, unsigned nElts) : Decl(ObjCForwardProtocol, L) { NumReferencedProtocols = nElts; @@ -645,8 +652,8 @@ class ObjCCategoryDecl : public NamedDecl { } public: - static ObjCCategoryDecl *Create(ASTContext &C, SourceLocation L, - IdentifierInfo *Id); + static ObjCCategoryDecl *Create(ASTContext &C, + SourceLocation L, IdentifierInfo *Id); ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; } @@ -735,8 +742,8 @@ class ObjCCategoryImplDecl : public NamedDecl { ObjCInterfaceDecl *classInterface) : NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {} public: - static ObjCCategoryImplDecl *Create(ASTContext &C, SourceLocation L, - IdentifierInfo *Id, + static ObjCCategoryImplDecl *Create(ASTContext &C, + SourceLocation L, IdentifierInfo *Id, ObjCInterfaceDecl *classInterface); ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } @@ -817,8 +824,8 @@ class ObjCImplementationDecl : public NamedDecl { ClassInterface(classInterface), SuperClass(superDecl), Ivars(0), NumIvars(0) {} public: - static ObjCImplementationDecl *Create(ASTContext &C, SourceLocation L, - IdentifierInfo *Id, + static ObjCImplementationDecl *Create(ASTContext &C, + SourceLocation L, IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, ObjCInterfaceDecl *superDecl); @@ -883,8 +890,8 @@ class ObjCCompatibleAliasDecl : public NamedDecl { ObjCInterfaceDecl* aliasedClass) : NamedDecl(ObjCCompatibleAlias, L, Id), AliasedClass(aliasedClass) {} public: - static ObjCCompatibleAliasDecl *Create(ASTContext &C, SourceLocation L, - IdentifierInfo *Id, + static ObjCCompatibleAliasDecl *Create(ASTContext &C, + SourceLocation L, IdentifierInfo *Id, ObjCInterfaceDecl* aliasedClass); const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index ce75122b3d..9e51b292fb 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1115,7 +1115,7 @@ QualType ASTContext::maxIntegerType(QualType lhs, QualType rhs) { 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 @@ QualType ASTContext::getCFConstantStringType() { 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 @@ ASTContext* ASTContext::Create(llvm::Deserializer& D) { TargetInfo &t = D.ReadRef(); IdentifierTable &idents = D.ReadRef(); SelectorTable &sels = D.ReadRef(); - + 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(); return A; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 3e7d83826e..38a20c1c01 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -204,77 +204,87 @@ void Decl::addDeclKind(Kind k) { // 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); 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(); return new (Mem) LinkageSpecDecl(L, Lang, D); @@ -319,6 +329,25 @@ const Attr *Decl::getAttrs() const { return (*DeclAttrs)[this]; } +//===----------------------------------------------------------------------===// +// ContextDecl Implementation +//===----------------------------------------------------------------------===// + +ContextDecl *ContextDecl::getParent() const { + if (ScopedDecl *SD = dyn_cast(this)) + return SD->getContext(); + else + return NULL; +} + +Decl *ContextDecl::ToDecl (const ContextDecl *D) { + return CastTo(D); +} + +ContextDecl *ContextDecl::FromDecl (const Decl *D) { + return CastTo(D); +} + //===----------------------------------------------------------------------===// // NamedDecl Implementation //===----------------------------------------------------------------------===// @@ -329,28 +358,6 @@ const char *NamedDecl::getName() const { return ""; } -//===----------------------------------------------------------------------===// -// 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(this)) - return VD->hasGlobalStorage(); - if (isa(this)) - return true; - - // FIXME: This needs to check the context the decl was defined in! - if (isa(this) || isa(this)) - return true; - - assert(0 && "Unknown ScopedDecl!"); - return false; -} - //===----------------------------------------------------------------------===// // FunctionDecl Implementation //===----------------------------------------------------------------------===// diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 2e3a06a956..a01c3042d3 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -19,7 +19,8 @@ using namespace clang; // 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 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, SourceLocation beginLoc, bool isVariadic, ImplementationControl impControl) { void *Mem = C.getAllocator().Allocate(); - 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(); - 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(); - 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(); 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(); 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(); 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(); 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(); 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 @@ ObjCImplementationDecl::Create(ASTContext &C, SourceLocation L, } ObjCCompatibleAliasDecl * -ObjCCompatibleAliasDecl::Create(ASTContext &C, SourceLocation L, +ObjCCompatibleAliasDecl::Create(ASTContext &C, + SourceLocation L, IdentifierInfo *Id, ObjCInterfaceDecl* AliasedClass) { void *Mem = C.getAllocator().Allocate(); 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(); return new (Mem) ObjCPropertyDecl(L); } @@ -431,3 +444,4 @@ void ObjCPropertyDecl::setPropertyDeclLists(ObjCIvarDecl **Properties, } + diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp index fe2ccefdce..3a79b9e0e2 100644 --- a/lib/AST/DeclSerialization.cpp +++ b/lib/AST/DeclSerialization.cpp @@ -39,7 +39,7 @@ Decl* Decl::Create(Deserializer& D) { default: assert (false && "Not implemented."); break; - + case BlockVar: return BlockVarDecl::CreateImpl(D); @@ -106,11 +106,15 @@ void NamedDecl::ReadInRec(Deserializer& D) { void ScopedDecl::EmitInRec(Serializer& S) const { NamedDecl::EmitInRec(S); S.EmitPtr(getNext()); // From ScopedDecl. + S.EmitPtr(cast_or_null(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(TmpD); } //===------------------------------------------------------------===// @@ -194,7 +198,7 @@ void VarDecl::ReadImpl(Deserializer& D) { 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 @@ BlockVarDecl* BlockVarDecl::CreateImpl(Deserializer& D) { 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 @@ void ParmVarDecl::EmitImpl(llvm::Serializer& S) const { 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(D.ReadInt()); @@ -245,7 +249,7 @@ void EnumDecl::EmitImpl(Serializer& S) const { } 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 @@ EnumConstantDecl* EnumConstantDecl::CreateImpl(Deserializer& D) { 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 @@ void FieldDecl::EmitImpl(Serializer& S) const { } 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(); @@ -338,7 +342,7 @@ FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D) { 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 @@ void RecordDecl::EmitImpl(Serializer& S) const { } 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 @@ void TypedefDecl::EmitImpl(Serializer& S) const { 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 da78ec0678..9e379e4be7 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -59,7 +59,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { 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 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { 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 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { 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 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer) 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 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer) // 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 d2ad5c5f75..b1d0499d13 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -32,6 +32,7 @@ namespace clang { class ASTConsumer; class Preprocessor; class Decl; + class ContextDecl; class NamedDecl; class ScopedDecl; class Expr; @@ -73,7 +74,9 @@ class Sema : public Action { /// 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 @@ private: 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 c9ea54fa0e..6f0f351000 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -40,6 +40,17 @@ Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) { 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 @@ ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, 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 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { } 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 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { 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 @@ Sema::ActOnParamDeclarator(struct DeclaratorChunk::ParamInfo &PI, } 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 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { Decl *decl = static_cast(ActOnDeclarator(GlobalScope, D, 0)); FunctionDecl *FD = cast(decl); CurFunctionDecl = FD; + PushContextDecl(FD); // Create Decl objects for each parameter, adding them to the FunctionDecl. llvm::SmallVector Params; @@ -1104,6 +1121,7 @@ Sema::DeclTy *Sema::ActOnFinishFunctionBody(DeclTy *D, StmtTy *Body) { MD->setBody((Stmt*)Body); CurMethodDecl = 0; } + PopContextDecl(); // Verify and clean out per-function state. // Check goto/label use. @@ -1173,7 +1191,8 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, 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 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK, 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 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK, 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 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *tagDecl, // FIXME: Chain fielddecls together. FieldDecl *NewFD; - if (isa(TagDecl)) - NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth); + if (RecordDecl *RD = dyn_cast(TagDecl)) + NewFD = FieldDecl::Create(Context, RD, Loc, II, T, BitWidth); else if (isa(TagDecl) || isa(TagDecl) || isa(TagDecl) || @@ -1335,7 +1354,7 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *tagDecl, // properties can appear within a protocol. // See corresponding FIXME in DeclObjC.h:ObjCPropertyDecl. isa(TagDecl)) - NewFD = ObjCIvarDecl::Create(Context, Loc, II, T); + NewFD = ObjCIvarDecl::Create(Context, dyn_cast(TagDecl), Loc, II, T); else assert(0 && "Sema::ActOnField(): Unknown TagDecl"); @@ -1515,7 +1534,7 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl, DeclTy *lastEnumConst, SourceLocation IdLoc, IdentifierInfo *Id, SourceLocation EqualLoc, ExprTy *val) { - theEnumDecl = theEnumDecl; // silence unused warning. + EnumDecl *TheEnumDecl = cast(static_cast(theEnumDecl)); EnumConstantDecl *LastEnumConst = cast_or_null(static_cast(lastEnumConst)); Expr *Val = static_cast(val); @@ -1576,7 +1595,8 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl, } 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 69a102203f..6b9b9e2d43 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -33,6 +33,7 @@ void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) { // 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 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( Diag(MethodLoc, diag::error_missing_method_context); return 0; } - llvm::SmallVector 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 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( ObjCMethodDecl::Optional : ObjCMethodDecl::Required); + llvm::SmallVector 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()));