[llvm-branch-commits] [clang-tools-extra] [clang-doc] Clean up implementation with better casting (PR #202060)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Jun 6 09:35:20 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tools-extra

Author: Paul Kirth (ilovepi)

<details>
<summary>Changes</summary>

Having access to RTTI style casting lets us use slightly nicer
structures to clean up the overly complicated dispatch logic in merging
and other places.

---
Full diff: https://github.com/llvm/llvm-project/pull/202060.diff


2 Files Affected:

- (modified) clang-tools-extra/clang-doc/Representation.cpp (+19-60) 
- (modified) clang-tools-extra/clang-doc/Representation.h (-5) 


``````````diff
diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp
index 0284f5a70615f..bd363dc42f805 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -180,83 +180,42 @@ void mergeUnkeyed<CommentInfo>(DocList<CommentInfo> &Target,
   }
 }
 
+template <typename T>
+static llvm::Error mergeTypedInfo(Info *&Reduced, Info *NewInfo,
+                           llvm::BumpPtrAllocator &Arena) {
+  if (!Reduced)
+    Reduced = allocatePtr<T>(Arena, NewInfo->USR);
+  cast<T>(Reduced)->merge(std::move(*cast<T>(NewInfo)));
+  return llvm::Error::success();
+}
+
 llvm::Error mergeSingleInfo(doc::Info *&Reduced, doc::Info *NewInfo,
                             llvm::BumpPtrAllocator &Arena) {
-  if (!Reduced) {
-    switch (NewInfo->IT) {
-    case InfoType::IT_namespace:
-      Reduced = allocatePtr<NamespaceInfo>(Arena, NewInfo->USR);
-      break;
-    case InfoType::IT_record:
-      Reduced = allocatePtr<RecordInfo>(Arena, NewInfo->USR);
-      break;
-    case InfoType::IT_enum:
-      Reduced = allocatePtr<EnumInfo>(Arena, NewInfo->USR);
-      break;
-    case InfoType::IT_function:
-      Reduced = allocatePtr<FunctionInfo>(Arena, NewInfo->USR);
-      break;
-    case InfoType::IT_typedef:
-      Reduced = allocatePtr<TypedefInfo>(Arena, NewInfo->USR);
-      break;
-    case InfoType::IT_concept:
-      Reduced = allocatePtr<ConceptInfo>(Arena, NewInfo->USR);
-      break;
-    case InfoType::IT_variable:
-      Reduced = allocatePtr<VarInfo>(Arena, NewInfo->USR);
-      break;
-    case InfoType::IT_friend:
-      Reduced = allocatePtr<FriendInfo>(Arena, NewInfo->USR);
-      break;
-    default:
-      return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                     "unknown info type");
-    }
-  }
-
-  if (Reduced->IT != NewInfo->IT)
+  if (Reduced && Reduced->IT != NewInfo->IT)
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                    "info types mismatch");
 
-  switch (Reduced->IT) {
+  switch (NewInfo->IT) {
   case InfoType::IT_namespace:
-    cast<NamespaceInfo>(Reduced)->merge(
-        std::move(*cast<NamespaceInfo>(NewInfo)));
-    break;
+    return mergeTypedInfo<NamespaceInfo>(Reduced, NewInfo, Arena);
   case InfoType::IT_record:
-    cast<RecordInfo>(Reduced)->merge(
-        std::move(*cast<RecordInfo>(NewInfo)));
-    break;
+    return mergeTypedInfo<RecordInfo>(Reduced, NewInfo, Arena);
   case InfoType::IT_enum:
-    cast<EnumInfo>(Reduced)->merge(
-        std::move(*cast<EnumInfo>(NewInfo)));
-    break;
+    return mergeTypedInfo<EnumInfo>(Reduced, NewInfo, Arena);
   case InfoType::IT_function:
-    cast<FunctionInfo>(Reduced)->merge(
-        std::move(*cast<FunctionInfo>(NewInfo)));
-    break;
+    return mergeTypedInfo<FunctionInfo>(Reduced, NewInfo, Arena);
   case InfoType::IT_typedef:
-    cast<TypedefInfo>(Reduced)->merge(
-        std::move(*cast<TypedefInfo>(NewInfo)));
-    break;
+    return mergeTypedInfo<TypedefInfo>(Reduced, NewInfo, Arena);
   case InfoType::IT_concept:
-    cast<ConceptInfo>(Reduced)->merge(
-        std::move(*cast<ConceptInfo>(NewInfo)));
-    break;
+    return mergeTypedInfo<ConceptInfo>(Reduced, NewInfo, Arena);
   case InfoType::IT_variable:
-    cast<VarInfo>(Reduced)->merge(
-        std::move(*cast<VarInfo>(NewInfo)));
-    break;
+    return mergeTypedInfo<VarInfo>(Reduced, NewInfo, Arena);
   case InfoType::IT_friend:
-    cast<FriendInfo>(Reduced)->merge(
-        std::move(*cast<FriendInfo>(NewInfo)));
-    break;
+    return mergeTypedInfo<FriendInfo>(Reduced, NewInfo, Arena);
   default:
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                    "unknown info type");
   }
-
-  return llvm::Error::success();
 }
 
 // Dispatch function.
diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index d135ba0cd09fa..e1e71decb3a78 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -603,8 +603,6 @@ struct SymbolInfo : public Info {
 
   SymbolInfo(const SymbolInfo &Other, llvm::BumpPtrAllocator &Arena);
 
-  // SymbolInfo is an intermediate base with no InfoType of its own; it covers
-  // every kind that isn't a namespace.
   static bool classof(const Info *I) {
     switch (I->IT) {
     case InfoType::IT_record:
@@ -713,9 +711,6 @@ struct RecordInfo : public SymbolInfo {
 
   RecordInfo(const RecordInfo &Other, llvm::BumpPtrAllocator &Arena);
 
-  // BaseRecordInfo also carries IT_record, so isa<RecordInfo> is true for it as
-  // well. BaseRecordInfo is never stored polymorphically as an Info*, so it has
-  // no classof of its own.
   static bool classof(const Info *I) { return I->IT == InfoType::IT_record; }
 
   void merge(RecordInfo &&I);

``````````

</details>


https://github.com/llvm/llvm-project/pull/202060


More information about the llvm-branch-commits mailing list