зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
c8aa5f1f26
Коммит
0ed844b04e
|
@ -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);
|
||||
|
|
|
@ -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,7 +82,12 @@ 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) {
|
||||
|
@ -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; }
|
||||
|
|
|
@ -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
|
||||
/// 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 {
|
||||
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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,
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
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);
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace clang {
|
|||
class ASTConsumer;
|
||||
class Preprocessor;
|
||||
class Decl;
|
||||
class ContextDecl;
|
||||
class NamedDecl;
|
||||
class ScopedDecl;
|
||||
class Expr;
|
||||
|
@ -74,6 +75,8 @@ class Sema : public Action {
|
|||
/// 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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()));
|
||||
|
|
Загрузка…
Ссылка в новой задаче