[clang] Improve LLVM-style RTTI support in ExternalASTSource/ExternalSemaSource
authorRaphael Isemann <teemperor@gmail.com>
Sun, 15 Dec 2019 15:09:20 +0000 (16:09 +0100)
committerRaphael Isemann <risemann@apple.com>
Sun, 15 Dec 2019 17:11:01 +0000 (18:11 +0100)
Summary:
We currently have some very basic LLVM-style RTTI support in the ExternalASTSource class hierarchy
based on the `SemaSource` bool( to discriminate it form the ExternalSemaSource). As ExternalASTSource
is supposed to be subclassed we should have extendable LLVM-style RTTI in this class hierarchy to make life easier
for projects building on top of Clang.

Most notably the current RTTI implementation forces LLDB to implement RTTI for its
own ExternalASTSource class (ClangExternalASTSourceCommon) by keeping a global set of
ExternalASTSources that are known to be ClangExternalASTSourceCommon. Projects
using Clang currently have to dosimilar workarounds to get RTTI support for their subclasses.

This patch turns this into full-fledged LLVM-style RTTI based on a static `ID` variable similar to
other LLVM class hierarchies. Also removes the friend declaration from ExternalASTSource to
its child class that was only used to grant access to the `SemaSource` member.

Reviewers: aprantl, dblaikie, rjmccall

Reviewed By: aprantl

Subscribers: riccibruno, labath, lhames, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D71397

clang/include/clang/AST/ExternalASTSource.h
clang/include/clang/Sema/ExternalSemaSource.h
clang/include/clang/Sema/MultiplexExternalSemaSource.h
clang/lib/AST/ExternalASTSource.cpp
clang/lib/Sema/MultiplexExternalSemaSource.cpp
clang/lib/Sema/Sema.cpp

index 3046336..899ac3f 100644 (file)
@@ -66,9 +66,8 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
   /// whenever we might have added new redeclarations for existing decls.
   uint32_t CurrentGeneration = 0;
 
-  /// Whether this AST source also provides information for
-  /// semantic analysis.
-  bool SemaSource = false;
+  /// LLVM-style RTTI.
+  static char ID;
 
 public:
   ExternalASTSource() = default;
@@ -325,6 +324,12 @@ public:
 
   virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
 
+  /// LLVM-style RTTI.
+  /// \{
+  virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
+  static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
+  /// \}
+
 protected:
   static DeclContextLookupResult
   SetExternalVisibleDeclsForName(const DeclContext *DC,
index 88fa6f5..c79ca0e 100644 (file)
@@ -50,10 +50,11 @@ struct ExternalVTableUse {
 /// external AST sources that also provide information for semantic
 /// analysis.
 class ExternalSemaSource : public ExternalASTSource {
+  /// LLVM-style RTTI.
+  static char ID;
+
 public:
-  ExternalSemaSource() {
-    ExternalASTSource::SemaSource = true;
-  }
+  ExternalSemaSource() = default;
 
   ~ExternalSemaSource() override;
 
@@ -222,10 +223,13 @@ public:
     return false;
   }
 
-  // isa/cast/dyn_cast support
-  static bool classof(const ExternalASTSource *Source) {
-    return Source->SemaSource;
+  /// LLVM-style RTTI.
+  /// \{
+  bool isA(const void *ClassID) const override {
+    return ClassID == &ID || ExternalASTSource::isA(ClassID);
   }
+  static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
+  /// \}
 };
 
 } // end namespace clang
index 8157e48..dcbac9f 100644 (file)
@@ -36,6 +36,8 @@ namespace clang {
 /// external AST sources that also provide information for semantic
 /// analysis.
 class MultiplexExternalSemaSource : public ExternalSemaSource {
+  /// LLVM-style RTTI.
+  static char ID;
 
 private:
   SmallVector<ExternalSemaSource *, 2> Sources; // doesn't own them.
@@ -352,9 +354,13 @@ public:
   bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc,
                                         QualType T) override;
 
-  // isa/cast/dyn_cast support
-  static bool classof(const MultiplexExternalSemaSource*) { return true; }
-  //static bool classof(const ExternalSemaSource*) { return true; }
+  /// LLVM-style RTTI.
+  /// \{
+  bool isA(const void *ClassID) const override {
+    return ClassID == &ID || ExternalSemaSource::isA(ClassID);
+  }
+  static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
+  /// \}
 };
 
 } // end namespace clang
index 7301027..837be55 100644 (file)
@@ -24,6 +24,8 @@
 
 using namespace clang;
 
+char ExternalASTSource::ID;
+
 ExternalASTSource::~ExternalASTSource() = default;
 
 llvm::Optional<ExternalASTSource::ASTSourceDescriptor>
index b0aa674..2b0cd6b 100644 (file)
@@ -15,6 +15,8 @@
 
 using namespace clang;
 
+char MultiplexExternalSemaSource::ID;
+
 ///Constructs a new multiplexing external sema source and appends the
 /// given element to it.
 ///
index c5bf6fe..2cd158a 100644 (file)
@@ -1917,6 +1917,7 @@ void Sema::ActOnComment(SourceRange Comment) {
 
 // Pin this vtable to this file.
 ExternalSemaSource::~ExternalSemaSource() {}
+char ExternalSemaSource::ID;
 
 void ExternalSemaSource::ReadMethodPool(Selector Sel) { }
 void ExternalSemaSource::updateOutOfDateSelector(Selector Sel) { }