[llvm-branch-commits] [clang] [CIR][CodeGen][NFC] Retire the CodeGenUtils.h catch-all header (PR #223451)

Henrich Lauko via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Sep 21 06:36:33 PDT 2026


https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/223451

>From 8c2107aae1b8722a408b3738485315f4b43000d3 Mon Sep 17 00:00:00 2001
From: Henrich Lauko <hlauko at nvidia.com>
Date: Mon, 14 Sep 2026 16:22:27 +0000
Subject: [PATCH] [CIR][CodeGen][NFC] Retire the CodeGenUtils.h catch-all
 header

The preceding patches group shared helpers by the classic CodeGen file, or
file family, they came from. That leaves CodeGenUtils.h holding only the
five helpers PR #221001 started the library with and the target-features
checker from PR #223056, so they move to the same places their neighbours
went and the header goes away. The library keeps its name.

checkTargetFeatures came out of CodeGenFunction.cpp, so it joins
shouldEmitLifetimeMarkers in FunctionUtils.h. TargetUtils.h would fit it by
subject, but the series sorts by origin file, and picking origin keeps the
rule mechanical.

isAAPCS is the one case origin does not settle, since it was duplicated in
CGExpr.cpp and CGRecordLayoutBuilder.cpp rather than living in one file. It
is a plain TargetInfo predicate, so it goes with the other target
predicates.

Doing this now avoids making every helper we share from here on pick
between the catch-all and a themed header, with no rule saying which. It
only moves code already on main, so it can be dropped without affecting the
patches before it.

No functional change intended.
---
 clang/include/clang/CodeGenUtils/ClassUtils.h |  18 ++
 .../include/clang/CodeGenUtils/CodeGenUtils.h |  65 -----
 .../clang/CodeGenUtils/FunctionUtils.h        |  26 +-
 .../include/clang/CodeGenUtils/ModuleUtils.h  |   7 +
 .../include/clang/CodeGenUtils/TargetUtils.h  |   4 +
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp       |   2 +-
 clang/lib/CIR/CodeGen/CIRGenClass.cpp         |   1 -
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp          |   2 +-
 clang/lib/CIR/CodeGen/CIRGenFunction.cpp      |   2 +-
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        |   1 -
 .../CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp |   2 +-
 clang/lib/CodeGen/CGClass.cpp                 |   1 -
 clang/lib/CodeGen/CGExpr.cpp                  |   2 +-
 clang/lib/CodeGen/CGRecordLayoutBuilder.cpp   |   2 +-
 clang/lib/CodeGen/CodeGenFunction.cpp         |   1 -
 clang/lib/CodeGen/CodeGenModule.cpp           |   1 -
 clang/lib/CodeGenUtils/CMakeLists.txt         |   1 -
 clang/lib/CodeGenUtils/ClassUtils.cpp         |  81 ++++++
 clang/lib/CodeGenUtils/CodeGenUtils.cpp       | 233 ------------------
 clang/lib/CodeGenUtils/FunctionUtils.cpp      | 120 +++++++++
 clang/lib/CodeGenUtils/ModuleUtils.cpp        |  17 ++
 clang/lib/CodeGenUtils/TargetUtils.cpp        |   5 +
 22 files changed, 282 insertions(+), 312 deletions(-)
 delete mode 100644 clang/include/clang/CodeGenUtils/CodeGenUtils.h
 delete mode 100644 clang/lib/CodeGenUtils/CodeGenUtils.cpp

diff --git a/clang/include/clang/CodeGenUtils/ClassUtils.h b/clang/include/clang/CodeGenUtils/ClassUtils.h
index 63664ed737933..8bd6cf7fa427f 100644
--- a/clang/include/clang/CodeGenUtils/ClassUtils.h
+++ b/clang/include/clang/CodeGenUtils/ClassUtils.h
@@ -24,6 +24,24 @@ namespace clang::CodeGenUtils {
 /// properly set.
 bool baseInitializerUsesThis(ASTContext &Ctx, const Expr *Init);
 
+/// Check whether we need to initialize any vtable pointers before calling this
+/// destructor.
+bool canSkipVTablePointerInitialization(ASTContext &Ctx,
+                                        const CXXDestructorDecl *Dtor);
+
+/// Check whether destructing \p Field has no observable behaviors, and thus can
+/// be skipped when creating a destructor body. So non-record types, anonymous
+/// structs/unions, or record types where the destructor doesnt DO anything are
+/// considered as this version of 'trivial'.
+/// Note: This is a more liberal definition of trivial destruction than the C++
+/// Standard's version, and thus cannot be used as a substitute for C++ Standard
+/// requirements.
+bool fieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
+
+/// Return whether \p BaseInit initializes a base class that is dynamic, that
+/// is, one whose vtable pointer must be set before the initializer runs.
+bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit);
+
 } // namespace clang::CodeGenUtils
 
 #endif // LLVM_CLANG_CODEGENUTILS_CLASSUTILS_H
diff --git a/clang/include/clang/CodeGenUtils/CodeGenUtils.h b/clang/include/clang/CodeGenUtils/CodeGenUtils.h
deleted file mode 100644
index b24f457f9537c..0000000000000
--- a/clang/include/clang/CodeGenUtils/CodeGenUtils.h
+++ /dev/null
@@ -1,65 +0,0 @@
-//===--- CodeGenUtils.h - Shared Classic CodeGen/CIR CodeGen Utils--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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_CODEGENUTILS_CODEGENUTILS_H
-#define LLVM_CLANG_CODEGENUTILS_CODEGENUTILS_H
-
-#include "clang/AST/ASTContext.h"
-#include "clang/Basic/SourceLocation.h"
-
-namespace clang {
-class CallExpr;
-class DiagnosticsEngine;
-class FunctionDecl;
-class LangOptions;
-} // namespace clang
-
-namespace clang::CodeGenUtils {
-/// Check whether we need to initialize any vtable pointers before calling this
-/// destructor.
-bool canSkipVTablePointerInitialization(ASTContext &Ctx,
-                                        const CXXDestructorDecl *Dtor);
-
-/// Check whether destructing \p Field has no observable behaviors, and thus can
-/// be skipped when creating a destructor body. So non-record types, anonymous
-/// structs/unions, or record types where the destructor doesnt DO anything are
-/// considered as this version of 'trivial'.
-/// Note: This is a more liberal definition of trivial destruction than the C++
-/// Standard's version, and thus cannot be used as a substitute for C++ Standard
-/// requirements.
-bool fieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
-
-/// Determines whether the language options require us to model
-/// unwind exceptions.  We treat -fexceptions as mandating this
-/// except under the fragile ObjC ABI with only ObjC exceptions
-/// enabled.  This means, for example, that C with -fexceptions
-/// enables this.
-bool hasUnwindExceptions(const LangOptions &LangOpts);
-
-/// Helper method to check if the underlying ABI is AAPCS
-bool isAAPCS(const TargetInfo &TargetInfo);
-
-bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit);
-
-/// Check that a call to a target-specific builtin has the required target
-/// features enabled in the caller, emitting an error diagnostic if not.
-/// \p caller is the FunctionDecl of the enclosing function (may be null).
-void checkTargetFeatures(ASTContext &Ctx, DiagnosticsEngine &Diags,
-                         const LangOptions &LangOpts, const CallExpr *E,
-                         const FunctionDecl *Caller,
-                         const FunctionDecl *TargetDecl);
-
-/// Overload taking a raw source location instead of a CallExpr.
-void checkTargetFeatures(ASTContext &Ctx, DiagnosticsEngine &Diags,
-                         const LangOptions &LangOpts, SourceLocation Loc,
-                         const FunctionDecl *Caller,
-                         const FunctionDecl *TargetDecl);
-
-} // namespace clang::CodeGenUtils
-
-#endif // LLVM_CLANG_CODEGENUTILS_CODEGENUTILS_H
diff --git a/clang/include/clang/CodeGenUtils/FunctionUtils.h b/clang/include/clang/CodeGenUtils/FunctionUtils.h
index f924874d829e0..588c957e3da0a 100644
--- a/clang/include/clang/CodeGenUtils/FunctionUtils.h
+++ b/clang/include/clang/CodeGenUtils/FunctionUtils.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file holds the queries that both classic CodeGen and CIR CodeGen need
-// while emitting a function body.
+// This file holds the queries and checks that both classic CodeGen and CIR
+// CodeGen need while emitting a function body.
 //
 //===----------------------------------------------------------------------===//
 
@@ -16,6 +16,14 @@
 
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+class ASTContext;
+class CallExpr;
+class DiagnosticsEngine;
+class FunctionDecl;
+} // namespace clang
 
 namespace clang::CodeGenUtils {
 
@@ -23,6 +31,20 @@ namespace clang::CodeGenUtils {
 bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts,
                                const LangOptions &LangOpts);
 
+/// Check that a call to a target-specific builtin has the required target
+/// features enabled in the caller, emitting an error diagnostic if not.
+/// \p caller is the FunctionDecl of the enclosing function (may be null).
+void checkTargetFeatures(ASTContext &Ctx, DiagnosticsEngine &Diags,
+                         const LangOptions &LangOpts, const CallExpr *E,
+                         const FunctionDecl *Caller,
+                         const FunctionDecl *TargetDecl);
+
+/// Overload taking a raw source location instead of a CallExpr.
+void checkTargetFeatures(ASTContext &Ctx, DiagnosticsEngine &Diags,
+                         const LangOptions &LangOpts, SourceLocation Loc,
+                         const FunctionDecl *Caller,
+                         const FunctionDecl *TargetDecl);
+
 } // namespace clang::CodeGenUtils
 
 #endif // LLVM_CLANG_CODEGENUTILS_FUNCTIONUTILS_H
diff --git a/clang/include/clang/CodeGenUtils/ModuleUtils.h b/clang/include/clang/CodeGenUtils/ModuleUtils.h
index 5c7423ad4fac5..3bb94184a03f0 100644
--- a/clang/include/clang/CodeGenUtils/ModuleUtils.h
+++ b/clang/include/clang/CodeGenUtils/ModuleUtils.h
@@ -19,6 +19,13 @@
 
 namespace clang::CodeGenUtils {
 
+/// Determines whether the language options require us to model
+/// unwind exceptions.  We treat -fexceptions as mandating this
+/// except under the fragile ObjC ABI with only ObjC exceptions
+/// enabled.  This means, for example, that C with -fexceptions
+/// enables this.
+bool hasUnwindExceptions(const LangOptions &LangOpts);
+
 /// Check whether \p D is a strong definition, and thus must not be given
 /// common linkage.  \p NoCommon reflects -fno-common.
 bool isVarDeclStrongDefinition(const ASTContext &Ctx, const VarDecl *D,
diff --git a/clang/include/clang/CodeGenUtils/TargetUtils.h b/clang/include/clang/CodeGenUtils/TargetUtils.h
index a44541c572590..2c812c6a2b617 100644
--- a/clang/include/clang/CodeGenUtils/TargetUtils.h
+++ b/clang/include/clang/CodeGenUtils/TargetUtils.h
@@ -21,6 +21,7 @@
 namespace clang {
 class Decl;
 class FunctionDecl;
+class TargetInfo;
 } // namespace clang
 
 namespace clang::CodeGenUtils {
@@ -53,6 +54,9 @@ ArmSMEInlinability getArmSMEInlinability(const FunctionDecl *Caller,
 /// TODO: Make this return false for SISD builtins.
 bool hasExtraNeonArgument(unsigned BuiltinID);
 
+/// Helper method to check if the underlying ABI is AAPCS
+bool isAAPCS(const TargetInfo &TargetInfo);
+
 /// Returns whether \p D must be given protected visibility on AMDGPU.
 /// \p HasHiddenVisibility is whether the emitted global currently has hidden
 /// visibility.
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index e2fe3adefd4af..217170daf36e2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -26,7 +26,7 @@
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
 #include "clang/CIR/MissingFeatures.h"
-#include "clang/CodeGenUtils/CodeGenUtils.h"
+#include "clang/CodeGenUtils/FunctionUtils.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/Support/ErrorHandling.h"
diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index c8edc1ccd02c6..70ce52a9b0cb0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -20,7 +20,6 @@
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/MissingFeatures.h"
 #include "clang/CodeGenUtils/ClassUtils.h"
-#include "clang/CodeGenUtils/CodeGenUtils.h"
 
 using namespace clang;
 using namespace clang::CIRGen;
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 664425b20577f..96c25e84507bd 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -30,8 +30,8 @@
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
 #include "clang/CIR/MissingFeatures.h"
-#include "clang/CodeGenUtils/CodeGenUtils.h"
 #include "clang/CodeGenUtils/ExprUtils.h"
+#include "clang/CodeGenUtils/TargetUtils.h"
 #include <optional>
 
 using namespace clang;
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 9ba717ce7135f..c83770b417123 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -21,7 +21,7 @@
 #include "clang/AST/GlobalDecl.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/MissingFeatures.h"
-#include "clang/CodeGenUtils/CodeGenUtils.h"
+#include "clang/CodeGenUtils/ClassUtils.h"
 #include "clang/CodeGenUtils/FunctionUtils.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/IR/FPEnv.h"
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 18bf3070e49e3..894c347da211e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -36,7 +36,6 @@
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
 #include "clang/CIR/Interfaces/CIROpInterfaces.h"
 #include "clang/CIR/MissingFeatures.h"
-#include "clang/CodeGenUtils/CodeGenUtils.h"
 #include "clang/CodeGenUtils/ModuleUtils.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
index 63715e1f6e814..49651c08c76d2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
@@ -22,8 +22,8 @@
 #include "clang/CIR/Dialect/IR/CIRAttrs.h"
 #include "clang/CIR/Dialect/IR/CIRDataLayout.h"
 #include "clang/CIR/MissingFeatures.h"
-#include "clang/CodeGenUtils/CodeGenUtils.h"
 #include "clang/CodeGenUtils/RecordLayoutUtils.h"
+#include "clang/CodeGenUtils/TargetUtils.h"
 #include "llvm/Support/Casting.h"
 
 #include <memory>
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 63f5d9ae13dbf..31965c98c75bb 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -26,7 +26,6 @@
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
 #include "clang/CodeGenUtils/ClassUtils.h"
-#include "clang/CodeGenUtils/CodeGenUtils.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/Support/SaveAndRestore.h"
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 35fad3a784da9..638e982f92803 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -39,8 +39,8 @@
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SourceManager.h"
-#include "clang/CodeGenUtils/CodeGenUtils.h"
 #include "clang/CodeGenUtils/ExprUtils.h"
+#include "clang/CodeGenUtils/TargetUtils.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/StringExtras.h"
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 905382f5ea939..dc6a7bfca35f6 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -21,8 +21,8 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/CodeGenOptions.h"
-#include "clang/CodeGenUtils/CodeGenUtils.h"
 #include "clang/CodeGenUtils/RecordLayoutUtils.h"
+#include "clang/CodeGenUtils/TargetUtils.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Type.h"
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 745423945ca83..7bc8477db321b 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -36,7 +36,6 @@
 #include "clang/Basic/TargetBuiltins.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
-#include "clang/CodeGenUtils/CodeGenUtils.h"
 #include "clang/CodeGenUtils/FunctionUtils.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/ScopeExit.h"
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index ce21ac7bbfbac..3e32c1fdd6569 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -48,7 +48,6 @@
 #include "clang/Basic/Version.h"
 #include "clang/CodeGen/BackendUtil.h"
 #include "clang/CodeGen/ConstantInitBuilder.h"
-#include "clang/CodeGenUtils/CodeGenUtils.h"
 #include "clang/CodeGenUtils/ModuleUtils.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ABI/IRTypeMapper.h"
diff --git a/clang/lib/CodeGenUtils/CMakeLists.txt b/clang/lib/CodeGenUtils/CMakeLists.txt
index edd32da5b5f7c..b083d95e9d47c 100644
--- a/clang/lib/CodeGenUtils/CMakeLists.txt
+++ b/clang/lib/CodeGenUtils/CMakeLists.txt
@@ -5,7 +5,6 @@ set(LLVM_LINK_COMPONENTS
 add_clang_library(clangCodeGenUtils
   CallUtils.cpp
   ClassUtils.cpp
-  CodeGenUtils.cpp
   EHPersonality.cpp
   ExprUtils.cpp
   FunctionUtils.cpp
diff --git a/clang/lib/CodeGenUtils/ClassUtils.cpp b/clang/lib/CodeGenUtils/ClassUtils.cpp
index 90bab38280c30..b8cd24177529f 100644
--- a/clang/lib/CodeGenUtils/ClassUtils.cpp
+++ b/clang/lib/CodeGenUtils/ClassUtils.cpp
@@ -36,4 +36,85 @@ bool baseInitializerUsesThis(ASTContext &Ctx, const Expr *Init) {
   return Checker.UsesThis;
 }
 
+static bool
+hasTrivialDestructorBody(ASTContext &Context,
+                         const CXXRecordDecl *BaseClassDecl,
+                         const CXXRecordDecl *MostDerivedClassDecl) {
+  // If the destructor is trivial we don't have to check anything else.
+  if (BaseClassDecl->hasTrivialDestructor())
+    return true;
+
+  if (!BaseClassDecl->getDestructor()->hasTrivialBody())
+    return false;
+
+  // Check fields.
+  for (const auto *Field : BaseClassDecl->fields())
+    if (!fieldHasTrivialDestructorBody(Context, Field))
+      return false;
+
+  // Check non-virtual bases.
+  for (const auto &I : BaseClassDecl->bases()) {
+    if (I.isVirtual())
+      continue;
+
+    const auto *NonVirtualBase = I.getType()->castAsCXXRecordDecl();
+    if (!hasTrivialDestructorBody(Context, NonVirtualBase,
+                                  MostDerivedClassDecl))
+      return false;
+  }
+
+  if (BaseClassDecl == MostDerivedClassDecl) {
+    // Check virtual bases.
+    for (const auto &I : BaseClassDecl->vbases()) {
+      const auto *VirtualBase = I.getType()->castAsCXXRecordDecl();
+      if (!hasTrivialDestructorBody(Context, VirtualBase, MostDerivedClassDecl))
+        return false;
+    }
+  }
+
+  return true;
+}
+
+bool fieldHasTrivialDestructorBody(ASTContext &Context,
+                                   const FieldDecl *Field) {
+  QualType FieldBaseElementType = Context.getBaseElementType(Field->getType());
+
+  auto *FieldClassDecl = FieldBaseElementType->getAsCXXRecordDecl();
+  if (!FieldClassDecl)
+    return true;
+
+  // The destructor for an implicit anonymous union member is never invoked.
+  if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
+    return true;
+
+  return hasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl);
+}
+
+bool canSkipVTablePointerInitialization(ASTContext &Ctx,
+                                        const CXXDestructorDecl *Dtor) {
+  const CXXRecordDecl *ClassDecl = Dtor->getParent();
+  if (!ClassDecl->isDynamicClass())
+    return true;
+
+  // For a final class, the vtable pointer is known to already point to the
+  // class's vtable.
+  if (ClassDecl->isEffectivelyFinal())
+    return true;
+
+  if (!Dtor->hasTrivialBody())
+    return false;
+
+  // Check the fields.
+  for (const auto *Field : ClassDecl->fields())
+    if (!fieldHasTrivialDestructorBody(Ctx, Field))
+      return false;
+
+  return true;
+}
+
+bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit) {
+  const Type *BaseType = BaseInit->getBaseClass();
+  return BaseType->castAsCXXRecordDecl()->isDynamicClass();
+}
+
 } // namespace clang::CodeGenUtils
diff --git a/clang/lib/CodeGenUtils/CodeGenUtils.cpp b/clang/lib/CodeGenUtils/CodeGenUtils.cpp
deleted file mode 100644
index 4fd78d6997e95..0000000000000
--- a/clang/lib/CodeGenUtils/CodeGenUtils.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-//==--- CodeGenUtils.cpp - Shared Classic CodeGen/CIR CodeGen Utils--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
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/CodeGenUtils/CodeGenUtils.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/Expr.h"
-#include "clang/Basic/Builtins.h"
-#include "clang/Basic/DiagnosticFrontend.h"
-#include "clang/Basic/TargetBuiltins.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/StringMap.h"
-
-namespace clang::CodeGenUtils {
-static bool
-hasTrivialDestructorBody(ASTContext &Context,
-                         const CXXRecordDecl *BaseClassDecl,
-                         const CXXRecordDecl *MostDerivedClassDecl) {
-  // If the destructor is trivial we don't have to check anything else.
-  if (BaseClassDecl->hasTrivialDestructor())
-    return true;
-
-  if (!BaseClassDecl->getDestructor()->hasTrivialBody())
-    return false;
-
-  // Check fields.
-  for (const auto *Field : BaseClassDecl->fields())
-    if (!fieldHasTrivialDestructorBody(Context, Field))
-      return false;
-
-  // Check non-virtual bases.
-  for (const auto &I : BaseClassDecl->bases()) {
-    if (I.isVirtual())
-      continue;
-
-    const auto *NonVirtualBase = I.getType()->castAsCXXRecordDecl();
-    if (!hasTrivialDestructorBody(Context, NonVirtualBase,
-                                  MostDerivedClassDecl))
-      return false;
-  }
-
-  if (BaseClassDecl == MostDerivedClassDecl) {
-    // Check virtual bases.
-    for (const auto &I : BaseClassDecl->vbases()) {
-      const auto *VirtualBase = I.getType()->castAsCXXRecordDecl();
-      if (!hasTrivialDestructorBody(Context, VirtualBase, MostDerivedClassDecl))
-        return false;
-    }
-  }
-
-  return true;
-}
-
-bool fieldHasTrivialDestructorBody(ASTContext &Context,
-                                   const FieldDecl *Field) {
-  QualType FieldBaseElementType = Context.getBaseElementType(Field->getType());
-
-  auto *FieldClassDecl = FieldBaseElementType->getAsCXXRecordDecl();
-  if (!FieldClassDecl)
-    return true;
-
-  // The destructor for an implicit anonymous union member is never invoked.
-  if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
-    return true;
-
-  return hasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl);
-}
-
-/// Check whether we need to initialize any vtable pointers before calling this
-/// destructor.
-bool canSkipVTablePointerInitialization(ASTContext &Ctx,
-                                        const CXXDestructorDecl *Dtor) {
-  const CXXRecordDecl *ClassDecl = Dtor->getParent();
-  if (!ClassDecl->isDynamicClass())
-    return true;
-
-  // For a final class, the vtable pointer is known to already point to the
-  // class's vtable.
-  if (ClassDecl->isEffectivelyFinal())
-    return true;
-
-  if (!Dtor->hasTrivialBody())
-    return false;
-
-  // Check the fields.
-  for (const auto *Field : ClassDecl->fields())
-    if (!fieldHasTrivialDestructorBody(Ctx, Field))
-      return false;
-
-  return true;
-}
-bool hasUnwindExceptions(const LangOptions &LangOpts) {
-  // If exceptions are completely disabled, obviously this is false.
-  if (!LangOpts.Exceptions)
-    return false;
-
-  // If C++ exceptions are enabled, this is true.
-  if (LangOpts.CXXExceptions)
-    return true;
-
-  // If ObjC exceptions are enabled, this depends on the ABI.
-  if (LangOpts.ObjCExceptions) {
-    return LangOpts.ObjCRuntime.hasUnwindExceptions();
-  }
-
-  return true;
-}
-
-bool isAAPCS(const TargetInfo &TargetInfo) {
-  return TargetInfo.getABI().starts_with("aapcs");
-}
-bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit) {
-  const Type *BaseType = BaseInit->getBaseClass();
-  return BaseType->castAsCXXRecordDecl()->isDynamicClass();
-}
-
-// Emits an error if we don't have a valid set of target features for the
-// called function.
-void checkTargetFeatures(ASTContext &Ctx, DiagnosticsEngine &Diags,
-                         const LangOptions &LangOpts, const CallExpr *E,
-                         const FunctionDecl *Caller,
-                         const FunctionDecl *TargetDecl) {
-  // SemaChecking cannot handle these x86 builtins because they have different
-  // parameter ranges depending on the caller's TargetAttribute.
-  if (Ctx.getTargetInfo().getTriple().isX86()) {
-    unsigned BuiltinID = TargetDecl->getBuiltinID();
-    if (BuiltinID == X86::BI__builtin_ia32_cmpps ||
-        BuiltinID == X86::BI__builtin_ia32_cmpss ||
-        BuiltinID == X86::BI__builtin_ia32_cmppd ||
-        BuiltinID == X86::BI__builtin_ia32_cmpsd) {
-      llvm::StringMap<bool> TargetFeatureMap;
-      Ctx.getFunctionFeatureMap(TargetFeatureMap, Caller);
-      llvm::APSInt Result = *(E->getArg(2)->getIntegerConstantExpr(Ctx));
-      if (Result.getSExtValue() > 7 && !TargetFeatureMap.lookup("avx"))
-        Diags.Report(E->getBeginLoc(), diag::err_builtin_needs_feature)
-            << TargetDecl->getDeclName() << "avx";
-    }
-  }
-  checkTargetFeatures(Ctx, Diags, LangOpts, E->getBeginLoc(), Caller,
-                      TargetDecl);
-}
-
-// Emits an error if we don't have a valid set of target features for the
-// called function.
-void checkTargetFeatures(ASTContext &Ctx, DiagnosticsEngine &Diags,
-                         const LangOptions &LangOpts, SourceLocation Loc,
-                         const FunctionDecl *Caller,
-                         const FunctionDecl *TargetDecl) {
-  if (!TargetDecl || !Caller)
-    return;
-
-  bool IsAlwaysInline = TargetDecl->hasAttr<AlwaysInlineAttr>();
-  bool IsFlatten = Caller->hasAttr<FlattenAttr>();
-
-  unsigned BuiltinID = TargetDecl->getBuiltinID();
-  std::string MissingFeature;
-  llvm::StringMap<bool> CallerFeatureMap;
-  Ctx.getFunctionFeatureMap(CallerFeatureMap, Caller);
-  // When compiling in HipStdPar mode we have to be conservative in rejecting
-  // target specific features in the FE, and defer the possible error to the
-  // AcceleratorCodeSelection pass, wherein iff an unsupported target builtin is
-  // referenced by an accelerator executable function, we emit an error.
-  bool IsHipStdPar = LangOpts.HIPStdPar && LangOpts.CUDAIsDevice;
-  if (BuiltinID) {
-    StringRef FeatureList(Ctx.BuiltinInfo.getRequiredFeatures(BuiltinID));
-    if (!Builtin::evaluateRequiredTargetFeatures(FeatureList,
-                                                 CallerFeatureMap) &&
-        !IsHipStdPar)
-      Diags.Report(Loc, diag::err_builtin_needs_feature)
-          << TargetDecl->getDeclName() << FeatureList;
-  } else if (!TargetDecl->isMultiVersion() &&
-             TargetDecl->hasAttr<TargetAttr>()) {
-    // Get the required features for the callee.
-    const TargetAttr *TD = TargetDecl->getAttr<TargetAttr>();
-    ParsedTargetAttr ParsedAttr = Ctx.filterFunctionTargetAttrs(TD);
-
-    SmallVector<StringRef, 1> ReqFeatures;
-    llvm::StringMap<bool> CalleeFeatureMap;
-    Ctx.getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);
-
-    for (const auto &F : ParsedAttr.Features) {
-      if (F[0] == '+' && CalleeFeatureMap.lookup(F.substr(1)))
-        ReqFeatures.push_back(StringRef(F).substr(1));
-    }
-    for (const auto &F : CalleeFeatureMap) {
-      if (F.getValue())
-        ReqFeatures.push_back(F.getKey());
-    }
-    if (!llvm::all_of(ReqFeatures,
-                      [&](StringRef Feature) {
-                        if (!CallerFeatureMap.lookup(Feature)) {
-                          MissingFeature = Feature.str();
-                          return false;
-                        }
-                        return true;
-                      }) &&
-        !IsHipStdPar) {
-      if (IsAlwaysInline)
-        Diags.Report(Loc, diag::err_function_needs_feature)
-            << Caller->getDeclName() << TargetDecl->getDeclName()
-            << MissingFeature;
-      else if (IsFlatten)
-        Diags.Report(Loc, diag::err_flatten_function_needs_feature)
-            << Caller->getDeclName() << TargetDecl->getDeclName()
-            << MissingFeature;
-    }
-  } else if (!Caller->isMultiVersion() && Caller->hasAttr<TargetAttr>()) {
-    llvm::StringMap<bool> CalleeFeatureMap;
-    Ctx.getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);
-
-    for (const auto &F : CalleeFeatureMap) {
-      if (F.getValue() &&
-          (!CallerFeatureMap.lookup(F.getKey()) ||
-           !CallerFeatureMap.find(F.getKey())->getValue()) &&
-          !IsHipStdPar) {
-        if (IsAlwaysInline)
-          Diags.Report(Loc, diag::err_function_needs_feature)
-              << Caller->getDeclName() << TargetDecl->getDeclName()
-              << F.getKey();
-        else if (IsFlatten)
-          Diags.Report(Loc, diag::err_flatten_function_needs_feature)
-              << Caller->getDeclName() << TargetDecl->getDeclName()
-              << F.getKey();
-      }
-    }
-  }
-}
-
-} // namespace clang::CodeGenUtils
diff --git a/clang/lib/CodeGenUtils/FunctionUtils.cpp b/clang/lib/CodeGenUtils/FunctionUtils.cpp
index 9f01745abbf82..083c04d30bec4 100644
--- a/clang/lib/CodeGenUtils/FunctionUtils.cpp
+++ b/clang/lib/CodeGenUtils/FunctionUtils.cpp
@@ -7,6 +7,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/CodeGenUtils/FunctionUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/Expr.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/Basic/TargetBuiltins.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/StringMap.h"
 
 namespace clang::CodeGenUtils {
 
@@ -26,4 +34,116 @@ bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts,
   return CGOpts.OptimizationLevel != 0;
 }
 
+// Emits an error if we don't have a valid set of target features for the
+// called function.
+void checkTargetFeatures(ASTContext &Ctx, DiagnosticsEngine &Diags,
+                         const LangOptions &LangOpts, const CallExpr *E,
+                         const FunctionDecl *Caller,
+                         const FunctionDecl *TargetDecl) {
+  // SemaChecking cannot handle these x86 builtins because they have different
+  // parameter ranges depending on the caller's TargetAttribute.
+  if (Ctx.getTargetInfo().getTriple().isX86()) {
+    unsigned BuiltinID = TargetDecl->getBuiltinID();
+    if (BuiltinID == X86::BI__builtin_ia32_cmpps ||
+        BuiltinID == X86::BI__builtin_ia32_cmpss ||
+        BuiltinID == X86::BI__builtin_ia32_cmppd ||
+        BuiltinID == X86::BI__builtin_ia32_cmpsd) {
+      llvm::StringMap<bool> TargetFeatureMap;
+      Ctx.getFunctionFeatureMap(TargetFeatureMap, Caller);
+      llvm::APSInt Result = *(E->getArg(2)->getIntegerConstantExpr(Ctx));
+      if (Result.getSExtValue() > 7 && !TargetFeatureMap.lookup("avx"))
+        Diags.Report(E->getBeginLoc(), diag::err_builtin_needs_feature)
+            << TargetDecl->getDeclName() << "avx";
+    }
+  }
+  checkTargetFeatures(Ctx, Diags, LangOpts, E->getBeginLoc(), Caller,
+                      TargetDecl);
+}
+
+// Emits an error if we don't have a valid set of target features for the
+// called function.
+void checkTargetFeatures(ASTContext &Ctx, DiagnosticsEngine &Diags,
+                         const LangOptions &LangOpts, SourceLocation Loc,
+                         const FunctionDecl *Caller,
+                         const FunctionDecl *TargetDecl) {
+  if (!TargetDecl || !Caller)
+    return;
+
+  bool IsAlwaysInline = TargetDecl->hasAttr<AlwaysInlineAttr>();
+  bool IsFlatten = Caller->hasAttr<FlattenAttr>();
+
+  unsigned BuiltinID = TargetDecl->getBuiltinID();
+  std::string MissingFeature;
+  llvm::StringMap<bool> CallerFeatureMap;
+  Ctx.getFunctionFeatureMap(CallerFeatureMap, Caller);
+  // When compiling in HipStdPar mode we have to be conservative in rejecting
+  // target specific features in the FE, and defer the possible error to the
+  // AcceleratorCodeSelection pass, wherein iff an unsupported target builtin is
+  // referenced by an accelerator executable function, we emit an error.
+  bool IsHipStdPar = LangOpts.HIPStdPar && LangOpts.CUDAIsDevice;
+  if (BuiltinID) {
+    StringRef FeatureList(Ctx.BuiltinInfo.getRequiredFeatures(BuiltinID));
+    if (!Builtin::evaluateRequiredTargetFeatures(FeatureList,
+                                                 CallerFeatureMap) &&
+        !IsHipStdPar)
+      Diags.Report(Loc, diag::err_builtin_needs_feature)
+          << TargetDecl->getDeclName() << FeatureList;
+  } else if (!TargetDecl->isMultiVersion() &&
+             TargetDecl->hasAttr<TargetAttr>()) {
+    // Get the required features for the callee.
+    const TargetAttr *TD = TargetDecl->getAttr<TargetAttr>();
+    ParsedTargetAttr ParsedAttr = Ctx.filterFunctionTargetAttrs(TD);
+
+    SmallVector<StringRef, 1> ReqFeatures;
+    llvm::StringMap<bool> CalleeFeatureMap;
+    Ctx.getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);
+
+    for (const auto &F : ParsedAttr.Features) {
+      if (F[0] == '+' && CalleeFeatureMap.lookup(F.substr(1)))
+        ReqFeatures.push_back(StringRef(F).substr(1));
+    }
+    for (const auto &F : CalleeFeatureMap) {
+      if (F.getValue())
+        ReqFeatures.push_back(F.getKey());
+    }
+    if (!llvm::all_of(ReqFeatures,
+                      [&](StringRef Feature) {
+                        if (!CallerFeatureMap.lookup(Feature)) {
+                          MissingFeature = Feature.str();
+                          return false;
+                        }
+                        return true;
+                      }) &&
+        !IsHipStdPar) {
+      if (IsAlwaysInline)
+        Diags.Report(Loc, diag::err_function_needs_feature)
+            << Caller->getDeclName() << TargetDecl->getDeclName()
+            << MissingFeature;
+      else if (IsFlatten)
+        Diags.Report(Loc, diag::err_flatten_function_needs_feature)
+            << Caller->getDeclName() << TargetDecl->getDeclName()
+            << MissingFeature;
+    }
+  } else if (!Caller->isMultiVersion() && Caller->hasAttr<TargetAttr>()) {
+    llvm::StringMap<bool> CalleeFeatureMap;
+    Ctx.getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);
+
+    for (const auto &F : CalleeFeatureMap) {
+      if (F.getValue() &&
+          (!CallerFeatureMap.lookup(F.getKey()) ||
+           !CallerFeatureMap.find(F.getKey())->getValue()) &&
+          !IsHipStdPar) {
+        if (IsAlwaysInline)
+          Diags.Report(Loc, diag::err_function_needs_feature)
+              << Caller->getDeclName() << TargetDecl->getDeclName()
+              << F.getKey();
+        else if (IsFlatten)
+          Diags.Report(Loc, diag::err_flatten_function_needs_feature)
+              << Caller->getDeclName() << TargetDecl->getDeclName()
+              << F.getKey();
+      }
+    }
+  }
+}
+
 } // namespace clang::CodeGenUtils
diff --git a/clang/lib/CodeGenUtils/ModuleUtils.cpp b/clang/lib/CodeGenUtils/ModuleUtils.cpp
index 0d4882345e303..89655301400e6 100644
--- a/clang/lib/CodeGenUtils/ModuleUtils.cpp
+++ b/clang/lib/CodeGenUtils/ModuleUtils.cpp
@@ -12,6 +12,23 @@
 
 namespace clang::CodeGenUtils {
 
+bool hasUnwindExceptions(const LangOptions &LangOpts) {
+  // If exceptions are completely disabled, obviously this is false.
+  if (!LangOpts.Exceptions)
+    return false;
+
+  // If C++ exceptions are enabled, this is true.
+  if (LangOpts.CXXExceptions)
+    return true;
+
+  // If ObjC exceptions are enabled, this depends on the ABI.
+  if (LangOpts.ObjCExceptions) {
+    return LangOpts.ObjCRuntime.hasUnwindExceptions();
+  }
+
+  return true;
+}
+
 bool isVarDeclStrongDefinition(const ASTContext &Ctx, const VarDecl *D,
                                bool NoCommon) {
   // Don't give variables common linkage if -fno-common was specified unless it
diff --git a/clang/lib/CodeGenUtils/TargetUtils.cpp b/clang/lib/CodeGenUtils/TargetUtils.cpp
index f72218f4dda2d..86ebb29410d10 100644
--- a/clang/lib/CodeGenUtils/TargetUtils.cpp
+++ b/clang/lib/CodeGenUtils/TargetUtils.cpp
@@ -10,6 +10,7 @@
 #include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/Basic/TargetBuiltins.h"
+#include "clang/Basic/TargetInfo.h"
 
 namespace clang::CodeGenUtils {
 
@@ -72,6 +73,10 @@ bool hasExtraNeonArgument(unsigned BuiltinID) {
   return mask != 0;
 }
 
+bool isAAPCS(const TargetInfo &TargetInfo) {
+  return TargetInfo.getABI().starts_with("aapcs");
+}
+
 bool requiresAMDGPUProtectedVisibility(const Decl *D,
                                        bool HasHiddenVisibility) {
   if (!HasHiddenVisibility)



More information about the llvm-branch-commits mailing list