[llvm-branch-commits] [clang] [CIR][CodeGen][NFC] Share hasOwnStorage (PR #227259)
Henrich Lauko via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Sep 29 04:23:10 PDT 2026
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/227259
>From 282c541c8e55b550792d3d9edf6efe9f9a72231d Mon Sep 17 00:00:00 2001
From: Henrich Lauko <hlauko at nvidia.com>
Date: Tue, 29 Sep 2026 09:56:18 +0000
Subject: [PATCH] [CIR][CodeGen][NFC] Share hasOwnStorage
Deduplicates `hasOwnStorage` between CIR and classic CodeGen into
`RecordLayoutUtils.h`.
---
.../clang/CodeGenUtils/RecordLayoutUtils.h | 5 +++++
.../CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp | 17 +--------------
clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 21 ++++---------------
clang/lib/CodeGenUtils/RecordLayoutUtils.cpp | 12 +++++++++++
4 files changed, 22 insertions(+), 33 deletions(-)
diff --git a/clang/include/clang/CodeGenUtils/RecordLayoutUtils.h b/clang/include/clang/CodeGenUtils/RecordLayoutUtils.h
index 2c1ee3c271a3d1..594411e0762771 100644
--- a/clang/include/clang/CodeGenUtils/RecordLayoutUtils.h
+++ b/clang/include/clang/CodeGenUtils/RecordLayoutUtils.h
@@ -18,6 +18,11 @@
namespace clang::CodeGenUtils {
+/// Recursively searches all of the bases of \p Decl to find out whether
+/// \p Query is not the primary vbase of some base class.
+bool hasOwnStorage(const ASTContext &Ctx, const CXXRecordDecl *Decl,
+ const CXXRecordDecl *Query);
+
/// The Microsoft bitfield layout rule allocates discrete storage units of the
/// field's formal type and only combines adjacent fields of the same formal
/// type. We want to emit a layout with these discrete storage units instead
diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
index 733cb208fd93e6..63715e1f6e8145 100644
--- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
@@ -134,10 +134,6 @@ struct CIRRecordLowering final {
/// Helper function to check if the target machine is BigEndian.
bool isBigEndian() const { return astContext.getTargetInfo().isBigEndian(); }
- // Recursively searches all of the bases to find out if a vbase is
- // not the primary vbase of some base class.
- bool hasOwnStorage(const CXXRecordDecl *decl, const CXXRecordDecl *query);
-
CharUnits bitsToCharUnits(uint64_t bitOffset) {
return astContext.toCharUnitsFromBits(bitOffset);
}
@@ -1112,17 +1108,6 @@ void CIRRecordLowering::lowerUnion(bool nonVirtualBaseType) {
packed = !layoutSize.isMultipleOf(getMemberAlignment(storageType));
}
-bool CIRRecordLowering::hasOwnStorage(const CXXRecordDecl *decl,
- const CXXRecordDecl *query) {
- const ASTRecordLayout &declLayout = astContext.getASTRecordLayout(decl);
- if (declLayout.isPrimaryBaseVirtual() && declLayout.getPrimaryBase() == query)
- return false;
- for (const auto &base : decl->bases())
- if (!hasOwnStorage(base.getType()->getAsCXXRecordDecl(), query))
- return false;
- return true;
-}
-
/// The AAPCS that defines that, when possible, bit-fields should
/// be accessed using containers of the declared type width:
/// When a volatile bit-field is read, and its container does not overlap with
@@ -1278,7 +1263,7 @@ void CIRRecordLowering::accumulateVBases() {
// get its own storage location but instead lives inside of that base.
if (CodeGenUtils::isOverlappingVBaseABI(astContext) &&
astContext.isNearlyEmpty(baseDecl) &&
- !hasOwnStorage(cxxRecordDecl, baseDecl)) {
+ !CodeGenUtils::hasOwnStorage(astContext, cxxRecordDecl, baseDecl)) {
members.push_back(MemberInfo(offset, MemberInfo::InfoKind::VBase, nullptr,
cir::RecordMemberKind::Data, baseDecl));
continue;
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 7b21b40ff26ed1..905382f5ea9395 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -172,10 +172,6 @@ struct CGRecordLowering {
void accumulateBases();
void accumulateVPtrs();
void accumulateVBases();
- /// Recursively searches all of the bases to find out if a vbase is
- /// not the primary vbase of some base class.
- bool hasOwnStorage(const CXXRecordDecl *Decl,
- const CXXRecordDecl *Query) const;
void calculateZeroInit();
CharUnits calculateTailClippingOffset(bool isNonVirtualBaseType) const;
void checkBitfieldClipping(bool isNonVirtualBaseType) const;
@@ -865,7 +861,8 @@ CGRecordLowering::calculateTailClippingOffset(bool isNonVirtualBaseType) const {
continue;
// If the vbase is a primary virtual base of some base, then it doesn't
// get its own storage location but instead lives inside of that base.
- if (Context.isNearlyEmpty(BaseDecl) && !hasOwnStorage(RD, BaseDecl))
+ if (Context.isNearlyEmpty(BaseDecl) &&
+ !CodeGenUtils::hasOwnStorage(Context, RD, BaseDecl))
continue;
ScissorOffset = std::min(ScissorOffset,
Layout.getVBaseClassOffset(BaseDecl));
@@ -883,7 +880,8 @@ void CGRecordLowering::accumulateVBases() {
// If the vbase is a primary virtual base of some base, then it doesn't
// get its own storage location but instead lives inside of that base.
if (CodeGenUtils::isOverlappingVBaseABI(Context) &&
- Context.isNearlyEmpty(BaseDecl) && !hasOwnStorage(RD, BaseDecl)) {
+ Context.isNearlyEmpty(BaseDecl) &&
+ !CodeGenUtils::hasOwnStorage(Context, RD, BaseDecl)) {
Members.push_back(MemberInfo(Offset, MemberInfo::VBase, nullptr,
BaseDecl));
continue;
@@ -897,17 +895,6 @@ void CGRecordLowering::accumulateVBases() {
}
}
-bool CGRecordLowering::hasOwnStorage(const CXXRecordDecl *Decl,
- const CXXRecordDecl *Query) const {
- const ASTRecordLayout &DeclLayout = Context.getASTRecordLayout(Decl);
- if (DeclLayout.isPrimaryBaseVirtual() && DeclLayout.getPrimaryBase() == Query)
- return false;
- for (const auto &Base : Decl->bases())
- if (!hasOwnStorage(Base.getType()->getAsCXXRecordDecl(), Query))
- return false;
- return true;
-}
-
void CGRecordLowering::calculateZeroInit() {
for (std::vector<MemberInfo>::const_iterator Member = Members.begin(),
MemberEnd = Members.end();
diff --git a/clang/lib/CodeGenUtils/RecordLayoutUtils.cpp b/clang/lib/CodeGenUtils/RecordLayoutUtils.cpp
index b41fb61491377f..31306470b6da65 100644
--- a/clang/lib/CodeGenUtils/RecordLayoutUtils.cpp
+++ b/clang/lib/CodeGenUtils/RecordLayoutUtils.cpp
@@ -7,10 +7,22 @@
//===----------------------------------------------------------------------===//
#include "clang/CodeGenUtils/RecordLayoutUtils.h"
+#include "clang/AST/RecordLayout.h"
#include "clang/Basic/TargetInfo.h"
namespace clang::CodeGenUtils {
+bool hasOwnStorage(const ASTContext &Ctx, const CXXRecordDecl *Decl,
+ const CXXRecordDecl *Query) {
+ const ASTRecordLayout &DeclLayout = Ctx.getASTRecordLayout(Decl);
+ if (DeclLayout.isPrimaryBaseVirtual() && DeclLayout.getPrimaryBase() == Query)
+ return false;
+ for (const auto &Base : Decl->bases())
+ if (!hasOwnStorage(Ctx, Base.getType()->getAsCXXRecordDecl(), Query))
+ return false;
+ return true;
+}
+
bool isDiscreteBitFieldABI(const ASTContext &Ctx, const RecordDecl *RD) {
return Ctx.getTargetInfo().getCXXABI().isMicrosoft() || RD->isMsStruct(Ctx);
}
More information about the llvm-branch-commits
mailing list