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
This commit is contained in:
Chris Lattner 2008-04-04 06:12:32 +00:00
Родитель c8aa5f1f26
Коммит 0ed844b04e
12 изменённых файлов: 636 добавлений и 370 удалений

Просмотреть файл

@ -822,7 +822,7 @@ Stmt *RewriteTest::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
std::string RecName = clsDeclared->getIdentifier()->getName(); std::string RecName = clsDeclared->getIdentifier()->getName();
RecName += "_IMPL"; RecName += "_IMPL";
IdentifierInfo *II = &Context->Idents.get(RecName.c_str()); 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); SourceLocation(), II, 0);
assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl"); assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
@ -1581,7 +1581,8 @@ void RewriteTest::SynthSelGetUidFunctionDecl() {
QualType getFuncType = Context->getFunctionType(Context->getObjCSelType(), QualType getFuncType = Context->getFunctionType(Context->getObjCSelType(),
&ArgTys[0], ArgTys.size(), &ArgTys[0], ArgTys.size(),
false /*isVariadic*/); false /*isVariadic*/);
SelGetUidFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), SelGetUidFunctionDecl = FunctionDecl::Create(*Context, NULL,
SourceLocation(),
SelGetUidIdent, getFuncType, SelGetUidIdent, getFuncType,
FunctionDecl::Extern, false, 0); FunctionDecl::Extern, false, 0);
} }
@ -1595,7 +1596,8 @@ void RewriteTest::SynthGetProtocolFunctionDecl() {
QualType getFuncType = Context->getFunctionType(Context->getObjCProtoType(), QualType getFuncType = Context->getFunctionType(Context->getObjCProtoType(),
&ArgTys[0], ArgTys.size(), &ArgTys[0], ArgTys.size(),
false /*isVariadic*/); false /*isVariadic*/);
GetProtocolFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), GetProtocolFunctionDecl = FunctionDecl::Create(*Context, NULL,
SourceLocation(),
SelGetProtoIdent, getFuncType, SelGetProtoIdent, getFuncType,
FunctionDecl::Extern, false, 0); FunctionDecl::Extern, false, 0);
} }
@ -1622,7 +1624,8 @@ void RewriteTest::SynthSuperContructorFunctionDecl() {
QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(), &ArgTys[0], ArgTys.size(),
false); false);
SuperContructorFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), SuperContructorFunctionDecl = FunctionDecl::Create(*Context, NULL,
SourceLocation(),
msgSendIdent, msgSendType, msgSendIdent, msgSendType,
FunctionDecl::Extern, false, 0); FunctionDecl::Extern, false, 0);
} }
@ -1640,7 +1643,8 @@ void RewriteTest::SynthMsgSendFunctionDecl() {
QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(), &ArgTys[0], ArgTys.size(),
true /*isVariadic*/); true /*isVariadic*/);
MsgSendFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), MsgSendFunctionDecl = FunctionDecl::Create(*Context, NULL,
SourceLocation(),
msgSendIdent, msgSendType, msgSendIdent, msgSendType,
FunctionDecl::Extern, false, 0); FunctionDecl::Extern, false, 0);
} }
@ -1649,7 +1653,8 @@ void RewriteTest::SynthMsgSendFunctionDecl() {
void RewriteTest::SynthMsgSendSuperFunctionDecl() { void RewriteTest::SynthMsgSendSuperFunctionDecl() {
IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper"); IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
llvm::SmallVector<QualType, 16> ArgTys; llvm::SmallVector<QualType, 16> ArgTys;
RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, SourceLocation(), RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, NULL,
SourceLocation(),
&Context->Idents.get("objc_super"), 0); &Context->Idents.get("objc_super"), 0);
QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
@ -1660,7 +1665,8 @@ void RewriteTest::SynthMsgSendSuperFunctionDecl() {
QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(), &ArgTys[0], ArgTys.size(),
true /*isVariadic*/); true /*isVariadic*/);
MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, NULL,
SourceLocation(),
msgSendIdent, msgSendType, msgSendIdent, msgSendType,
FunctionDecl::Extern, false, 0); FunctionDecl::Extern, false, 0);
} }
@ -1678,7 +1684,8 @@ void RewriteTest::SynthMsgSendStretFunctionDecl() {
QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(), &ArgTys[0], ArgTys.size(),
true /*isVariadic*/); true /*isVariadic*/);
MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, NULL,
SourceLocation(),
msgSendIdent, msgSendType, msgSendIdent, msgSendType,
FunctionDecl::Extern, false, 0); FunctionDecl::Extern, false, 0);
} }
@ -1689,7 +1696,8 @@ void RewriteTest::SynthMsgSendSuperStretFunctionDecl() {
IdentifierInfo *msgSendIdent = IdentifierInfo *msgSendIdent =
&Context->Idents.get("objc_msgSendSuper_stret"); &Context->Idents.get("objc_msgSendSuper_stret");
llvm::SmallVector<QualType, 16> ArgTys; llvm::SmallVector<QualType, 16> ArgTys;
RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, SourceLocation(), RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, NULL,
SourceLocation(),
&Context->Idents.get("objc_super"), 0); &Context->Idents.get("objc_super"), 0);
QualType argT = Context->getPointerType(Context->getTagDeclType(RD)); QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
assert(!argT.isNull() && "Can't build 'struct objc_super *' type"); assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
@ -1700,7 +1708,7 @@ void RewriteTest::SynthMsgSendSuperStretFunctionDecl() {
QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(), &ArgTys[0], ArgTys.size(),
true /*isVariadic*/); true /*isVariadic*/);
MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, NULL,
SourceLocation(), SourceLocation(),
msgSendIdent, msgSendType, msgSendIdent, msgSendType,
FunctionDecl::Extern, false, 0); FunctionDecl::Extern, false, 0);
@ -1719,7 +1727,8 @@ void RewriteTest::SynthMsgSendFpretFunctionDecl() {
QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(), &ArgTys[0], ArgTys.size(),
true /*isVariadic*/); true /*isVariadic*/);
MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, NULL,
SourceLocation(),
msgSendIdent, msgSendType, msgSendIdent, msgSendType,
FunctionDecl::Extern, false, 0); FunctionDecl::Extern, false, 0);
} }
@ -1733,7 +1742,8 @@ void RewriteTest::SynthGetClassFunctionDecl() {
QualType getClassType = Context->getFunctionType(Context->getObjCIdType(), QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(), &ArgTys[0], ArgTys.size(),
false /*isVariadic*/); false /*isVariadic*/);
GetClassFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), GetClassFunctionDecl = FunctionDecl::Create(*Context, NULL,
SourceLocation(),
getClassIdent, getClassType, getClassIdent, getClassType,
FunctionDecl::Extern, false, 0); FunctionDecl::Extern, false, 0);
} }
@ -1747,7 +1757,8 @@ void RewriteTest::SynthGetMetaClassFunctionDecl() {
QualType getClassType = Context->getFunctionType(Context->getObjCIdType(), QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(), &ArgTys[0], ArgTys.size(),
false /*isVariadic*/); false /*isVariadic*/);
GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, NULL,
SourceLocation(),
getClassIdent, getClassType, getClassIdent, getClassType,
FunctionDecl::Extern, false, 0); FunctionDecl::Extern, false, 0);
} }
@ -1769,7 +1780,7 @@ Stmt *RewriteTest::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
// The minus 2 removes the begin/end double quotes. // The minus 2 removes the begin/end double quotes.
Preamble += utostr(prettyBuf.str().size()-2) + "};\n"; 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, &Context->Idents.get(S.c_str()), strType,
VarDecl::Static, NULL); VarDecl::Static, NULL);
DeclRefExpr *DRE = new DeclRefExpr(NewVD, strType, SourceLocation()); 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; }; // struct objc_super { struct objc_object *receiver; struct objc_class *super; };
QualType RewriteTest::getSuperStructType() { QualType RewriteTest::getSuperStructType() {
if (!SuperStructDecl) { if (!SuperStructDecl) {
SuperStructDecl = RecordDecl::Create(*Context, Decl::Struct, SuperStructDecl = RecordDecl::Create(*Context, Decl::Struct, NULL,
SourceLocation(), SourceLocation(),
&Context->Idents.get("objc_super"), 0); &Context->Idents.get("objc_super"), 0);
QualType FieldTypes[2]; QualType FieldTypes[2];
@ -1830,7 +1841,8 @@ QualType RewriteTest::getSuperStructType() {
FieldDecl *FieldDecls[2]; FieldDecl *FieldDecls[2];
for (unsigned i = 0; i < 2; ++i) for (unsigned i = 0; i < 2; ++i)
FieldDecls[i] = FieldDecl::Create(*Context, SourceLocation(), 0, FieldDecls[i] = FieldDecl::Create(*Context, SuperStructDecl,
SourceLocation(), 0,
FieldTypes[i]); FieldTypes[i]);
SuperStructDecl->defineBody(FieldDecls, 4); SuperStructDecl->defineBody(FieldDecls, 4);
@ -1840,7 +1852,7 @@ QualType RewriteTest::getSuperStructType() {
QualType RewriteTest::getConstantStringStructType() { QualType RewriteTest::getConstantStringStructType() {
if (!ConstantStringDecl) { if (!ConstantStringDecl) {
ConstantStringDecl = RecordDecl::Create(*Context, Decl::Struct, ConstantStringDecl = RecordDecl::Create(*Context, Decl::Struct, NULL,
SourceLocation(), SourceLocation(),
&Context->Idents.get("__NSConstantStringImpl"), 0); &Context->Idents.get("__NSConstantStringImpl"), 0);
QualType FieldTypes[4]; QualType FieldTypes[4];
@ -1857,7 +1869,8 @@ QualType RewriteTest::getConstantStringStructType() {
FieldDecl *FieldDecls[4]; FieldDecl *FieldDecls[4];
for (unsigned i = 0; i < 4; ++i) for (unsigned i = 0; i < 4; ++i)
FieldDecls[i] = FieldDecl::Create(*Context, SourceLocation(), 0, FieldDecls[i] = FieldDecl::Create(*Context, ConstantStringDecl,
SourceLocation(), 0,
FieldTypes[i]); FieldTypes[i]);
ConstantStringDecl->defineBody(FieldDecls, 4); ConstantStringDecl->defineBody(FieldDecls, 4);

Просмотреть файл

@ -14,190 +14,14 @@
#ifndef LLVM_CLANG_AST_DECL_H #ifndef LLVM_CLANG_AST_DECL_H
#define LLVM_CLANG_AST_DECL_H #define LLVM_CLANG_AST_DECL_H
#include "clang/AST/Attr.h" #include "clang/AST/DeclBase.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;
}
namespace clang { namespace clang {
class Expr; class Expr;
class Stmt; class Stmt;
class StringLiteral; class StringLiteral;
class FunctionDecl;
class IdentifierInfo; 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<typename T> const T *getAttr() const {
for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
if (const T *V = dyn_cast<T>(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 /// NamedDecl - This represents a decl with an identifier for a name. Many
/// decls have names, but not ObjCMethodDecl, @class, etc. /// decls have names, but not ObjCMethodDecl, @class, etc.
class NamedDecl : public Decl { class NamedDecl : public Decl {
@ -234,11 +58,16 @@ class ScopedDecl : public NamedDecl {
/// ///
ScopedDecl *Next; ScopedDecl *Next;
ContextDecl *CtxDecl;
protected: protected:
ScopedDecl(Kind DK, SourceLocation L, IdentifierInfo *Id,ScopedDecl *PrevDecl) ScopedDecl(Kind DK, ContextDecl *CD, SourceLocation L,
: NamedDecl(DK, L, Id), NextDeclarator(PrevDecl), Next(0) {} IdentifierInfo *Id, ScopedDecl *PrevDecl)
: NamedDecl(DK, L, Id), NextDeclarator(PrevDecl), Next(0), CtxDecl(CD) {}
public: public:
ContextDecl *getContext() const { return CtxDecl; }
ScopedDecl *getNext() const { return Next; } ScopedDecl *getNext() const { return Next; }
void setNext(ScopedDecl *N) { Next = N; } void setNext(ScopedDecl *N) { Next = N; }
@ -253,8 +82,13 @@ public:
// scoped decl is defined outside the current function or method. This is // scoped decl is defined outside the current function or method. This is
// roughly global variables and functions, but also handles enums (which could // roughly global variables and functions, but also handles enums (which could
// be defined inside or outside a function etc). // 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. // Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { static bool classof(const Decl *D) {
return D->getKind() >= ScopedFirst && D->getKind() <= ScopedLast; return D->getKind() >= ScopedFirst && D->getKind() <= ScopedLast;
@ -276,9 +110,9 @@ class ValueDecl : public ScopedDecl {
QualType DeclType; QualType DeclType;
protected: protected:
ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T, ValueDecl(Kind DK, ContextDecl *CD, SourceLocation L,
ScopedDecl *PrevDecl) IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl)
: ScopedDecl(DK, L, Id, PrevDecl), DeclType(T) {} : ScopedDecl(DK, CD, L, Id, PrevDecl), DeclType(T) {}
public: public:
QualType getType() const { return DeclType; } QualType getType() const { return DeclType; }
void setType(QualType newType) { DeclType = newType; } void setType(QualType newType) { DeclType = newType; }
@ -309,9 +143,9 @@ private:
friend class StmtIteratorBase; friend class StmtIteratorBase;
protected: 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) 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: public:
StorageClass getStorageClass() const { return (StorageClass)SClass; } StorageClass getStorageClass() const { return (StorageClass)SClass; }
@ -362,11 +196,12 @@ protected:
/// void foo() { int x; static int y; extern int z; } /// void foo() { int x; static int y; extern int z; }
/// ///
class BlockVarDecl : public VarDecl { 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) ScopedDecl *PrevDecl)
: VarDecl(BlockVar, L, Id, T, S, PrevDecl) {} : VarDecl(BlockVar, CD, L, Id, T, S, PrevDecl) {}
public: public:
static BlockVarDecl *Create(ASTContext &C, SourceLocation L, static BlockVarDecl *Create(ASTContext &C, ContextDecl *CD, SourceLocation L,
IdentifierInfo *Id, QualType T, StorageClass S, IdentifierInfo *Id, QualType T, StorageClass S,
ScopedDecl *PrevDecl); ScopedDecl *PrevDecl);
// Implement isa/cast/dyncast/etc. // Implement isa/cast/dyncast/etc.
@ -385,11 +220,13 @@ protected:
/// definitions (C99 6.9.2p2) using our type system (without storing a /// definitions (C99 6.9.2p2) using our type system (without storing a
/// pointer to the decl's scope, which is transient). /// pointer to the decl's scope, which is transient).
class FileVarDecl : public VarDecl { 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) ScopedDecl *PrevDecl)
: VarDecl(FileVar, L, Id, T, S, PrevDecl) {} : VarDecl(FileVar, CD, L, Id, T, S, PrevDecl) {}
public: 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); QualType T, StorageClass S, ScopedDecl *PrevDecl);
// Implement isa/cast/dyncast/etc. // Implement isa/cast/dyncast/etc.
@ -410,12 +247,14 @@ class ParmVarDecl : public VarDecl {
/// in, inout, etc. /// in, inout, etc.
unsigned objcDeclQualifier : 6; 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) ScopedDecl *PrevDecl)
: VarDecl(ParmVar, L, Id, T, S, PrevDecl), : VarDecl(ParmVar, CD, L, Id, T, S, PrevDecl),
objcDeclQualifier(OBJC_TQ_None) {} objcDeclQualifier(OBJC_TQ_None) {}
public: 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); QualType T, StorageClass S, ScopedDecl *PrevDecl);
ObjCDeclQualifier getObjCDeclQualifier() const { ObjCDeclQualifier getObjCDeclQualifier() const {
@ -440,7 +279,7 @@ protected:
/// FunctionDecl - An instance of this class is created to represent a function /// FunctionDecl - An instance of this class is created to represent a function
/// declaration or definition. /// declaration or definition.
class FunctionDecl : public ValueDecl { class FunctionDecl : public ValueDecl, public ContextDecl {
public: public:
enum StorageClass { enum StorageClass {
None, Extern, Static, PrivateExtern None, Extern, Static, PrivateExtern
@ -462,13 +301,15 @@ private:
unsigned SClass : 2; unsigned SClass : 2;
bool IsInline : 1; 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) 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) {} ParamInfo(0), Body(0), DeclChain(0), SClass(S), IsInline(isInline) {}
virtual ~FunctionDecl(); virtual ~FunctionDecl();
public: public:
static FunctionDecl *Create(ASTContext &C, SourceLocation L, static FunctionDecl *Create(ASTContext &C, ContextDecl *CD, SourceLocation L,
IdentifierInfo *Id, QualType T, IdentifierInfo *Id, QualType T,
StorageClass S = None, bool isInline = false, StorageClass S = None, bool isInline = false,
ScopedDecl *PrevDecl = 0); ScopedDecl *PrevDecl = 0);
@ -525,14 +366,18 @@ protected:
class FieldDecl : public NamedDecl { class FieldDecl : public NamedDecl {
QualType DeclType; QualType DeclType;
Expr *BitWidth; Expr *BitWidth;
ContextDecl *CtxDecl;
protected: protected:
FieldDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T, FieldDecl(Kind DK, ContextDecl *CD,
SourceLocation L, IdentifierInfo *Id, QualType T,
Expr *BW = NULL) Expr *BW = NULL)
: NamedDecl(DK, L, Id), DeclType(T), BitWidth(BW) {} : NamedDecl(DK, L, Id), DeclType(T), BitWidth(BW), CtxDecl(CD) {}
FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *BW) FieldDecl(RecordDecl *CD, SourceLocation L,
IdentifierInfo *Id, QualType T, Expr *BW)
: NamedDecl(Field, L, Id), DeclType(T), BitWidth(BW) {} : NamedDecl(Field, L, Id), DeclType(T), BitWidth(BW) {}
public: 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 T, Expr *BW = NULL);
QualType getType() const { return DeclType; } QualType getType() const { return DeclType; }
@ -540,6 +385,7 @@ public:
bool isBitField() const { return BitWidth != NULL; } bool isBitField() const { return BitWidth != NULL; }
Expr *getBitWidth() const { return BitWidth; } Expr *getBitWidth() const { return BitWidth; }
ContextDecl *getContextDecl() const { return CtxDecl; }
// Implement isa/cast/dyncast/etc. // Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { static bool classof(const Decl *D) {
return D->getKind() >= FieldFirst && D->getKind() <= FieldLast; return D->getKind() >= FieldFirst && D->getKind() <= FieldLast;
@ -564,14 +410,16 @@ class EnumConstantDecl : public ValueDecl {
Expr *Init; // an integer constant expression Expr *Init; // an integer constant expression
llvm::APSInt Val; // The value. llvm::APSInt Val; // The value.
protected: 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) 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() {} ~EnumConstantDecl() {}
public: public:
static EnumConstantDecl *Create(ASTContext &C, SourceLocation L, static EnumConstantDecl *Create(ASTContext &C, EnumDecl *CD,
IdentifierInfo *Id, QualType T, Expr *E, SourceLocation L, IdentifierInfo *Id,
QualType T, Expr *E,
const llvm::APSInt &V, ScopedDecl *PrevDecl); const llvm::APSInt &V, ScopedDecl *PrevDecl);
const Expr *getInitExpr() const { return Init; } const Expr *getInitExpr() const { return Init; }
@ -607,8 +455,9 @@ class TypeDecl : public ScopedDecl {
Type *TypeForDecl; Type *TypeForDecl;
friend class ASTContext; friend class ASTContext;
protected: protected:
TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) TypeDecl(Kind DK, ContextDecl *CD, SourceLocation L,
: ScopedDecl(DK, L, Id, PrevDecl), TypeForDecl(0) {} IdentifierInfo *Id, ScopedDecl *PrevDecl)
: ScopedDecl(DK, CD, L, Id, PrevDecl), TypeForDecl(0) {}
public: public:
// Implement isa/cast/dyncast/etc. // Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { static bool classof(const Decl *D) {
@ -621,12 +470,14 @@ public:
class TypedefDecl : public TypeDecl { class TypedefDecl : public TypeDecl {
/// UnderlyingType - This is the type the typedef is set to. /// UnderlyingType - This is the type the typedef is set to.
QualType UnderlyingType; QualType UnderlyingType;
TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T, ScopedDecl *PD) TypedefDecl(ContextDecl *CD, SourceLocation L,
: TypeDecl(Typedef, L, Id, PD), UnderlyingType(T) {} IdentifierInfo *Id, QualType T, ScopedDecl *PD)
: TypeDecl(Typedef, CD, L, Id, PD), UnderlyingType(T) {}
~TypedefDecl() {} ~TypedefDecl() {}
public: 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 T, ScopedDecl *PD);
QualType getUnderlyingType() const { return UnderlyingType; } QualType getUnderlyingType() const { return UnderlyingType; }
@ -648,13 +499,14 @@ protected:
/// TagDecl - Represents the declaration of a struct/union/class/enum. /// 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 /// IsDefinition - True if this is a definition ("struct foo {};"), false if
/// it is a declaration ("struct foo;"). /// it is a declaration ("struct foo;").
bool IsDefinition : 1; bool IsDefinition : 1;
protected: protected:
TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) TagDecl(Kind DK, ContextDecl *CD, SourceLocation L,
: TypeDecl(DK, L, Id, PrevDecl) { IdentifierInfo *Id, ScopedDecl *PrevDecl)
: TypeDecl(DK, CD, L, Id, PrevDecl), ContextDecl(DK) {
IsDefinition = false; IsDefinition = false;
} }
public: public:
@ -695,13 +547,15 @@ class EnumDecl : public TagDecl {
/// have a different type than this does. /// have a different type than this does.
QualType IntegerType; QualType IntegerType;
EnumDecl(SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl) EnumDecl(ContextDecl *CD, SourceLocation L,
: TagDecl(Enum, L, Id, PrevDecl) { IdentifierInfo *Id, ScopedDecl *PrevDecl)
: TagDecl(Enum, CD, L, Id, PrevDecl) {
ElementList = 0; ElementList = 0;
IntegerType = QualType(); IntegerType = QualType();
} }
public: public:
static EnumDecl *Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id, static EnumDecl *Create(ASTContext &C, ContextDecl *CD,
SourceLocation L, IdentifierInfo *Id,
ScopedDecl *PrevDecl); ScopedDecl *PrevDecl);
/// defineElements - When created, EnumDecl correspond to a forward declared /// defineElements - When created, EnumDecl correspond to a forward declared
@ -753,8 +607,8 @@ class RecordDecl : public TagDecl {
FieldDecl **Members; // Null if not defined. FieldDecl **Members; // Null if not defined.
int NumMembers; // -1 if not defined. int NumMembers; // -1 if not defined.
RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, RecordDecl(Kind DK, ContextDecl *CD, SourceLocation L, IdentifierInfo *Id,
ScopedDecl *PrevDecl) : TagDecl(DK, L, Id, PrevDecl) { ScopedDecl *PrevDecl) : TagDecl(DK, CD, L, Id, PrevDecl) {
HasFlexibleArrayMember = false; HasFlexibleArrayMember = false;
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!"); assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
Members = 0; Members = 0;
@ -762,8 +616,9 @@ class RecordDecl : public TagDecl {
} }
public: public:
static RecordDecl *Create(ASTContext &C, Kind DK, SourceLocation L, static RecordDecl *Create(ASTContext &C, Kind DK, ContextDecl *CD,
IdentifierInfo *Id, ScopedDecl *PrevDecl); SourceLocation L, IdentifierInfo *Id,
ScopedDecl *PrevDecl);
bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; } bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; } void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }

Просмотреть файл

@ -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<typename T> const T *getAttr() const {
for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
if (const T *V = dyn_cast<T>(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<typename T> struct KindTrait {
static Decl::Kind getKind(const T *D) { return D->getKind(); }
};
// Used only by the ToDecl and FromDecl methods
template<typename To, typename From>
static To *CastTo(const From *D) {
Decl::Kind DK = KindTrait<From>::getKind(D);
switch(DK) {
case Decl::Function:
return static_cast<FunctionDecl*>(const_cast<From*>(D));
case Decl::ObjCMethod:
return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
case Decl::ObjCInterface:
return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
default:
// check for TagDecl
if (DK >= Decl::TagFirst && DK <= Decl::TagLast)
return static_cast<TagDecl*>(const_cast<From*>(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<ContextDecl> {
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<const ::clang::ContextDecl*> {
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<const ::clang::ContextDecl*> {};
template<> struct simplify_type<const ::clang::ContextDecl> {
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<const ::clang::ContextDecl> {};
/// Implement cast_convert_val for ContextDecl, so that we can dyn_cast from
/// a Decl class to ContextDecl.
template<class FromTy>
struct cast_convert_val< ::clang::ContextDecl,const FromTy,const FromTy> {
static ::clang::ContextDecl &doit(const FromTy &Val) {
return *::clang::ContextDecl::FromDecl(&Val);
}
};
template<class FromTy>
struct cast_convert_val< ::clang::ContextDecl,FromTy,FromTy>
: public cast_convert_val< ::clang::ContextDecl,const FromTy,const FromTy>
{};
template<class FromTy>
struct cast_convert_val< ::clang::ContextDecl,const FromTy*,const FromTy*> {
static ::clang::ContextDecl *doit(const FromTy *Val) {
return ::clang::ContextDecl::FromDecl(Val);
}
};
template<class FromTy>
struct cast_convert_val< ::clang::ContextDecl,FromTy*,FromTy*>
: public cast_convert_val< ::clang::ContextDecl,const FromTy*,const FromTy*>
{};
} // end namespace llvm
#endif

Просмотреть файл

@ -48,7 +48,7 @@ class ObjCPropertyDecl;
/// A selector represents a unique name for a method. The selector names for /// A selector represents a unique name for a method. The selector names for
/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu. /// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
/// ///
class ObjCMethodDecl : public Decl { class ObjCMethodDecl : public Decl, public ContextDecl {
public: public:
enum ImplementationControl { None, Required, Optional }; enum ImplementationControl { None, Required, Optional };
private: private:
@ -96,6 +96,7 @@ private:
bool isVariadic = false, bool isVariadic = false,
ImplementationControl impControl = None) ImplementationControl impControl = None)
: Decl(ObjCMethod, beginLoc), : Decl(ObjCMethod, beginLoc),
ContextDecl(ObjCMethod),
IsInstance(isInstance), IsVariadic(isVariadic), IsInstance(isInstance), IsVariadic(isVariadic),
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
MethodContext(static_cast<NamedDecl*>(contextDecl)), MethodContext(static_cast<NamedDecl*>(contextDecl)),
@ -105,7 +106,8 @@ private:
virtual ~ObjCMethodDecl(); virtual ~ObjCMethodDecl();
public: public:
static ObjCMethodDecl *Create(ASTContext &C, SourceLocation beginLoc, static ObjCMethodDecl *Create(ASTContext &C,
SourceLocation beginLoc,
SourceLocation endLoc, Selector SelInfo, SourceLocation endLoc, Selector SelInfo,
QualType T, Decl *contextDecl, QualType T, Decl *contextDecl,
AttributeList *M = 0, bool isInstance = true, AttributeList *M = 0, bool isInstance = true,
@ -191,7 +193,7 @@ public:
/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes /// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
/// typically inherit from NSObject (an exception is NSProxy). /// 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 /// TypeForDecl - This indicates the Type object that represents this
/// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
Type *TypeForDecl; Type *TypeForDecl;
@ -229,9 +231,11 @@ class ObjCInterfaceDecl : public NamedDecl {
SourceLocation EndLoc; // marks the '>', '}', or identifier. SourceLocation EndLoc; // marks the '>', '}', or identifier.
SourceLocation AtEndLoc; // marks the end of the entire interface. 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) 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), ReferencedProtocols(0), NumReferencedProtocols(0), Ivars(0),
NumIvars(0), NumIvars(0),
InstanceMethods(0), NumInstanceMethods(0), InstanceMethods(0), NumInstanceMethods(0),
@ -242,7 +246,8 @@ class ObjCInterfaceDecl : public NamedDecl {
} }
public: public:
static ObjCInterfaceDecl *Create(ASTContext &C, SourceLocation atLoc, static ObjCInterfaceDecl *Create(ASTContext &C,
SourceLocation atLoc,
unsigned numRefProtos, IdentifierInfo *Id, unsigned numRefProtos, IdentifierInfo *Id,
bool ForwardDecl = false, bool ForwardDecl = false,
bool isInternal = false); bool isInternal = false);
@ -371,10 +376,12 @@ public:
/// } /// }
/// ///
class ObjCIvarDecl : public FieldDecl { class ObjCIvarDecl : public FieldDecl {
ObjCIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T) ObjCIvarDecl(ContextDecl *CD, SourceLocation L,
: FieldDecl(ObjCIvar, L, Id, T) {} IdentifierInfo *Id, QualType T)
: FieldDecl(ObjCIvar, CD, L, Id, T) {}
public: public:
static ObjCIvarDecl *Create(ASTContext &C, SourceLocation L, static ObjCIvarDecl *Create(ASTContext &C, ObjCInterfaceDecl *CD,
SourceLocation L,
IdentifierInfo *Id, QualType T); IdentifierInfo *Id, QualType T);
enum AccessControl { enum AccessControl {
@ -559,7 +566,7 @@ class ObjCForwardProtocolDecl : public Decl {
ObjCProtocolDecl **ReferencedProtocols; ObjCProtocolDecl **ReferencedProtocols;
unsigned NumReferencedProtocols; unsigned NumReferencedProtocols;
ObjCForwardProtocolDecl(SourceLocation L, ObjCForwardProtocolDecl(SourceLocation L,
ObjCProtocolDecl **Elts, unsigned nElts) ObjCProtocolDecl **Elts, unsigned nElts)
: Decl(ObjCForwardProtocol, L) { : Decl(ObjCForwardProtocol, L) {
NumReferencedProtocols = nElts; NumReferencedProtocols = nElts;
@ -645,8 +652,8 @@ class ObjCCategoryDecl : public NamedDecl {
} }
public: public:
static ObjCCategoryDecl *Create(ASTContext &C, SourceLocation L, static ObjCCategoryDecl *Create(ASTContext &C,
IdentifierInfo *Id); SourceLocation L, IdentifierInfo *Id);
ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; } void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; }
@ -735,8 +742,8 @@ class ObjCCategoryImplDecl : public NamedDecl {
ObjCInterfaceDecl *classInterface) ObjCInterfaceDecl *classInterface)
: NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {} : NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {}
public: public:
static ObjCCategoryImplDecl *Create(ASTContext &C, SourceLocation L, static ObjCCategoryImplDecl *Create(ASTContext &C,
IdentifierInfo *Id, SourceLocation L, IdentifierInfo *Id,
ObjCInterfaceDecl *classInterface); ObjCInterfaceDecl *classInterface);
ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
@ -817,8 +824,8 @@ class ObjCImplementationDecl : public NamedDecl {
ClassInterface(classInterface), SuperClass(superDecl), ClassInterface(classInterface), SuperClass(superDecl),
Ivars(0), NumIvars(0) {} Ivars(0), NumIvars(0) {}
public: public:
static ObjCImplementationDecl *Create(ASTContext &C, SourceLocation L, static ObjCImplementationDecl *Create(ASTContext &C,
IdentifierInfo *Id, SourceLocation L, IdentifierInfo *Id,
ObjCInterfaceDecl *classInterface, ObjCInterfaceDecl *classInterface,
ObjCInterfaceDecl *superDecl); ObjCInterfaceDecl *superDecl);
@ -883,8 +890,8 @@ class ObjCCompatibleAliasDecl : public NamedDecl {
ObjCInterfaceDecl* aliasedClass) ObjCInterfaceDecl* aliasedClass)
: NamedDecl(ObjCCompatibleAlias, L, Id), AliasedClass(aliasedClass) {} : NamedDecl(ObjCCompatibleAlias, L, Id), AliasedClass(aliasedClass) {}
public: public:
static ObjCCompatibleAliasDecl *Create(ASTContext &C, SourceLocation L, static ObjCCompatibleAliasDecl *Create(ASTContext &C,
IdentifierInfo *Id, SourceLocation L, IdentifierInfo *Id,
ObjCInterfaceDecl* aliasedClass); ObjCInterfaceDecl* aliasedClass);
const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }

Просмотреть файл

@ -1115,7 +1115,7 @@ QualType ASTContext::maxIntegerType(QualType lhs, QualType rhs) {
QualType ASTContext::getCFConstantStringType() { QualType ASTContext::getCFConstantStringType() {
if (!CFConstantStringTypeDecl) { if (!CFConstantStringTypeDecl) {
CFConstantStringTypeDecl = CFConstantStringTypeDecl =
RecordDecl::Create(*this, Decl::Struct, SourceLocation(), RecordDecl::Create(*this, Decl::Struct, NULL, SourceLocation(),
&Idents.get("NSConstantString"), 0); &Idents.get("NSConstantString"), 0);
QualType FieldTypes[4]; QualType FieldTypes[4];
@ -1131,7 +1131,8 @@ QualType ASTContext::getCFConstantStringType() {
FieldDecl *FieldDecls[4]; FieldDecl *FieldDecls[4];
for (unsigned i = 0; i < 4; ++i) for (unsigned i = 0; i < 4; ++i)
FieldDecls[i] = FieldDecl::Create(*this, SourceLocation(), 0, FieldDecls[i] = FieldDecl::Create(*this, CFConstantStringTypeDecl,
SourceLocation(), 0,
FieldTypes[i]); FieldTypes[i]);
CFConstantStringTypeDecl->defineBody(FieldDecls, 4); CFConstantStringTypeDecl->defineBody(FieldDecls, 4);
@ -1907,14 +1908,14 @@ ASTContext* ASTContext::Create(llvm::Deserializer& D) {
TargetInfo &t = D.ReadRef<TargetInfo>(); TargetInfo &t = D.ReadRef<TargetInfo>();
IdentifierTable &idents = D.ReadRef<IdentifierTable>(); IdentifierTable &idents = D.ReadRef<IdentifierTable>();
SelectorTable &sels = D.ReadRef<SelectorTable>(); SelectorTable &sels = D.ReadRef<SelectorTable>();
unsigned size_reserve = D.ReadInt(); unsigned size_reserve = D.ReadInt();
ASTContext* A = new ASTContext(SM,t,idents,sels,size_reserve); ASTContext* A = new ASTContext(SM,t,idents,sels,size_reserve);
for (unsigned i = 0; i < size_reserve; ++i) for (unsigned i = 0; i < size_reserve; ++i)
Type::Create(*A,i,D); Type::Create(*A,i,D);
// FIXME: A->CFConstantStringTypeDecl = D.ReadOwnedPtr<RecordDecl>(); // FIXME: A->CFConstantStringTypeDecl = D.ReadOwnedPtr<RecordDecl>();
return A; return A;

Просмотреть файл

@ -204,77 +204,87 @@ void Decl::addDeclKind(Kind k) {
// Decl Allocation/Deallocation Method Implementations // 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, IdentifierInfo *Id, QualType T,
StorageClass S, ScopedDecl *PrevDecl) { StorageClass S, ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<BlockVarDecl>(); 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, FileVarDecl *FileVarDecl::Create(ASTContext &C, ContextDecl *CD,
IdentifierInfo *Id, QualType T, StorageClass S, SourceLocation L, IdentifierInfo *Id,
QualType T, StorageClass S,
ScopedDecl *PrevDecl) { ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<FileVarDecl>(); 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, ParmVarDecl *ParmVarDecl::Create(ASTContext &C, ContextDecl *CD,
IdentifierInfo *Id, QualType T, StorageClass S, SourceLocation L, IdentifierInfo *Id,
QualType T, StorageClass S,
ScopedDecl *PrevDecl) { ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<ParmVarDecl>(); 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, IdentifierInfo *Id, QualType T,
StorageClass S, bool isInline, StorageClass S, bool isInline,
ScopedDecl *PrevDecl) { ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<FunctionDecl>(); 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) { IdentifierInfo *Id, QualType T, Expr *BW) {
void *Mem = C.getAllocator().Allocate<FieldDecl>(); 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, IdentifierInfo *Id, QualType T,
Expr *E, const llvm::APSInt &V, Expr *E, const llvm::APSInt &V,
ScopedDecl *PrevDecl){ ScopedDecl *PrevDecl){
void *Mem = C.getAllocator().Allocate<EnumConstantDecl>(); 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, IdentifierInfo *Id, QualType T,
ScopedDecl *PD) { ScopedDecl *PD) {
void *Mem = C.getAllocator().Allocate<TypedefDecl>(); 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) { ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<EnumDecl>(); 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, RecordDecl *RecordDecl::Create(ASTContext &C, Kind DK, ContextDecl *CD,
IdentifierInfo *Id, ScopedDecl *PrevDecl) { SourceLocation L, IdentifierInfo *Id,
ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<RecordDecl>(); 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) { StringLiteral *Str) {
void *Mem = C.getAllocator().Allocate<FileScopeAsmDecl>(); void *Mem = C.getAllocator().Allocate<FileScopeAsmDecl>();
return new (Mem) FileScopeAsmDecl(L, Str); return new (Mem) FileScopeAsmDecl(L, Str);
} }
LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, SourceLocation L, LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
SourceLocation L,
LanguageIDs Lang, Decl *D) { LanguageIDs Lang, Decl *D) {
void *Mem = C.getAllocator().Allocate<LinkageSpecDecl>(); void *Mem = C.getAllocator().Allocate<LinkageSpecDecl>();
return new (Mem) LinkageSpecDecl(L, Lang, D); return new (Mem) LinkageSpecDecl(L, Lang, D);
@ -319,6 +329,25 @@ const Attr *Decl::getAttrs() const {
return (*DeclAttrs)[this]; return (*DeclAttrs)[this];
} }
//===----------------------------------------------------------------------===//
// 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 // NamedDecl Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -329,28 +358,6 @@ const char *NamedDecl::getName() const {
return ""; 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<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 // FunctionDecl Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

Просмотреть файл

@ -19,7 +19,8 @@ using namespace clang;
// ObjC Decl Allocation/Deallocation Method Implementations // ObjC Decl Allocation/Deallocation Method Implementations
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, SourceLocation beginLoc, ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
SourceLocation beginLoc,
SourceLocation endLoc, SourceLocation endLoc,
Selector SelInfo, QualType T, Selector SelInfo, QualType T,
Decl *contextDecl, Decl *contextDecl,
@ -27,61 +28,71 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, SourceLocation beginLoc,
bool isVariadic, bool isVariadic,
ImplementationControl impControl) { ImplementationControl impControl) {
void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>(); 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, M, isInstance,
isVariadic, impControl); isVariadic, impControl);
} }
ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,SourceLocation atLoc, ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
SourceLocation atLoc,
unsigned numRefProtos, unsigned numRefProtos,
IdentifierInfo *Id, IdentifierInfo *Id,
bool ForwardDecl, bool isInternal){ bool ForwardDecl, bool isInternal){
void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>(); void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos, Id, ForwardDecl, return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos,
Id, ForwardDecl,
isInternal); isInternal);
} }
ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L, ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCInterfaceDecl *CD,
SourceLocation L,
IdentifierInfo *Id, QualType T) { IdentifierInfo *Id, QualType T) {
void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>(); 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, unsigned numRefProtos,
IdentifierInfo *Id) { IdentifierInfo *Id) {
void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>(); void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id); 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) { ObjCInterfaceDecl **Elts, unsigned nElts) {
void *Mem = C.getAllocator().Allocate<ObjCClassDecl>(); void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
return new (Mem) ObjCClassDecl(L, Elts, nElts); return new (Mem) ObjCClassDecl(L, Elts, nElts);
} }
ObjCForwardProtocolDecl * ObjCForwardProtocolDecl *
ObjCForwardProtocolDecl::Create(ASTContext &C, SourceLocation L, ObjCForwardProtocolDecl::Create(ASTContext &C,
SourceLocation L,
ObjCProtocolDecl **Elts, unsigned NumElts) { ObjCProtocolDecl **Elts, unsigned NumElts) {
void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>(); void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts); return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
} }
ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, SourceLocation L, ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
SourceLocation L,
IdentifierInfo *Id) { IdentifierInfo *Id) {
void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>(); void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
return new (Mem) ObjCCategoryDecl(L, Id); return new (Mem) ObjCCategoryDecl(L, Id);
} }
ObjCCategoryImplDecl * ObjCCategoryImplDecl *
ObjCCategoryImplDecl::Create(ASTContext &C, SourceLocation L,IdentifierInfo *Id, ObjCCategoryImplDecl::Create(ASTContext &C,
SourceLocation L,IdentifierInfo *Id,
ObjCInterfaceDecl *ClassInterface) { ObjCInterfaceDecl *ClassInterface) {
void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>(); void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface); return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
} }
ObjCImplementationDecl * ObjCImplementationDecl *
ObjCImplementationDecl::Create(ASTContext &C, SourceLocation L, ObjCImplementationDecl::Create(ASTContext &C,
SourceLocation L,
IdentifierInfo *Id, IdentifierInfo *Id,
ObjCInterfaceDecl *ClassInterface, ObjCInterfaceDecl *ClassInterface,
ObjCInterfaceDecl *SuperDecl) { ObjCInterfaceDecl *SuperDecl) {
@ -90,14 +101,16 @@ ObjCImplementationDecl::Create(ASTContext &C, SourceLocation L,
} }
ObjCCompatibleAliasDecl * ObjCCompatibleAliasDecl *
ObjCCompatibleAliasDecl::Create(ASTContext &C, SourceLocation L, ObjCCompatibleAliasDecl::Create(ASTContext &C,
SourceLocation L,
IdentifierInfo *Id, IdentifierInfo *Id,
ObjCInterfaceDecl* AliasedClass) { ObjCInterfaceDecl* AliasedClass) {
void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>(); void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass); 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>(); void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
return new (Mem) ObjCPropertyDecl(L); return new (Mem) ObjCPropertyDecl(L);
} }
@ -431,3 +444,4 @@ void ObjCPropertyDecl::setPropertyDeclLists(ObjCIvarDecl **Properties,
} }

Просмотреть файл

@ -39,7 +39,7 @@ Decl* Decl::Create(Deserializer& D) {
default: default:
assert (false && "Not implemented."); assert (false && "Not implemented.");
break; break;
case BlockVar: case BlockVar:
return BlockVarDecl::CreateImpl(D); return BlockVarDecl::CreateImpl(D);
@ -106,11 +106,15 @@ void NamedDecl::ReadInRec(Deserializer& D) {
void ScopedDecl::EmitInRec(Serializer& S) const { void ScopedDecl::EmitInRec(Serializer& S) const {
NamedDecl::EmitInRec(S); NamedDecl::EmitInRec(S);
S.EmitPtr(getNext()); // From ScopedDecl. S.EmitPtr(getNext()); // From ScopedDecl.
S.EmitPtr(cast_or_null<Decl>(getContext())); // From ScopedDecl.
} }
void ScopedDecl::ReadInRec(Deserializer& D) { void ScopedDecl::ReadInRec(Deserializer& D) {
NamedDecl::ReadInRec(D); NamedDecl::ReadInRec(D);
D.ReadPtr(Next); // From ScopedDecl. D.ReadPtr(Next); // From ScopedDecl.
Decl *TmpD;
D.ReadPtr(TmpD); // From ScopedDecl.
CtxDecl = cast_or_null<ContextDecl>(TmpD);
} }
//===------------------------------------------------------------===// //===------------------------------------------------------------===//
@ -194,7 +198,7 @@ void VarDecl::ReadImpl(Deserializer& D) {
BlockVarDecl* BlockVarDecl::CreateImpl(Deserializer& D) { BlockVarDecl* BlockVarDecl::CreateImpl(Deserializer& D) {
BlockVarDecl* decl = BlockVarDecl* decl =
new BlockVarDecl(SourceLocation(),NULL,QualType(),None,NULL); new BlockVarDecl(0, SourceLocation(),NULL,QualType(),None,NULL);
decl->VarDecl::ReadImpl(D); decl->VarDecl::ReadImpl(D);
@ -207,7 +211,7 @@ BlockVarDecl* BlockVarDecl::CreateImpl(Deserializer& D) {
FileVarDecl* FileVarDecl::CreateImpl(Deserializer& D) { FileVarDecl* FileVarDecl::CreateImpl(Deserializer& D) {
FileVarDecl* decl = FileVarDecl* decl =
new FileVarDecl(SourceLocation(),NULL,QualType(),None,NULL); new FileVarDecl(0, SourceLocation(),NULL,QualType(),None,NULL);
decl->VarDecl::ReadImpl(D); decl->VarDecl::ReadImpl(D);
@ -225,7 +229,7 @@ void ParmVarDecl::EmitImpl(llvm::Serializer& S) const {
ParmVarDecl* ParmVarDecl::CreateImpl(Deserializer& D) { ParmVarDecl* ParmVarDecl::CreateImpl(Deserializer& D) {
ParmVarDecl* decl = ParmVarDecl* decl =
new ParmVarDecl(SourceLocation(),NULL,QualType(),None,NULL); new ParmVarDecl(0, SourceLocation(),NULL,QualType(),None,NULL);
decl->VarDecl::ReadImpl(D); decl->VarDecl::ReadImpl(D);
decl->objcDeclQualifier = static_cast<ObjCDeclQualifier>(D.ReadInt()); decl->objcDeclQualifier = static_cast<ObjCDeclQualifier>(D.ReadInt());
@ -245,7 +249,7 @@ void EnumDecl::EmitImpl(Serializer& S) const {
} }
EnumDecl* EnumDecl::CreateImpl(Deserializer& D) { 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->ScopedDecl::ReadInRec(D);
decl->setDefinition(D.ReadBool()); decl->setDefinition(D.ReadBool());
@ -277,7 +281,7 @@ EnumConstantDecl* EnumConstantDecl::CreateImpl(Deserializer& D) {
D.Read(val); D.Read(val);
EnumConstantDecl* decl = EnumConstantDecl* decl =
new EnumConstantDecl(SourceLocation(),NULL,QualType(),NULL, new EnumConstantDecl(0, SourceLocation(),NULL,QualType(),NULL,
val,NULL); val,NULL);
decl->ValueDecl::ReadInRec(D); decl->ValueDecl::ReadInRec(D);
@ -302,7 +306,7 @@ void FieldDecl::EmitImpl(Serializer& S) const {
} }
FieldDecl* FieldDecl::CreateImpl(Deserializer& D) { 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->DeclType.ReadBackpatch(D);
decl->ReadInRec(D); decl->ReadInRec(D);
decl->BitWidth = D.ReadOwnedPtr<Expr>(); decl->BitWidth = D.ReadOwnedPtr<Expr>();
@ -338,7 +342,7 @@ FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D) {
bool IsInline = D.ReadBool(); bool IsInline = D.ReadBool();
FunctionDecl* decl = FunctionDecl* decl =
new FunctionDecl(SourceLocation(),NULL,QualType(),SClass, IsInline, 0); new FunctionDecl(0, SourceLocation(),NULL,QualType(),SClass, IsInline, 0);
decl->ValueDecl::ReadInRec(D); decl->ValueDecl::ReadInRec(D);
D.ReadPtr(decl->DeclChain); D.ReadPtr(decl->DeclChain);
@ -382,7 +386,7 @@ void RecordDecl::EmitImpl(Serializer& S) const {
} }
RecordDecl* RecordDecl::CreateImpl(Decl::Kind DK, Deserializer& D) { 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->ScopedDecl::ReadInRec(D);
decl->setDefinition(D.ReadBool()); decl->setDefinition(D.ReadBool());
@ -418,7 +422,7 @@ void TypedefDecl::EmitImpl(Serializer& S) const {
TypedefDecl* TypedefDecl::CreateImpl(Deserializer& D) { TypedefDecl* TypedefDecl::CreateImpl(Deserializer& D) {
QualType T = QualType::ReadVal(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::ReadInRec(D);
decl->ScopedDecl::ReadOutRec(D); decl->ScopedDecl::ReadOutRec(D);

Просмотреть файл

@ -59,7 +59,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
TUScope->AddDecl(IDecl); TUScope->AddDecl(IDecl);
// Synthesize "typedef struct objc_selector *SEL;" // Synthesize "typedef struct objc_selector *SEL;"
RecordDecl *SelTag = RecordDecl::Create(Context, Decl::Struct, RecordDecl *SelTag = RecordDecl::Create(Context, Decl::Struct, CurContext,
SourceLocation(), SourceLocation(),
&Context.Idents.get("objc_selector"), &Context.Idents.get("objc_selector"),
0); 0);
@ -67,7 +67,8 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
TUScope->AddDecl(SelTag); TUScope->AddDecl(SelTag);
QualType SelT = Context.getPointerType(Context.getTagDeclType(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"), &Context.Idents.get("SEL"),
SelT, 0); SelT, 0);
SelTypedef->getIdentifier()->setFETokenInfo(SelTypedef); SelTypedef->getIdentifier()->setFETokenInfo(SelTypedef);
@ -77,7 +78,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer) Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
: PP(pp), Context(ctxt), Consumer(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 // Get IdentifierInfo objects for known functions for which we
// do extra checking. // do extra checking.
@ -99,11 +100,12 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
if (PP.getLangOptions().ObjC1) { if (PP.getLangOptions().ObjC1) {
// Synthesize "typedef struct objc_class *Class;" // Synthesize "typedef struct objc_class *Class;"
RecordDecl *ClassTag = RecordDecl::Create(Context, Decl::Struct, RecordDecl *ClassTag = RecordDecl::Create(Context, Decl::Struct,
SourceLocation(), NULL,
SourceLocation(),
&IT.get("objc_class"), 0); &IT.get("objc_class"), 0);
QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag)); QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
TypedefDecl *ClassTypedef = TypedefDecl *ClassTypedef =
TypedefDecl::Create(Context, SourceLocation(), TypedefDecl::Create(Context, NULL, SourceLocation(),
&Context.Idents.get("Class"), ClassT, 0); &Context.Idents.get("Class"), ClassT, 0);
Context.setObjCClassType(ClassTypedef); Context.setObjCClassType(ClassTypedef);
@ -115,13 +117,16 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
// Synthesize "typedef struct objc_object { Class isa; } *id;" // Synthesize "typedef struct objc_object { Class isa; } *id;"
RecordDecl *ObjectTag = RecordDecl *ObjectTag =
RecordDecl::Create(Context, Decl::Struct, SourceLocation(), RecordDecl::Create(Context, Decl::Struct, NULL,
SourceLocation(),
&IT.get("objc_object"), 0); &IT.get("objc_object"), 0);
FieldDecl *IsaDecl = FieldDecl::Create(Context, SourceLocation(), 0, FieldDecl *IsaDecl = FieldDecl::Create(Context, ObjectTag,
SourceLocation(), 0,
Context.getObjCClassType()); Context.getObjCClassType());
ObjectTag->defineBody(&IsaDecl, 1); ObjectTag->defineBody(&IsaDecl, 1);
QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag)); QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
TypedefDecl *IdTypedef = TypedefDecl::Create(Context, SourceLocation(), TypedefDecl *IdTypedef = TypedefDecl::Create(Context, NULL,
SourceLocation(),
&Context.Idents.get("id"), &Context.Idents.get("id"),
ObjT, 0); ObjT, 0);
Context.setObjCIdType(IdTypedef); Context.setObjCIdType(IdTypedef);

Просмотреть файл

@ -32,6 +32,7 @@ namespace clang {
class ASTConsumer; class ASTConsumer;
class Preprocessor; class Preprocessor;
class Decl; class Decl;
class ContextDecl;
class NamedDecl; class NamedDecl;
class ScopedDecl; class ScopedDecl;
class Expr; class Expr;
@ -73,7 +74,9 @@ class Sema : public Action {
/// CurMethodDecl - If inside of a method body, this contains a pointer to /// CurMethodDecl - If inside of a method body, this contains a pointer to
/// the method decl for the method being parsed. /// the method decl for the method being parsed.
ObjCMethodDecl *CurMethodDecl; ObjCMethodDecl *CurMethodDecl;
ContextDecl *CurContext;
/// LabelMap - This is a mapping from label identifiers to the LabelStmt for /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
/// it (which acts like the label decl in some ways). Forward referenced /// it (which acts like the label decl in some ways). Forward referenced
/// labels have a LabelStmt created for them with a null location & SubStmt. /// labels have a LabelStmt created for them with a null location & SubStmt.
@ -246,6 +249,10 @@ private:
virtual void ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl, virtual void ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl,
DeclTy **Elements, unsigned NumElements); DeclTy **Elements, unsigned NumElements);
private: private:
/// Set the current declaration context until it gets popped.
void PushContextDecl(ContextDecl *CD);
void PopContextDecl();
/// Subroutines of ActOnDeclarator(). /// Subroutines of ActOnDeclarator().
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T, TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
ScopedDecl *LastDecl); ScopedDecl *LastDecl);

Просмотреть файл

@ -40,6 +40,17 @@ Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) {
return 0; 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) { void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
if (S->decl_empty()) return; if (S->decl_empty()) return;
assert((S->getFlags() & Scope::DeclScope) &&"Scope shouldn't contain decls!"); assert((S->getFlags() & Scope::DeclScope) &&"Scope shouldn't contain decls!");
@ -156,7 +167,8 @@ ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
InitBuiltinVaListType(); InitBuiltinVaListType();
QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context); 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); FunctionDecl::Extern, false, 0);
// Find translation-unit scope to insert this function into. // 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(); bool isInline = D.getDeclSpec().isInlineSpecified();
FunctionDecl *NewFD = FunctionDecl::Create(Context, D.getIdentifierLoc(), FunctionDecl *NewFD = FunctionDecl::Create(Context, CurContext,
D.getIdentifierLoc(),
II, R, SC, isInline, II, R, SC, isInline,
LastDeclarator); LastDeclarator);
// Handle attributes. // Handle attributes.
@ -784,10 +797,12 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
R.getAsString()); R.getAsString());
InvalidDecl = true; InvalidDecl = true;
} }
NewVD = FileVarDecl::Create(Context, D.getIdentifierLoc(), II, R, SC, NewVD = FileVarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
II, R, SC,
LastDeclarator); LastDeclarator);
} else { } else {
NewVD = BlockVarDecl::Create(Context, D.getIdentifierLoc(), II, R, SC, NewVD = BlockVarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
II, R, SC,
LastDeclarator); LastDeclarator);
} }
// Handle attributes prior to checking for duplicates in MergeVarDecl // Handle attributes prior to checking for duplicates in MergeVarDecl
@ -1000,7 +1015,8 @@ Sema::ActOnParamDeclarator(struct DeclaratorChunk::ParamInfo &PI,
} else if (parmDeclType->isFunctionType()) } else if (parmDeclType->isFunctionType())
parmDeclType = Context.getPointerType(parmDeclType); 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); VarDecl::None, 0);
if (PI.InvalidType) if (PI.InvalidType)
@ -1060,6 +1076,7 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
Decl *decl = static_cast<Decl*>(ActOnDeclarator(GlobalScope, D, 0)); Decl *decl = static_cast<Decl*>(ActOnDeclarator(GlobalScope, D, 0));
FunctionDecl *FD = cast<FunctionDecl>(decl); FunctionDecl *FD = cast<FunctionDecl>(decl);
CurFunctionDecl = FD; CurFunctionDecl = FD;
PushContextDecl(FD);
// Create Decl objects for each parameter, adding them to the FunctionDecl. // Create Decl objects for each parameter, adding them to the FunctionDecl.
llvm::SmallVector<ParmVarDecl*, 16> Params; llvm::SmallVector<ParmVarDecl*, 16> Params;
@ -1104,6 +1121,7 @@ Sema::DeclTy *Sema::ActOnFinishFunctionBody(DeclTy *D, StmtTy *Body) {
MD->setBody((Stmt*)Body); MD->setBody((Stmt*)Body);
CurMethodDecl = 0; CurMethodDecl = 0;
} }
PopContextDecl();
// Verify and clean out per-function state. // Verify and clean out per-function state.
// Check goto/label use. // Check goto/label use.
@ -1173,7 +1191,8 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
assert(!T.isNull() && "GetTypeForDeclarator() returned null type"); assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
// Scope manipulation handled by caller. // Scope manipulation handled by caller.
TypedefDecl *NewTD = TypedefDecl::Create(Context, D.getIdentifierLoc(), TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext,
D.getIdentifierLoc(),
D.getIdentifier(), D.getIdentifier(),
T, LastDeclarator); T, LastDeclarator);
if (D.getInvalidType()) if (D.getInvalidType())
@ -1253,7 +1272,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
case Decl::Enum: case Decl::Enum:
// FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.: // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
// enum X { A, B, C } D; D should chain to X. // 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 this is an undefined enum, warn.
if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum); if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum);
break; break;
@ -1262,7 +1281,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
case Decl::Class: case Decl::Class:
// FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.: // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
// struct X { int A; } D; D should chain to X. // 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; break;
} }
@ -1326,8 +1345,8 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *tagDecl,
// FIXME: Chain fielddecls together. // FIXME: Chain fielddecls together.
FieldDecl *NewFD; FieldDecl *NewFD;
if (isa<RecordDecl>(TagDecl)) if (RecordDecl *RD = dyn_cast<RecordDecl>(TagDecl))
NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth); NewFD = FieldDecl::Create(Context, RD, Loc, II, T, BitWidth);
else if (isa<ObjCInterfaceDecl>(TagDecl) || else if (isa<ObjCInterfaceDecl>(TagDecl) ||
isa<ObjCImplementationDecl>(TagDecl) || isa<ObjCImplementationDecl>(TagDecl) ||
isa<ObjCCategoryDecl>(TagDecl) || isa<ObjCCategoryDecl>(TagDecl) ||
@ -1335,7 +1354,7 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *tagDecl,
// properties can appear within a protocol. // properties can appear within a protocol.
// See corresponding FIXME in DeclObjC.h:ObjCPropertyDecl. // See corresponding FIXME in DeclObjC.h:ObjCPropertyDecl.
isa<ObjCProtocolDecl>(TagDecl)) isa<ObjCProtocolDecl>(TagDecl))
NewFD = ObjCIvarDecl::Create(Context, Loc, II, T); NewFD = ObjCIvarDecl::Create(Context, dyn_cast<ObjCInterfaceDecl>(TagDecl), Loc, II, T);
else else
assert(0 && "Sema::ActOnField(): Unknown TagDecl"); assert(0 && "Sema::ActOnField(): Unknown TagDecl");
@ -1515,7 +1534,7 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,
DeclTy *lastEnumConst, DeclTy *lastEnumConst,
SourceLocation IdLoc, IdentifierInfo *Id, SourceLocation IdLoc, IdentifierInfo *Id,
SourceLocation EqualLoc, ExprTy *val) { SourceLocation EqualLoc, ExprTy *val) {
theEnumDecl = theEnumDecl; // silence unused warning. EnumDecl *TheEnumDecl = cast<EnumDecl>(static_cast<Decl*>(theEnumDecl));
EnumConstantDecl *LastEnumConst = EnumConstantDecl *LastEnumConst =
cast_or_null<EnumConstantDecl>(static_cast<Decl*>(lastEnumConst)); cast_or_null<EnumConstantDecl>(static_cast<Decl*>(lastEnumConst));
Expr *Val = static_cast<Expr*>(val); Expr *Val = static_cast<Expr*>(val);
@ -1576,7 +1595,8 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,
} }
EnumConstantDecl *New = EnumConstantDecl *New =
EnumConstantDecl::Create(Context, IdLoc, Id, EltTy, Val, EnumVal, EnumConstantDecl::Create(Context, TheEnumDecl, IdLoc, Id, EltTy,
Val, EnumVal,
LastEnumConst); LastEnumConst);
// Register this decl in the current scope stack. // Register this decl in the current scope stack.

Просмотреть файл

@ -33,6 +33,7 @@ void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
// Allow all of Sema to see that we are entering a method definition. // Allow all of Sema to see that we are entering a method definition.
CurMethodDecl = MDecl; CurMethodDecl = MDecl;
PushContextDecl(MDecl);
// Create Decl objects for each parameter, entrring them in the scope for // Create Decl objects for each parameter, entrring them in the scope for
// binding to their use. // binding to their use.
@ -813,23 +814,6 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration(
Diag(MethodLoc, diag::error_missing_method_context); Diag(MethodLoc, diag::error_missing_method_context);
return 0; 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; QualType resultDeclType;
if (ReturnType) if (ReturnType)
@ -845,6 +829,25 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration(
ObjCMethodDecl::Optional : ObjCMethodDecl::Optional :
ObjCMethodDecl::Required); 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->setMethodParams(&Params[0], Sel.getNumArgs());
ObjCMethod->setObjCDeclQualifier( ObjCMethod->setObjCDeclQualifier(
CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier())); CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));