]> granicus.if.org Git - clang/commitdiff
Make DeclContexts maintenance a bit easier.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 16 Feb 2009 14:28:33 +0000 (14:28 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 16 Feb 2009 14:28:33 +0000 (14:28 +0000)
-In DeclNodes.def, only mark as DeclContexts the top classes that directly derive from DeclContext. If the Decl has subclasses,
 it should be marked with DECL_CONTEXT_BASE.

-Use DeclNodes.def to automate the DeclContext::classof and DeclContext::CastTo definitions.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64629 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclBase.h
include/clang/AST/DeclNodes.def
lib/AST/DeclBase.cpp

index 89ef3b86c818436cc5a7a69db40fd7c32dc52fd8..8172ab22c734c87c106d0a473a1b396b9d99a0a9 100644 (file)
@@ -326,17 +326,20 @@ protected:
 };
 
 /// DeclContext - This is used only as base class of specific decl types that
-/// can act as declaration contexts. These decls are:
+/// can act as declaration contexts. These decls are (only the top classes
+/// that directly derive from DeclContext are mentioned, not their subclasses):
 ///
 ///   TranslationUnitDecl
 ///   NamespaceDecl
 ///   FunctionDecl
-///   RecordDecl/CXXRecordDecl
-///   EnumDecl
+///   TagDecl
 ///   ObjCMethodDecl
-///   ObjCInterfaceDecl
+///   ObjCContainerDecl
+///   ObjCCategoryImplDecl
+///   ObjCImplementationDecl
 ///   LinkageSpecDecl
 ///   BlockDecl
+///
 class DeclContext {
   /// DeclKind - This indicates which class this is.
   Decl::Kind DeclKind   :  8;
@@ -380,36 +383,16 @@ class DeclContext {
   static To *CastTo(const From *D) {
     Decl::Kind DK = KindTrait<From>::getKind(D);
     switch(DK) {
-      case Decl::TranslationUnit:
-        return static_cast<TranslationUnitDecl*>(const_cast<From*>(D));
-      case Decl::Namespace:
-        return static_cast<NamespaceDecl*>(const_cast<From*>(D));
-      case Decl::Enum:
-        return static_cast<EnumDecl*>(const_cast<From*>(D));
-      case Decl::Record:
-        return static_cast<RecordDecl*>(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:
-        return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
-      case Decl::ObjCCategory:
-        return static_cast<ObjCCategoryDecl*>(const_cast<From*>(D));
-      case Decl::ObjCProtocol:
-        return static_cast<ObjCProtocolDecl*>(const_cast<From*>(D));
-      case Decl::ObjCImplementation:
-        return static_cast<ObjCImplementationDecl*>(const_cast<From*>(D));
-      case Decl::ObjCCategoryImpl:
-        return static_cast<ObjCCategoryImplDecl*>(const_cast<From*>(D));
-      case Decl::LinkageSpec:
-        return static_cast<LinkageSpecDecl*>(const_cast<From*>(D));
-      case Decl::Block:
-        return static_cast<BlockDecl*>(const_cast<From*>(D));
+#define DECL_CONTEXT(Name) \
+      case Decl::Name:     \
+        return static_cast<Name##Decl*>(const_cast<From*>(D));
+#define DECL_CONTEXT_BASE(Name)
+#include "clang/AST/DeclNodes.def"
       default:
-        if (DK >= Decl::FunctionFirst && DK <= Decl::FunctionLast)
-          return static_cast<FunctionDecl*>(const_cast<From*>(D));
-
+#define DECL_CONTEXT_BASE(Name)                                   \
+        if (DK >= Decl::Name##First && DK <= Decl::Name##Last)    \
+          return static_cast<Name##Decl*>(const_cast<From*>(D));
+#include "clang/AST/DeclNodes.def"
         assert(false && "a decl that inherits DeclContext isn't handled");
         return 0;
     }
@@ -800,12 +783,15 @@ public:
   static bool classof(const Decl *D) {
     switch (D->getKind()) {
 #define DECL_CONTEXT(Name) case Decl::Name:
+#define DECL_CONTEXT_BASE(Name)
 #include "clang/AST/DeclNodes.def"
         return true;
       default:
-        if (D->getKind() >= Decl::FunctionFirst &&
-            D->getKind() <= Decl::FunctionLast)
+#define DECL_CONTEXT_BASE(Name)                   \
+        if (D->getKind() >= Decl::Name##First &&  \
+            D->getKind() <= Decl::Name##Last)     \
           return true;
+#include "clang/AST/DeclNodes.def"
         return false;
     }
   }
index 602c37e5e68893b25ef69ff389788502ca86dd5c..a22fa70b8b5afe86ac74b7a287c0e9411b1396f9 100644 (file)
 #  define DECL_CONTEXT(Decl)
 #endif
 
+#ifndef DECL_CONTEXT_BASE
+#  define DECL_CONTEXT_BASE(Decl) DECL_CONTEXT(Decl)
+#endif
+
 #ifndef LAST_DECL_CONTEXT
 #  define LAST_DECL_CONTEXT(Decl) DECL_CONTEXT(Decl)
 #endif
@@ -117,21 +121,16 @@ DECL(ObjCClass, Decl)
 DECL(FileScopeAsm, Decl)
 LAST_DECL(Block, Decl)
 
-// Declaration contexts
+// Declaration contexts. DECL_CONTEXT_BASE indicates that it has subclasses.
 DECL_CONTEXT(TranslationUnit)
 DECL_CONTEXT(Namespace)
-DECL_CONTEXT(Enum)
-DECL_CONTEXT(Record)
-DECL_CONTEXT(CXXRecord)
-DECL_CONTEXT(Function)
+DECL_CONTEXT(LinkageSpec)
 DECL_CONTEXT(ObjCMethod)
-DECL_CONTEXT(ObjCContainer)
-DECL_CONTEXT(ObjCInterface)
-DECL_CONTEXT(ObjCProtocol)
-DECL_CONTEXT(ObjCCategory)
 DECL_CONTEXT(ObjCCategoryImpl)
-DECL_CONTEXT(LinkageSpec)
 DECL_CONTEXT(ObjCImplementation)
+DECL_CONTEXT_BASE(Tag)
+DECL_CONTEXT_BASE(Function)
+DECL_CONTEXT_BASE(ObjCContainer)
 LAST_DECL_CONTEXT(Block)
 
 // Declaration ranges
@@ -149,6 +148,7 @@ LAST_DECL_RANGE(Var, Var, NonTypeTemplateParm)
 #undef LAST_DECL_RANGE
 #undef DECL_RANGE
 #undef LAST_DECL_CONTEXT
+#undef DECL_CONTEXT_BASE
 #undef DECL_CONTEXT
 #undef ABSTRACT_DECL
 #undef LAST_DECL
index 1e3683c85761a0487f54dfd1993f3d54bba5e2c4..91f2bf2765e305c1d56bcbdfb69fd2dfc382b967 100644 (file)
@@ -50,7 +50,7 @@ const char *Decl::getDeclKindName() const {
 const char *DeclContext::getDeclKindName() const {
   switch (DeclKind) {
   default: assert(0 && "Declaration context not in DeclNodes.def!");
-#define DECL_CONTEXT(Node) case Decl::Node: return #Node;
+#define DECL(Derived, Base) case Decl::Derived: return #Derived;
 #include "clang/AST/DeclNodes.def"
   }
 }