[llvm-branch-commits] [clang] [CIR][CodeGen][NFC] Share the record layout queries (PR #223424)
Henrich Lauko via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Sep 29 03:25:44 PDT 2026
https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/223424
>From f0607ab0e63430283c502c1e603ae422ee65d01f Mon Sep 17 00:00:00 2001
From: Henrich Lauko <hlauko at nvidia.com>
Date: Tue, 29 Sep 2026 09:56:08 +0000
Subject: [PATCH] [CIR][CodeGen][NFC] Share isEmptyFieldForLayout and
isEmptyRecordForLayout
Both CodeGens define these two mutually recursive predicates, classic in
ABIInfoImpl.cpp and CIR in TargetInfo.cpp, with equivalent bodies. They move
to a new RecordLayoutUtils.h, named for CGRecordLayoutBuilder.cpp, which is
where their remaining siblings come from in the next two patches.
The pair has around 30 unqualified callers between the two CodeGens.
ABIInfoImpl.h and CIR/CodeGen/TargetInfo.h re-export the shared
declarations with using-declarations, so those callers are untouched.
No functional change.
---
.../clang/CodeGenUtils/RecordLayoutUtils.h | 34 ++++++++++++++
clang/lib/CIR/CodeGen/TargetInfo.cpp | 34 --------------
clang/lib/CIR/CodeGen/TargetInfo.h | 12 ++---
clang/lib/CodeGen/ABIInfoImpl.cpp | 33 --------------
clang/lib/CodeGen/ABIInfoImpl.h | 12 ++---
clang/lib/CodeGenUtils/CMakeLists.txt | 1 +
clang/lib/CodeGenUtils/RecordLayoutUtils.cpp | 45 +++++++++++++++++++
7 files changed, 86 insertions(+), 85 deletions(-)
create mode 100644 clang/include/clang/CodeGenUtils/RecordLayoutUtils.h
create mode 100644 clang/lib/CodeGenUtils/RecordLayoutUtils.cpp
diff --git a/clang/include/clang/CodeGenUtils/RecordLayoutUtils.h b/clang/include/clang/CodeGenUtils/RecordLayoutUtils.h
new file mode 100644
index 0000000000000..77f14fee5a3b4
--- /dev/null
+++ b/clang/include/clang/CodeGenUtils/RecordLayoutUtils.h
@@ -0,0 +1,34 @@
+//===--- RecordLayoutUtils.h - Shared record layout queries -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file holds the AST queries about record layout that both classic
+// CodeGen and CIR CodeGen need while lowering a record to its target type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGENUTILS_RECORDLAYOUTUTILS_H
+#define LLVM_CLANG_CODEGENUTILS_RECORDLAYOUTUTILS_H
+
+#include "clang/AST/ASTContext.h"
+
+namespace clang::CodeGenUtils {
+
+/// Return true iff the field is "empty", that is, either a zero-width
+/// bit-field or an \ref isEmptyRecordForLayout.
+bool isEmptyFieldForLayout(const ASTContext &Ctx, const FieldDecl *FD);
+
+/// Return true iff a structure contains only empty base classes (per \ref
+/// isEmptyRecordForLayout) and fields (per \ref isEmptyFieldForLayout). Note,
+/// C++ record fields are considered empty if the [[no_unique_address]]
+/// attribute would have made them empty, so this is not the same as \ref
+/// isEmptyRecord.
+bool isEmptyRecordForLayout(const ASTContext &Ctx, QualType T);
+
+} // namespace clang::CodeGenUtils
+
+#endif // LLVM_CLANG_CODEGENUTILS_RECORDLAYOUTUTILS_H
diff --git a/clang/lib/CIR/CodeGen/TargetInfo.cpp b/clang/lib/CIR/CodeGen/TargetInfo.cpp
index cede4941b4473..57bc5f167e460 100644
--- a/clang/lib/CIR/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CIR/CodeGen/TargetInfo.cpp
@@ -11,40 +11,6 @@
using namespace clang;
using namespace clang::CIRGen;
-bool clang::CIRGen::isEmptyRecordForLayout(const ASTContext &context,
- QualType t) {
- const auto *rd = t->getAsRecordDecl();
- if (!rd)
- return false;
-
- // If this is a C++ record, check the bases first.
- if (const CXXRecordDecl *cxxrd = dyn_cast<CXXRecordDecl>(rd)) {
- if (cxxrd->isDynamicClass())
- return false;
-
- for (const auto &i : cxxrd->bases())
- if (!isEmptyRecordForLayout(context, i.getType()))
- return false;
- }
-
- for (const auto *i : rd->fields())
- if (!isEmptyFieldForLayout(context, i))
- return false;
-
- return true;
-}
-
-bool clang::CIRGen::isEmptyFieldForLayout(const ASTContext &context,
- const FieldDecl *fd) {
- if (fd->isZeroLengthBitField())
- return true;
-
- if (fd->isUnnamedBitField())
- return false;
-
- return isEmptyRecordForLayout(context, fd->getType());
-}
-
bool clang::CIRGen::isEmptyRecordForABI(const ASTContext &context, QualType t) {
const auto *rd = t->getAsRecordDecl();
if (!rd)
diff --git a/clang/lib/CIR/CodeGen/TargetInfo.h b/clang/lib/CIR/CodeGen/TargetInfo.h
index 5f380026e025d..e094fa53561f5 100644
--- a/clang/lib/CIR/CodeGen/TargetInfo.h
+++ b/clang/lib/CIR/CodeGen/TargetInfo.h
@@ -21,21 +21,15 @@
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
+#include "clang/CodeGenUtils/RecordLayoutUtils.h"
#include <memory>
#include <utility>
namespace clang::CIRGen {
-/// isEmptyFieldForLayout - Return true if the field is "empty", that is,
-/// either a zero-width bit-field or an isEmptyRecordForLayout.
-bool isEmptyFieldForLayout(const ASTContext &context, const FieldDecl *fd);
-
-/// isEmptyRecordForLayout - Return true if a structure contains only empty
-/// base classes (per isEmptyRecordForLayout) and fields (per
-/// isEmptyFieldForLayout). Note, C++ record fields are considered empty
-/// if the [[no_unique_address]] attribute would have made them empty.
-bool isEmptyRecordForLayout(const ASTContext &context, QualType t);
+using CodeGenUtils::isEmptyFieldForLayout;
+using CodeGenUtils::isEmptyRecordForLayout;
/// isEmptyFieldForABI - Return true if the field is "empty", that is, it is a
/// zero-width bit-field or an (array of) empty record(s). An unnamed
diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp
index 887a645a4783a..23b6b7e8200da 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.cpp
+++ b/clang/lib/CodeGen/ABIInfoImpl.cpp
@@ -302,39 +302,6 @@ bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
return true;
}
-bool CodeGen::isEmptyFieldForLayout(const ASTContext &Context,
- const FieldDecl *FD) {
- if (FD->isZeroLengthBitField())
- return true;
-
- if (FD->isUnnamedBitField())
- return false;
-
- return isEmptyRecordForLayout(Context, FD->getType());
-}
-
-bool CodeGen::isEmptyRecordForLayout(const ASTContext &Context, QualType T) {
- const auto *RD = T->getAsRecordDecl();
- if (!RD)
- return false;
-
- // If this is a C++ record, check the bases first.
- if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
- if (CXXRD->isDynamicClass())
- return false;
-
- for (const auto &I : CXXRD->bases())
- if (!isEmptyRecordForLayout(Context, I.getType()))
- return false;
- }
-
- for (const auto *I : RD->fields())
- if (!isEmptyFieldForLayout(Context, I))
- return false;
-
- return true;
-}
-
const Type *CodeGen::isSingleElementStruct(QualType T, ASTContext &Context) {
const auto *RD = T->getAsRecordDecl();
if (!RD)
diff --git a/clang/lib/CodeGen/ABIInfoImpl.h b/clang/lib/CodeGen/ABIInfoImpl.h
index d9d79c6a55ddb..89ea2219096a2 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.h
+++ b/clang/lib/CodeGen/ABIInfoImpl.h
@@ -11,6 +11,7 @@
#include "ABIInfo.h"
#include "CGCXXABI.h"
+#include "clang/CodeGenUtils/RecordLayoutUtils.h"
namespace clang::CodeGen {
@@ -120,15 +121,8 @@ bool isEmptyField(ASTContext &Context, const FieldDecl *FD, bool AllowArrays,
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
bool AsIfNoUniqueAddr = false);
-/// isEmptyFieldForLayout - Return true iff the field is "empty", that is,
-/// either a zero-width bit-field or an \ref isEmptyRecordForLayout.
-bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD);
-
-/// isEmptyRecordForLayout - Return true iff a structure contains only empty
-/// base classes (per \ref isEmptyRecordForLayout) and fields (per
-/// \ref isEmptyFieldForLayout). Note, C++ record fields are considered empty
-/// if the [[no_unique_address]] attribute would have made them empty.
-bool isEmptyRecordForLayout(const ASTContext &Context, QualType T);
+using CodeGenUtils::isEmptyFieldForLayout;
+using CodeGenUtils::isEmptyRecordForLayout;
/// isSingleElementStruct - Determine if a structure is a "single
/// element struct", i.e. it has exactly one non-empty field or
diff --git a/clang/lib/CodeGenUtils/CMakeLists.txt b/clang/lib/CodeGenUtils/CMakeLists.txt
index 5839e8f2e1fe5..f46ac572a0ce9 100644
--- a/clang/lib/CodeGenUtils/CMakeLists.txt
+++ b/clang/lib/CodeGenUtils/CMakeLists.txt
@@ -11,6 +11,7 @@ add_clang_library(clangCodeGenUtils
FunctionUtils.cpp
ItaniumCXXABIUtils.cpp
ModuleUtils.cpp
+ RecordLayoutUtils.cpp
LINK_LIBS
clangAST
diff --git a/clang/lib/CodeGenUtils/RecordLayoutUtils.cpp b/clang/lib/CodeGenUtils/RecordLayoutUtils.cpp
new file mode 100644
index 0000000000000..3b8d433dc8759
--- /dev/null
+++ b/clang/lib/CodeGenUtils/RecordLayoutUtils.cpp
@@ -0,0 +1,45 @@
+//===--- RecordLayoutUtils.cpp - Shared record layout queries -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CodeGenUtils/RecordLayoutUtils.h"
+
+namespace clang::CodeGenUtils {
+
+bool isEmptyFieldForLayout(const ASTContext &Ctx, const FieldDecl *FD) {
+ if (FD->isZeroLengthBitField())
+ return true;
+
+ if (FD->isUnnamedBitField())
+ return false;
+
+ return isEmptyRecordForLayout(Ctx, FD->getType());
+}
+
+bool isEmptyRecordForLayout(const ASTContext &Ctx, QualType T) {
+ const auto *RD = T->getAsRecordDecl();
+ if (!RD)
+ return false;
+
+ // If this is a C++ record, check the bases first.
+ if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
+ if (CXXRD->isDynamicClass())
+ return false;
+
+ for (const auto &I : CXXRD->bases())
+ if (!isEmptyRecordForLayout(Ctx, I.getType()))
+ return false;
+ }
+
+ for (const auto *I : RD->fields())
+ if (!isEmptyFieldForLayout(Ctx, I))
+ return false;
+
+ return true;
+}
+
+} // namespace clang::CodeGenUtils
More information about the llvm-branch-commits
mailing list