]> granicus.if.org Git - clang/commitdiff
Simplify handling of struct/union/class tags.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 15 Oct 2008 00:42:39 +0000 (00:42 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 15 Oct 2008 00:42:39 +0000 (00:42 +0000)
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
include/clang/AST/DeclBase.h
include/clang/AST/DeclCXX.h
include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
lib/AST/Decl.cpp
lib/AST/DeclBase.cpp
lib/AST/DeclCXX.cpp
lib/AST/DeclSerialization.cpp
lib/AST/StmtDumper.cpp
lib/CodeGen/CGDecl.cpp

index e18cfc59e3c2a344d7e6c52aa0c645ff58ba1b3b..be8d842525bcbf350b9f033624ffa3df6b77ff53 100644 (file)
@@ -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);
 };
index f278b71fdfac00151f30d858bd51ffec0fc347e2..a1239deea4a857bde43151141d9790ea26b28eba 100644 (file)
@@ -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;
     }
   }
index e8beb62d7e40364b07634a02fdc5d124d6f3ab91..2ce4956a1d476968dfdba91eb9ab27d20378df26 100644 (file)
@@ -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));
index 49850a7d6fb0eb39949ae5562f21afef2c25676a..e24359d4ac3476047591fb40660f173806552659 100644 (file)
@@ -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.");
index 382b9ebd512f6e23c2fab7857a262afe66e7c248..3713776298a9f67c3193bf7cfcf999d420d54a19 100644 (file)
@@ -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;
 }
index 265913ccc017b5f943c68a9e9a9df27ec96322b8..75d6bc6ce9a7b27fe45b162a08d7dcc29cc98cb3 100644 (file)
@@ -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:
index 3f937914add186619d552a95ca2526bd3ef30a61..af89da44cc39f97d1162753d5f341c1615eef634 100644 (file)
@@ -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;
 }
index 718885b2b568b2a7e6fd4b6dec8d11d026150328..a0befbdbb0852fc756b61f8c815ae5e753760bdc 100644 (file)
@@ -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());
index dd92e84e9d271fdccdcc2057c74bbbcd5c34acbd..666cad6260397782e6c438c509bb3ab5c5d05c05 100644 (file)
@@ -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;
index 6ab227d95a8f406b648ea3254c20b86ea26e2eb7..57e9c39832f52ae63c5fc70ff73454fcda0a2e0b 100644 (file)
@@ -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;