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

llvm-svn: 49208
This commit is contained in:
Chris Lattner 2008-04-04 06:12:32 +00:00
parent 318d3ef88e
commit c5ffed4a66
12 changed files with 636 additions and 370 deletions

View File

@ -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<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);
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<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);
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);

View File

@ -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<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
/// 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<Decl*>(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; }

View File

@ -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

View File

@ -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<NamedDecl*>(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; }

View File

@ -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<TargetInfo>();
IdentifierTable &idents = D.ReadRef<IdentifierTable>();
SelectorTable &sels = D.ReadRef<SelectorTable>();
unsigned size_reserve = D.ReadInt();
ASTContext* A = new ASTContext(SM,t,idents,sels,size_reserve);
for (unsigned i = 0; i < size_reserve; ++i)
Type::Create(*A,i,D);
// FIXME: A->CFConstantStringTypeDecl = D.ReadOwnedPtr<RecordDecl>();
return A;

View File

@ -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<BlockVarDecl>();
return new (Mem) BlockVarDecl(L, Id, T, S, PrevDecl);
return new (Mem) BlockVarDecl(CD, L, Id, T, S, PrevDecl);
}
FileVarDecl *FileVarDecl::Create(ASTContext &C, SourceLocation L,
IdentifierInfo *Id, QualType T, StorageClass S,
FileVarDecl *FileVarDecl::Create(ASTContext &C, ContextDecl *CD,
SourceLocation L, IdentifierInfo *Id,
QualType T, StorageClass S,
ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<FileVarDecl>();
return new (Mem) FileVarDecl(L, Id, T, S, PrevDecl);
return new (Mem) FileVarDecl(CD, L, Id, T, S, PrevDecl);
}
ParmVarDecl *ParmVarDecl::Create(ASTContext &C, SourceLocation L,
IdentifierInfo *Id, QualType T, StorageClass S,
ParmVarDecl *ParmVarDecl::Create(ASTContext &C, ContextDecl *CD,
SourceLocation L, IdentifierInfo *Id,
QualType T, StorageClass S,
ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<ParmVarDecl>();
return new (Mem) ParmVarDecl(L, Id, T, S, PrevDecl);
return new (Mem) ParmVarDecl(CD, L, Id, T, S, PrevDecl);
}
FunctionDecl *FunctionDecl::Create(ASTContext &C, SourceLocation L,
FunctionDecl *FunctionDecl::Create(ASTContext &C, ContextDecl *CD,
SourceLocation L,
IdentifierInfo *Id, QualType T,
StorageClass S, bool isInline,
ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<FunctionDecl>();
return new (Mem) FunctionDecl(L, Id, T, S, isInline, PrevDecl);
return new (Mem) FunctionDecl(CD, L, Id, T, S, isInline, PrevDecl);
}
FieldDecl *FieldDecl::Create(ASTContext &C, SourceLocation L,
FieldDecl *FieldDecl::Create(ASTContext &C, RecordDecl *CD, SourceLocation L,
IdentifierInfo *Id, QualType T, Expr *BW) {
void *Mem = C.getAllocator().Allocate<FieldDecl>();
return new (Mem) FieldDecl(L, Id, T, BW);
return new (Mem) FieldDecl(CD, L, Id, T, BW);
}
EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, SourceLocation L,
EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
SourceLocation L,
IdentifierInfo *Id, QualType T,
Expr *E, const llvm::APSInt &V,
ScopedDecl *PrevDecl){
void *Mem = C.getAllocator().Allocate<EnumConstantDecl>();
return new (Mem) EnumConstantDecl(L, Id, T, E, V, PrevDecl);
return new (Mem) EnumConstantDecl(CD, L, Id, T, E, V, PrevDecl);
}
TypedefDecl *TypedefDecl::Create(ASTContext &C, SourceLocation L,
TypedefDecl *TypedefDecl::Create(ASTContext &C, ContextDecl *CD,
SourceLocation L,
IdentifierInfo *Id, QualType T,
ScopedDecl *PD) {
void *Mem = C.getAllocator().Allocate<TypedefDecl>();
return new (Mem) TypedefDecl(L, Id, T, PD);
return new (Mem) TypedefDecl(CD, L, Id, T, PD);
}
EnumDecl *EnumDecl::Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id,
EnumDecl *EnumDecl::Create(ASTContext &C, ContextDecl *CD, SourceLocation L,
IdentifierInfo *Id,
ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<EnumDecl>();
return new (Mem) EnumDecl(L, Id, PrevDecl);
return new (Mem) EnumDecl(CD, L, Id, PrevDecl);
}
RecordDecl *RecordDecl::Create(ASTContext &C, Kind DK, SourceLocation L,
IdentifierInfo *Id, ScopedDecl *PrevDecl) {
RecordDecl *RecordDecl::Create(ASTContext &C, Kind DK, ContextDecl *CD,
SourceLocation L, IdentifierInfo *Id,
ScopedDecl *PrevDecl) {
void *Mem = C.getAllocator().Allocate<RecordDecl>();
return new (Mem) RecordDecl(DK, L, Id, PrevDecl);
return new (Mem) RecordDecl(DK, CD, L, Id, PrevDecl);
}
FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, SourceLocation L,
FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C,
SourceLocation L,
StringLiteral *Str) {
void *Mem = C.getAllocator().Allocate<FileScopeAsmDecl>();
return new (Mem) FileScopeAsmDecl(L, Str);
}
LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, SourceLocation L,
LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
SourceLocation L,
LanguageIDs Lang, Decl *D) {
void *Mem = C.getAllocator().Allocate<LinkageSpecDecl>();
return new (Mem) LinkageSpecDecl(L, Lang, D);
@ -319,6 +329,25 @@ const Attr *Decl::getAttrs() const {
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
//===----------------------------------------------------------------------===//
@ -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<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
//===----------------------------------------------------------------------===//

View File

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

View File

@ -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<Decl>(getContext())); // From ScopedDecl.
}
void ScopedDecl::ReadInRec(Deserializer& D) {
NamedDecl::ReadInRec(D);
D.ReadPtr(Next); // From ScopedDecl.
Decl *TmpD;
D.ReadPtr(TmpD); // From ScopedDecl.
CtxDecl = cast_or_null<ContextDecl>(TmpD);
}
//===------------------------------------------------------------===//
@ -194,7 +198,7 @@ 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<ObjCDeclQualifier>(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<Expr>();
@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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<Decl*>(ActOnDeclarator(GlobalScope, D, 0));
FunctionDecl *FD = cast<FunctionDecl>(decl);
CurFunctionDecl = FD;
PushContextDecl(FD);
// Create Decl objects for each parameter, adding them to the FunctionDecl.
llvm::SmallVector<ParmVarDecl*, 16> Params;
@ -1104,6 +1121,7 @@ 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<RecordDecl>(TagDecl))
NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth);
if (RecordDecl *RD = dyn_cast<RecordDecl>(TagDecl))
NewFD = FieldDecl::Create(Context, RD, Loc, II, T, BitWidth);
else if (isa<ObjCInterfaceDecl>(TagDecl) ||
isa<ObjCImplementationDecl>(TagDecl) ||
isa<ObjCCategoryDecl>(TagDecl) ||
@ -1335,7 +1354,7 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *tagDecl,
// properties can appear within a protocol.
// See corresponding FIXME in DeclObjC.h:ObjCPropertyDecl.
isa<ObjCProtocolDecl>(TagDecl))
NewFD = ObjCIvarDecl::Create(Context, Loc, II, T);
NewFD = ObjCIvarDecl::Create(Context, dyn_cast<ObjCInterfaceDecl>(TagDecl), Loc, II, T);
else
assert(0 && "Sema::ActOnField(): Unknown TagDecl");
@ -1515,7 +1534,7 @@ 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<EnumDecl>(static_cast<Decl*>(theEnumDecl));
EnumConstantDecl *LastEnumConst =
cast_or_null<EnumConstantDecl>(static_cast<Decl*>(lastEnumConst));
Expr *Val = static_cast<Expr*>(val);
@ -1576,7 +1595,8 @@ 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.

View File

@ -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<ParmVarDecl*, 16> Params;
for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
// FIXME: arg->AttrList must be stored too!
QualType argType;
if (ArgTypes[i])
argType = QualType::getFromOpaquePtr(ArgTypes[i]);
else
argType = Context.getObjCIdType();
ParmVarDecl* Param = ParmVarDecl::Create(Context, SourceLocation(/*FIXME*/),
ArgNames[i], argType,
VarDecl::None, 0);
Param->setObjCDeclQualifier(
CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
Params.push_back(Param);
}
QualType resultDeclType;
if (ReturnType)
@ -845,6 +829,25 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration(
ObjCMethodDecl::Optional :
ObjCMethodDecl::Required);
llvm::SmallVector<ParmVarDecl*, 16> Params;
for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
// FIXME: arg->AttrList must be stored too!
QualType argType;
if (ArgTypes[i])
argType = QualType::getFromOpaquePtr(ArgTypes[i]);
else
argType = Context.getObjCIdType();
ParmVarDecl* Param = ParmVarDecl::Create(Context, ObjCMethod,
SourceLocation(/*FIXME*/),
ArgNames[i], argType,
VarDecl::None, 0);
Param->setObjCDeclQualifier(
CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
Params.push_back(Param);
}
ObjCMethod->setMethodParams(&Params[0], Sel.getNumArgs());
ObjCMethod->setObjCDeclQualifier(
CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));