зеркало из https://github.com/microsoft/clang-1.git
Simplify handling of struct/union/class tags.
Instead of using two sets of Decl kinds (Struct/Union/Class and CXXStruct/CXXUnion/CXXClass), use one 'Record' and one 'CXXRecord' Decl kind and make tag kind a property of TagDecl. Cleans up the code a bit and better reflects that Decl class structure. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57541 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
00231ee34c
Коммит
35bc0821c4
|
@ -728,13 +728,18 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
/// TagDeclKind - The TagKind enum.
|
||||
unsigned TagDeclKind : 2;
|
||||
|
||||
/// IsDefinition - True if this is a definition ("struct foo {};"), false if
|
||||
/// it is a declaration ("struct foo;").
|
||||
bool IsDefinition : 1;
|
||||
protected:
|
||||
TagDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
||||
TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
|
||||
IdentifierInfo *Id, ScopedDecl *PrevDecl)
|
||||
: TypeDecl(DK, DC, L, Id, PrevDecl) {
|
||||
assert((DK != Enum || TK == TK_enum) &&"EnumDecl not matched with TK_enum");
|
||||
TagDeclKind = TK;
|
||||
IsDefinition = false;
|
||||
}
|
||||
public:
|
||||
|
@ -764,19 +769,13 @@ public:
|
|||
}
|
||||
|
||||
TagKind getTagKind() const {
|
||||
switch (getKind()) {
|
||||
default: assert(0 && "Unknown TagDecl!");
|
||||
case Struct: case CXXStruct: return TK_struct;
|
||||
case Union: case CXXUnion: return TK_union;
|
||||
case Class: case CXXClass: return TK_class;
|
||||
case Enum: return TK_enum;
|
||||
}
|
||||
return TagKind(TagDeclKind);
|
||||
}
|
||||
|
||||
bool isStruct() const { return getKind() == Struct || getKind() == CXXStruct;}
|
||||
bool isClass() const { return getKind() == Class || getKind() == CXXClass; }
|
||||
bool isUnion() const { return getKind() == Union || getKind() == CXXUnion; }
|
||||
bool isEnum() const { return getKind() == Enum; }
|
||||
bool isStruct() const { return getTagKind() == TK_struct; }
|
||||
bool isClass() const { return getTagKind() == TK_class; }
|
||||
bool isUnion() const { return getTagKind() == TK_union; }
|
||||
bool isEnum() const { return getTagKind() == TK_enum; }
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) {
|
||||
|
@ -800,7 +799,7 @@ class EnumDecl : public TagDecl, public DeclContext {
|
|||
|
||||
EnumDecl(DeclContext *DC, SourceLocation L,
|
||||
IdentifierInfo *Id, ScopedDecl *PrevDecl)
|
||||
: TagDecl(Enum, DC, L, Id, PrevDecl), DeclContext(Enum) {
|
||||
: TagDecl(Enum, TK_enum, DC, L, Id, PrevDecl), DeclContext(Enum) {
|
||||
IntegerType = QualType();
|
||||
}
|
||||
public:
|
||||
|
@ -870,7 +869,8 @@ class RecordDecl : public TagDecl {
|
|||
int NumMembers; // -1 if not defined.
|
||||
|
||||
protected:
|
||||
RecordDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id);
|
||||
RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
|
||||
SourceLocation L, IdentifierInfo *Id);
|
||||
virtual ~RecordDecl();
|
||||
|
||||
public:
|
||||
|
@ -941,7 +941,7 @@ protected:
|
|||
virtual void EmitImpl(llvm::Serializer& S) const;
|
||||
|
||||
/// CreateImpl - Deserialize a RecordDecl. Called by Decl::Create.
|
||||
static RecordDecl* CreateImpl(Kind DK, llvm::Deserializer& D, ASTContext& C);
|
||||
static RecordDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
|
||||
|
||||
friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
|
||||
};
|
||||
|
|
|
@ -59,14 +59,8 @@ public:
|
|||
Typedef,
|
||||
// TagDecl
|
||||
Enum, // [DeclContext]
|
||||
// RecordDecl
|
||||
Struct,
|
||||
Union,
|
||||
Class,
|
||||
// CXXRecordDecl [DeclContext]
|
||||
CXXStruct,
|
||||
CXXUnion,
|
||||
CXXClass,
|
||||
Record,
|
||||
CXXRecord, // [DeclContext]
|
||||
// ValueDecl
|
||||
EnumConstant,
|
||||
Function, // [DeclContext]
|
||||
|
@ -90,10 +84,9 @@ public:
|
|||
NamedFirst = Field , NamedLast = ParmVar,
|
||||
FieldFirst = Field , FieldLast = ObjCAtDefsField,
|
||||
ScopedFirst = Namespace , ScopedLast = ParmVar,
|
||||
TypeFirst = Typedef , TypeLast = CXXClass,
|
||||
TagFirst = Enum , TagLast = CXXClass,
|
||||
RecordFirst = Struct , RecordLast = CXXClass,
|
||||
CXXRecordFirst = CXXStruct , CXXRecordLast = CXXClass,
|
||||
TypeFirst = Typedef , TypeLast = CXXRecord,
|
||||
TagFirst = Enum , TagLast = CXXRecord,
|
||||
RecordFirst = Record , RecordLast = CXXRecord,
|
||||
ValueFirst = EnumConstant , ValueLast = ParmVar,
|
||||
FunctionFirst = Function , FunctionLast = CXXMethod,
|
||||
VarFirst = Var , VarLast = ParmVar
|
||||
|
@ -189,12 +182,8 @@ public:
|
|||
case CXXMethod:
|
||||
case CXXClassVar:
|
||||
return IDNS_Ordinary;
|
||||
case Struct:
|
||||
case Union:
|
||||
case Class:
|
||||
case CXXStruct:
|
||||
case CXXUnion:
|
||||
case CXXClass:
|
||||
case Record:
|
||||
case CXXRecord:
|
||||
case Enum:
|
||||
return IDNS_Tag;
|
||||
case Namespace:
|
||||
|
@ -278,6 +267,8 @@ class DeclContext {
|
|||
return static_cast<NamespaceDecl*>(const_cast<From*>(D));
|
||||
case Decl::Enum:
|
||||
return static_cast<EnumDecl*>(const_cast<From*>(D));
|
||||
case Decl::CXXRecord:
|
||||
return static_cast<CXXRecordDecl*>(const_cast<From*>(D));
|
||||
case Decl::ObjCMethod:
|
||||
return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
|
||||
case Decl::ObjCInterface:
|
||||
|
@ -285,8 +276,6 @@ class DeclContext {
|
|||
default:
|
||||
if (DK >= Decl::FunctionFirst && DK <= Decl::FunctionLast)
|
||||
return static_cast<FunctionDecl*>(const_cast<From*>(D));
|
||||
if (DK >= Decl::CXXRecordFirst && DK <= Decl::CXXRecordLast)
|
||||
return static_cast<CXXRecordDecl*>(const_cast<From*>(D));
|
||||
|
||||
assert(false && "a decl that inherits DeclContext isn't handled");
|
||||
return 0;
|
||||
|
@ -325,6 +314,7 @@ public:
|
|||
case Decl::TranslationUnit:
|
||||
case Decl::Namespace:
|
||||
case Decl::Enum:
|
||||
case Decl::CXXRecord:
|
||||
case Decl::ObjCMethod:
|
||||
case Decl::ObjCInterface:
|
||||
case Decl::Block:
|
||||
|
@ -333,9 +323,6 @@ public:
|
|||
if (D->getKind() >= Decl::FunctionFirst &&
|
||||
D->getKind() <= Decl::FunctionLast)
|
||||
return true;
|
||||
if (D->getKind() >= Decl::CXXRecordFirst &&
|
||||
D->getKind() <= Decl::CXXRecordLast)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,11 +42,9 @@ public:
|
|||
/// CXXRecordDecl - Represents a C++ struct/union/class.
|
||||
/// The only difference with RecordDecl is that CXXRecordDecl is a DeclContext.
|
||||
class CXXRecordDecl : public RecordDecl, public DeclContext {
|
||||
protected:
|
||||
CXXRecordDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
|
||||
: RecordDecl(DK, DC, L, Id), DeclContext(DK) {
|
||||
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
|
||||
}
|
||||
CXXRecordDecl(TagKind TK, DeclContext *DC,
|
||||
SourceLocation L, IdentifierInfo *Id)
|
||||
: RecordDecl(CXXRecord, TK, DC, L, Id), DeclContext(CXXRecord) {}
|
||||
public:
|
||||
static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
|
||||
SourceLocation L, IdentifierInfo *Id,
|
||||
|
@ -65,9 +63,7 @@ public:
|
|||
return cast_or_null<CXXFieldDecl>(RecordDecl::getMember(name));
|
||||
}
|
||||
|
||||
static bool classof(const Decl *D) {
|
||||
return D->getKind() >= CXXRecordFirst && D->getKind() <= CXXRecordLast;
|
||||
}
|
||||
static bool classof(const Decl *D) { return D->getKind() == CXXRecord; }
|
||||
static bool classof(const CXXRecordDecl *D) { return true; }
|
||||
static DeclContext *castToDeclContext(const CXXRecordDecl *D) {
|
||||
return static_cast<DeclContext *>(const_cast<CXXRecordDecl*>(D));
|
||||
|
|
|
@ -61,9 +61,7 @@ public:
|
|||
DISPATCH_CASE(ImplicitParam,ImplicitParamDecl)
|
||||
DISPATCH_CASE(EnumConstant,EnumConstantDecl)
|
||||
DISPATCH_CASE(Typedef,TypedefDecl)
|
||||
DISPATCH_CASE(Struct,RecordDecl) // FIXME: Refine. VisitStructDecl?
|
||||
DISPATCH_CASE(Union,RecordDecl) // FIXME: Refine.
|
||||
DISPATCH_CASE(Class,RecordDecl) // FIXME: Refine.
|
||||
DISPATCH_CASE(Record,RecordDecl) // FIXME: Refine. VisitStructDecl?
|
||||
DISPATCH_CASE(Enum,EnumDecl)
|
||||
default:
|
||||
assert(false && "Subtype of ScopedDecl not handled.");
|
||||
|
|
|
@ -221,9 +221,9 @@ TagDecl* TagDecl::getDefinition(ASTContext& C) const {
|
|||
// RecordDecl Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
RecordDecl::RecordDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
||||
RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
|
||||
IdentifierInfo *Id)
|
||||
: TagDecl(DK, DC, L, Id, 0) {
|
||||
: TagDecl(DK, TK, DC, L, Id, 0) {
|
||||
|
||||
HasFlexibleArrayMember = false;
|
||||
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
|
||||
|
@ -236,16 +236,7 @@ RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
|
|||
RecordDecl* PrevDecl) {
|
||||
|
||||
void *Mem = C.getAllocator().Allocate<RecordDecl>();
|
||||
Kind DK;
|
||||
switch (TK) {
|
||||
default: assert(0 && "Invalid TagKind!");
|
||||
case TK_enum: assert(0 && "Enum TagKind passed for Record!");
|
||||
case TK_struct: DK = Struct; break;
|
||||
case TK_union: DK = Union; break;
|
||||
case TK_class: DK = Class; break;
|
||||
}
|
||||
|
||||
RecordDecl* R = new (Mem) RecordDecl(DK, DC, L, Id);
|
||||
RecordDecl* R = new (Mem) RecordDecl(Record, TK, DC, L, Id);
|
||||
C.getTypeDeclType(R, PrevDecl);
|
||||
return R;
|
||||
}
|
||||
|
|
|
@ -74,9 +74,8 @@ const char *Decl::getDeclKindName() const {
|
|||
case ObjCMethod: return "ObjCMethod";
|
||||
case ObjCProtocol: return "ObjCProtocol";
|
||||
case ObjCForwardProtocol: return "ObjCForwardProtocol";
|
||||
case Struct: return "Struct";
|
||||
case Union: return "Union";
|
||||
case Class: return "Class";
|
||||
case Record: return "Record";
|
||||
case CXXRecord: return "CXXRecord";
|
||||
case Enum: return "Enum";
|
||||
case Block: return "Block";
|
||||
}
|
||||
|
@ -206,7 +205,7 @@ void Decl::addDeclKind(Kind k) {
|
|||
case ParmVar: nParmVars++; break;
|
||||
case EnumConstant: nEnumConst++; break;
|
||||
case Field: nFieldDecls++; break;
|
||||
case Struct: case Union: case Class: nSUC++; break;
|
||||
case Record: nSUC++; break;
|
||||
case Enum: nEnumDecls++; break;
|
||||
case ObjCInterface: nInterfaceDecls++; break;
|
||||
case ObjCClass: nClassDecls++; break;
|
||||
|
@ -228,7 +227,7 @@ void Decl::addDeclKind(Kind k) {
|
|||
case TranslationUnit: break;
|
||||
|
||||
case CXXField: nCXXFieldDecls++; break;
|
||||
case CXXStruct: case CXXUnion: case CXXClass: nCXXSUC++; break;
|
||||
case CXXRecord: nCXXSUC++; break;
|
||||
// FIXME: Statistics for C++ decls.
|
||||
case CXXMethod:
|
||||
case CXXClassVar:
|
||||
|
|
|
@ -29,16 +29,8 @@ CXXFieldDecl *CXXFieldDecl::Create(ASTContext &C, CXXRecordDecl *RD,
|
|||
CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
|
||||
SourceLocation L, IdentifierInfo *Id,
|
||||
CXXRecordDecl* PrevDecl) {
|
||||
Kind DK;
|
||||
switch (TK) {
|
||||
default: assert(0 && "Invalid TagKind!");
|
||||
case TK_enum: assert(0 && "Enum TagKind passed for Record!");
|
||||
case TK_struct: DK = CXXStruct; break;
|
||||
case TK_union: DK = CXXUnion; break;
|
||||
case TK_class: DK = CXXClass; break;
|
||||
}
|
||||
void *Mem = C.getAllocator().Allocate<CXXRecordDecl>();
|
||||
CXXRecordDecl* R = new (Mem) CXXRecordDecl(DK, DC, L, Id);
|
||||
CXXRecordDecl* R = new (Mem) CXXRecordDecl(TK, DC, L, Id);
|
||||
C.getTypeDeclType(R, PrevDecl);
|
||||
return R;
|
||||
}
|
||||
|
|
|
@ -75,10 +75,8 @@ Decl* Decl::Create(Deserializer& D, ASTContext& C) {
|
|||
Dcl = FunctionDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case Class:
|
||||
case Union:
|
||||
case Struct:
|
||||
Dcl = RecordDecl::CreateImpl(k, D, C);
|
||||
case Record:
|
||||
Dcl = RecordDecl::CreateImpl(D, C);
|
||||
break;
|
||||
|
||||
case Typedef:
|
||||
|
@ -461,6 +459,8 @@ BlockDecl* BlockDecl::CreateImpl(Deserializer& D, ASTContext& C) {
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void RecordDecl::EmitImpl(Serializer& S) const {
|
||||
S.EmitInt(getTagKind());
|
||||
|
||||
ScopedDecl::EmitInRec(S);
|
||||
S.EmitBool(isDefinition());
|
||||
S.EmitBool(hasFlexibleArrayMember());
|
||||
|
@ -473,11 +473,11 @@ void RecordDecl::EmitImpl(Serializer& S) const {
|
|||
ScopedDecl::EmitOutRec(S);
|
||||
}
|
||||
|
||||
RecordDecl* RecordDecl::CreateImpl(Decl::Kind DK, Deserializer& D,
|
||||
ASTContext& C) {
|
||||
RecordDecl* RecordDecl::CreateImpl(Deserializer& D, ASTContext& C) {
|
||||
TagKind TK = TagKind(D.ReadInt());
|
||||
|
||||
void *Mem = C.getAllocator().Allocate<RecordDecl>();
|
||||
RecordDecl* decl = new (Mem) RecordDecl(DK, 0, SourceLocation(), NULL);
|
||||
RecordDecl* decl = new (Mem) RecordDecl(Record, TK, 0, SourceLocation(), NULL);
|
||||
|
||||
decl->ScopedDecl::ReadInRec(D, C);
|
||||
decl->setDefinition(D.ReadBool());
|
||||
|
|
|
@ -284,13 +284,9 @@ void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
|
|||
case Decl::ParmVar: fprintf(F,"ParmVar"); break;
|
||||
case Decl::EnumConstant: fprintf(F,"EnumConstant"); break;
|
||||
case Decl::Typedef: fprintf(F,"Typedef"); break;
|
||||
case Decl::Struct: fprintf(F,"Struct"); break;
|
||||
case Decl::Union: fprintf(F,"Union"); break;
|
||||
case Decl::Class: fprintf(F,"Class"); break;
|
||||
case Decl::Record: fprintf(F,"Record"); break;
|
||||
case Decl::Enum: fprintf(F,"Enum"); break;
|
||||
case Decl::CXXStruct: fprintf(F,"CXXStruct"); break;
|
||||
case Decl::CXXUnion: fprintf(F,"CXXUnion"); break;
|
||||
case Decl::CXXClass: fprintf(F,"CXXClass"); break;
|
||||
case Decl::CXXRecord: fprintf(F,"CXXRecord"); break;
|
||||
case Decl::ObjCInterface: fprintf(F,"ObjCInterface"); break;
|
||||
case Decl::ObjCClass: fprintf(F,"ObjCClass"); break;
|
||||
default: fprintf(F,"Decl"); break;
|
||||
|
|
|
@ -33,14 +33,10 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
|
|||
assert(0 && "Parmdecls should not be in declstmts!");
|
||||
case Decl::Typedef: // typedef int X;
|
||||
case Decl::Function: // void X();
|
||||
case Decl::Struct: // struct X;
|
||||
case Decl::Union: // union X;
|
||||
case Decl::Class: // class X;
|
||||
case Decl::Record: // struct/union/class X;
|
||||
case Decl::Enum: // enum X;
|
||||
case Decl::EnumConstant: // enum ? { X = ? }
|
||||
case Decl::CXXStruct: // struct X; [C++]
|
||||
case Decl::CXXUnion: // union X; [C++]
|
||||
case Decl::CXXClass: // class X; [C++]
|
||||
case Decl::CXXRecord: // struct/union/class X; [C++]
|
||||
// None of these decls require codegen support.
|
||||
return;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче