[llvm-branch-commits] [clang] [CIR][CodeGen][NFC] Share canUseSingleInheritance (PR #227257)

Henrich Lauko via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Sep 29 03:26:29 PDT 2026


https://github.com/xlauko created https://github.com/llvm/llvm-project/pull/227257

Both CodeGens carry the same predicate deciding whether a class gets an
abi::__si_class_type_info. CIR's copy was marked "TODO(cir): this can
unified with LLVM codegen" and differed from classic only in spelling the
final check as one boolean expression; the shared version keeps that form.

No functional change intended.


>From 725ee5437a7564dc3a691b74e1ed7304b4116725 Mon Sep 17 00:00:00 2001
From: Henrich Lauko <hlauko at nvidia.com>
Date: Tue, 29 Sep 2026 09:55:33 +0000
Subject: [PATCH] [CIR][CodeGen][NFC] Share canUseSingleInheritance

Both CodeGens carry the same predicate deciding whether a class gets an
abi::__si_class_type_info. CIR's copy was marked "TODO(cir): this can
unified with LLVM codegen" and differed from classic only in spelling the
final check as one boolean expression; the shared version keeps that form.

No functional change intended.
---
 .../clang/CodeGenUtils/ItaniumCXXABIUtils.h   |  5 +++
 clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 30 ++---------------
 clang/lib/CodeGen/ItaniumCXXABI.cpp           | 32 ++-----------------
 clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp | 22 +++++++++++++
 4 files changed, 31 insertions(+), 58 deletions(-)

diff --git a/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h b/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h
index 59b94c9bb08c3..9d6a20ef82ab3 100644
--- a/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h
+++ b/clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h
@@ -62,6 +62,11 @@ enum BaseClassTypeInfoFlags {
   BCTI_Public = 0x2
 };
 
+/// Return whether the given record decl has a "single, public, non-virtual
+/// base at offset zero (i.e. the derived class is dynamic iff the base is)",
+/// according to Itanium C++ ABI, 2.95p6b.
+bool canUseSingleInheritance(const CXXRecordDecl *RD);
+
 /// Compute the src2dst_offset hint as described in the Itanium C++ ABI [2.9.7].
 CharUnits computeOffsetHint(ASTContext &Ctx, const CXXRecordDecl *Src,
                             const CXXRecordDecl *Dst);
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index 397d8f43895e6..cdc94838f5674 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -831,32 +831,6 @@ static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
   return false;
 }
 
-// Return whether the given record decl has a "single,
-// public, non-virtual base at offset zero (i.e. the derived class is dynamic
-// iff the base is)", according to Itanium C++ ABI, 2.95p6b.
-// TODO(cir): this can unified with LLVM codegen
-static bool canUseSingleInheritance(const CXXRecordDecl *rd) {
-  // Check the number of bases.
-  if (rd->getNumBases() != 1)
-    return false;
-
-  // Get the base.
-  CXXRecordDecl::base_class_const_iterator base = rd->bases_begin();
-
-  // Check that the base is not virtual.
-  if (base->isVirtual())
-    return false;
-
-  // Check that the base is public.
-  if (base->getAccessSpecifier() != AS_public)
-    return false;
-
-  // Check that the class is dynamic iff the base is.
-  auto *baseDecl = base->getType()->castAsCXXRecordDecl();
-  return baseDecl->isEmpty() ||
-         baseDecl->isDynamicClass() == rd->isDynamicClass();
-}
-
 const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) {
   // abi::__class_type_info.
   static const char *const classTypeInfo =
@@ -925,7 +899,7 @@ const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) {
       return classTypeInfo;
     }
 
-    if (canUseSingleInheritance(rd)) {
+    if (CodeGenUtils::canUseSingleInheritance(rd)) {
       return siClassTypeInfo;
     }
 
@@ -1421,7 +1395,7 @@ mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
       break;
     }
 
-    if (canUseSingleInheritance(rd)) {
+    if (CodeGenUtils::canUseSingleInheritance(rd)) {
       buildSIClassTypeInfo(loc, rd);
     } else {
       buildVMIClassTypeInfo(loc, rd);
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 228a2a6e689da..f7dedeaeb31bf 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3819,34 +3819,6 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
   return false;
 }
 
-// CanUseSingleInheritance - Return whether the given record decl has a "single,
-// public, non-virtual base at offset zero (i.e. the derived class is dynamic
-// iff the base is)", according to Itanium C++ ABI, 2.95p6b.
-static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
-  // Check the number of bases.
-  if (RD->getNumBases() != 1)
-    return false;
-
-  // Get the base.
-  CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
-
-  // Check that the base is not virtual.
-  if (Base->isVirtual())
-    return false;
-
-  // Check that the base is public.
-  if (Base->getAccessSpecifier() != AS_public)
-    return false;
-
-  // Check that the class is dynamic iff the base is.
-  auto *BaseDecl = Base->getType()->castAsCXXRecordDecl();
-  if (!BaseDecl->isEmpty() &&
-      BaseDecl->isDynamicClass() != RD->isDynamicClass())
-    return false;
-
-  return true;
-}
-
 void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty,
                                             llvm::Constant *StorageAddress) {
   // abi::__class_type_info.
@@ -3923,7 +3895,7 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty,
 
     if (!RD->hasDefinition() || !RD->getNumBases()) {
       VTableName = ClassTypeInfo;
-    } else if (CanUseSingleInheritance(RD)) {
+    } else if (CodeGenUtils::canUseSingleInheritance(RD)) {
       VTableName = SIClassTypeInfo;
     } else {
       VTableName = VMIClassTypeInfo;
@@ -4241,7 +4213,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
       break;
     }
 
-    if (CanUseSingleInheritance(RD))
+    if (CodeGenUtils::canUseSingleInheritance(RD))
       BuildSIClassTypeInfo(RD);
     else
       BuildVMIClassTypeInfo(RD);
diff --git a/clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp b/clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp
index a1ab26cfc17b0..2f22ab69d4c5a 100644
--- a/clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp
+++ b/clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp
@@ -61,6 +61,28 @@ CharUnits computeOffsetHint(ASTContext &Ctx, const CXXRecordDecl *Src,
   return Offset;
 }
 
+bool canUseSingleInheritance(const CXXRecordDecl *RD) {
+  // Check the number of bases.
+  if (RD->getNumBases() != 1)
+    return false;
+
+  // Get the base.
+  CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
+
+  // Check that the base is not virtual.
+  if (Base->isVirtual())
+    return false;
+
+  // Check that the base is public.
+  if (Base->getAccessSpecifier() != AS_public)
+    return false;
+
+  // Check that the class is dynamic iff the base is.
+  auto *BaseDecl = Base->getType()->castAsCXXRecordDecl();
+  return BaseDecl->isEmpty() ||
+         BaseDecl->isDynamicClass() == RD->isDynamicClass();
+}
+
 namespace {
 /// Contains virtual and non-virtual bases seen when traversing a class
 /// hierarchy.



More information about the llvm-branch-commits mailing list