[clang] 02c06c3 - [CIR][CodeGen][NFC] Share canUseSingleInheritance (#227257)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 8 01:10:50 PDT 2026
Author: Henrich Lauko
Date: 2026-10-08T10:10:45+02:00
New Revision: 02c06c3140efb0822106d26816cbac37e96ffd4b
URL: https://github.com/llvm/llvm-project/commit/02c06c3140efb0822106d26816cbac37e96ffd4b
DIFF: https://github.com/llvm/llvm-project/commit/02c06c3140efb0822106d26816cbac37e96ffd4b.diff
LOG: [CIR][CodeGen][NFC] Share canUseSingleInheritance (#227257)
Deduplicates `canUseSingleInheritance` between CIR and classic CodeGen into
`ItaniumCXXABIUtils.h`.
Assisted-by: Claude Code (Claude Fable 5.1).
Added:
Modified:
clang/include/clang/CodeGenUtils/ItaniumCXXABIUtils.h
clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
clang/lib/CodeGen/ItaniumCXXABI.cpp
clang/lib/CodeGenUtils/ItaniumCXXABIUtils.cpp
Removed:
################################################################################
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 763ed026f8714..25526f0668f00 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -835,32 +835,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 =
@@ -929,7 +903,7 @@ const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) {
return classTypeInfo;
}
- if (canUseSingleInheritance(rd)) {
+ if (CodeGenUtils::canUseSingleInheritance(rd)) {
return siClassTypeInfo;
}
@@ -1425,7 +1399,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 8e9aaa1313528..c851385822291 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3822,34 +3822,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.
@@ -3926,7 +3898,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;
@@ -4244,7 +4216,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 cfe-commits
mailing list