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));
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);
}
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);
}
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);
}
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);
}
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");
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);
}
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);
}
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");
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);
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);
}
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);
}
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);
}
// 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());
// 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];
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);
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];
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);
#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 {
///
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; }
// 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;
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; }
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; }
/// 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.
/// 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.
/// 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 {
/// 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
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);
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; }
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;
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; }
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) {
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; }
/// 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:
/// 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
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;
}
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; }
--- /dev/null
+//===-- 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
/// 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:
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)),
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,
/// 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;
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),
}
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);
/// }
///
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 {
ObjCProtocolDecl **ReferencedProtocols;
unsigned NumReferencedProtocols;
- ObjCForwardProtocolDecl(SourceLocation L,
+ ObjCForwardProtocolDecl(SourceLocation L,
ObjCProtocolDecl **Elts, unsigned nElts)
: Decl(ObjCForwardProtocol, L) {
NumReferencedProtocols = nElts;
}
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; }
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; }
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);
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; }
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];
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);
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;
// 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);
}
//===----------------------------------------------------------------------===//
-// NamedDecl Implementation
+// ContextDecl Implementation
//===----------------------------------------------------------------------===//
-const char *NamedDecl::getName() const {
- if (const IdentifierInfo *II = getIdentifier())
- return II->getName();
- return "";
+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);
}
//===----------------------------------------------------------------------===//
-// ScopedDecl Implementation
+// NamedDecl 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;
+const char *NamedDecl::getName() const {
+ if (const IdentifierInfo *II = getIdentifier())
+ return II->getName();
+ return "";
}
//===----------------------------------------------------------------------===//
// 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,
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) {
}
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);
}
}
+
default:
assert (false && "Not implemented.");
break;
-
+
case BlockVar:
return BlockVarDecl::CreateImpl(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);
}
//===------------------------------------------------------------===//
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);
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);
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());
}
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());
D.Read(val);
EnumConstantDecl* decl =
- new EnumConstantDecl(SourceLocation(),NULL,QualType(),NULL,
+ new EnumConstantDecl(0, SourceLocation(),NULL,QualType(),NULL,
val,NULL);
decl->ValueDecl::ReadInRec(D);
}
FieldDecl* FieldDecl::CreateImpl(Deserializer& D) {
- FieldDecl* decl = new FieldDecl(SourceLocation(), NULL, QualType(), 0);
+ FieldDecl* decl = new FieldDecl(0, SourceLocation(), NULL, QualType(), 0);
decl->DeclType.ReadBackpatch(D);
decl->ReadInRec(D);
decl->BitWidth = D.ReadOwnedPtr<Expr>();
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);
}
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());
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);
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);
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);
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.
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);
// 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);
class ASTConsumer;
class Preprocessor;
class Decl;
+ class ContextDecl;
class NamedDecl;
class ScopedDecl;
class Expr;
/// 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.
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);
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!");
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.
}
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.
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
} 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)
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;
MD->setBody((Stmt*)Body);
CurMethodDecl = 0;
}
+ PopContextDecl();
// Verify and clean out per-function state.
// Check goto/label use.
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())
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;
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;
}
// 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) ||
// 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");
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);
}
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.
// 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.
Diag(MethodLoc, diag::error_missing_method_context);
return 0;
}
+ QualType resultDeclType;
+
+ if (ReturnType)
+ resultDeclType = QualType::getFromOpaquePtr(ReturnType);
+ else // get the type for "id".
+ resultDeclType = Context.getObjCIdType();
+
+ ObjCMethodDecl* ObjCMethod =
+ ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
+ ClassDecl, AttrList,
+ MethodType == tok::minus, isVariadic,
+ MethodDeclKind == tok::objc_optional ?
+ ObjCMethodDecl::Optional :
+ ObjCMethodDecl::Required);
+
llvm::SmallVector<ParmVarDecl*, 16> Params;
for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
argType = QualType::getFromOpaquePtr(ArgTypes[i]);
else
argType = Context.getObjCIdType();
- ParmVarDecl* Param = ParmVarDecl::Create(Context, SourceLocation(/*FIXME*/),
+ ParmVarDecl* Param = ParmVarDecl::Create(Context, ObjCMethod,
+ SourceLocation(/*FIXME*/),
ArgNames[i], argType,
VarDecl::None, 0);
Param->setObjCDeclQualifier(
CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
Params.push_back(Param);
}
- QualType resultDeclType;
-
- if (ReturnType)
- resultDeclType = QualType::getFromOpaquePtr(ReturnType);
- else // get the type for "id".
- resultDeclType = Context.getObjCIdType();
-
- ObjCMethodDecl* ObjCMethod =
- ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
- ClassDecl, AttrList,
- MethodType == tok::minus, isVariadic,
- MethodDeclKind == tok::objc_optional ?
- ObjCMethodDecl::Optional :
- ObjCMethodDecl::Required);
-
+
ObjCMethod->setMethodParams(&Params[0], Sel.getNumArgs());
ObjCMethod->setObjCDeclQualifier(
CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));