From 35bc0821c4f80041724cd4c5c4889b2581546a41 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 15 Oct 2008 00:42:39 +0000 Subject: [PATCH] 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 --- include/clang/AST/Decl.h | 30 ++++++++--------- include/clang/AST/DeclBase.h | 33 ++++++------------- include/clang/AST/DeclCXX.h | 12 +++---- .../Analysis/Visitors/CFGRecStmtDeclVisitor.h | 4 +-- lib/AST/Decl.cpp | 15 ++------- lib/AST/DeclBase.cpp | 9 +++-- lib/AST/DeclCXX.cpp | 10 +----- lib/AST/DeclSerialization.cpp | 14 ++++---- lib/AST/StmtDumper.cpp | 8 ++--- lib/CodeGen/CGDecl.cpp | 8 ++--- 10 files changed, 49 insertions(+), 94 deletions(-) diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index e18cfc59e3..be8d842525 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -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); }; diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index f278b71fdf..a1239deea4 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -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(const_cast(D)); case Decl::Enum: return static_cast(const_cast(D)); + case Decl::CXXRecord: + return static_cast(const_cast(D)); case Decl::ObjCMethod: return static_cast(const_cast(D)); case Decl::ObjCInterface: @@ -285,8 +276,6 @@ class DeclContext { default: if (DK >= Decl::FunctionFirst && DK <= Decl::FunctionLast) return static_cast(const_cast(D)); - if (DK >= Decl::CXXRecordFirst && DK <= Decl::CXXRecordLast) - return static_cast(const_cast(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; } } diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index e8beb62d7e..2ce4956a1d 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -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(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(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(const_cast(D)); diff --git a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h index 49850a7d6f..e24359d4ac 100644 --- a/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h +++ b/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h @@ -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."); diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 382b9ebd51..3713776298 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -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(this)) && "Invalid Kind!"); @@ -236,16 +236,7 @@ RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, RecordDecl* PrevDecl) { void *Mem = C.getAllocator().Allocate(); - 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; } diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 265913ccc0..75d6bc6ce9 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -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: diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 3f937914ad..af89da44cc 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -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* R = new (Mem) CXXRecordDecl(DK, DC, L, Id); + CXXRecordDecl* R = new (Mem) CXXRecordDecl(TK, DC, L, Id); C.getTypeDeclType(R, PrevDecl); return R; } diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp index 718885b2b5..a0befbdbb0 100644 --- a/lib/AST/DeclSerialization.cpp +++ b/lib/AST/DeclSerialization.cpp @@ -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* 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()); diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp index dd92e84e9d..666cad6260 100644 --- a/lib/AST/StmtDumper.cpp +++ b/lib/AST/StmtDumper.cpp @@ -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; diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 6ab227d95a..57e9c39832 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -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; -- 2.40.0