https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/223451
>From 401843a4a8ca3b721d1c66c06c86fee38fbd46c9 Mon Sep 17 00:00:00 2001 From: Henrich Lauko <[email protected]> Date: Wed, 7 Oct 2026 18:19:45 +0000 Subject: [PATCH] [CIR][CodeGen][NFC] Retire the CodeGenUtils.h catch-all header Moves the last helpers out of `CodeGenUtils.h` into `ClassUtils.h`, `ModuleUtils.h`, `TargetUtils.h` and `FunctionUtils.h` (`checkTargetFeatures`, since it came from CodeGenFunction.cpp) and deletes the header. Only moves code already on main, so it can be dropped on its own. Assisted-by: Claude Code (Claude Fable 5.1). --- clang/include/clang/CodeGenUtils/ClassUtils.h | 18 ++ .../include/clang/CodeGenUtils/CodeGenUtils.h | 78 ----- .../clang/CodeGenUtils/FunctionUtils.h | 26 +- .../include/clang/CodeGenUtils/ModuleUtils.h | 15 + .../include/clang/CodeGenUtils/TargetUtils.h | 18 ++ 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/CIR/CodeGen/Targets/SPIRV.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/CodeGen/Targets/SPIR.cpp | 2 +- clang/lib/CodeGenUtils/CMakeLists.txt | 1 - clang/lib/CodeGenUtils/ClassUtils.cpp | 78 +++++ clang/lib/CodeGenUtils/CodeGenUtils.cpp | 269 ------------------ clang/lib/CodeGenUtils/FunctionUtils.cpp | 120 ++++++++ clang/lib/CodeGenUtils/ModuleUtils.cpp | 37 +++ clang/lib/CodeGenUtils/TargetUtils.cpp | 27 ++ 24 files changed, 345 insertions(+), 363 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 63664ed737933a..570c67110e1208 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 &Ctx, 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 8d77264e2b4ef1..00000000000000 --- a/clang/include/clang/CodeGenUtils/CodeGenUtils.h +++ /dev/null @@ -1,78 +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); - -/// Return the AST address space of constant literal, which is used to emit -/// the constant literal as global variable in LLVM IR. -/// Note: This is not necessarily the address space of the constant literal -/// in AST. For address space agnostic language, e.g. C++, constant literal -/// in AST is always in default address space. -LangAS getGlobalConstantAddressSpace(const LangOptions &LangOpts, - const TargetInfo &Target); - -bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit); - -/// Return true if a SPIR(-V) null pointer of type \p QT must be materialized -/// as an addrspacecast from a generic null pointer, as the null bit pattern in -/// non-generic address spaces is unspecified. -bool spirNullPointerNeedsGenericCast(QualType QT, const llvm::Triple &Triple); - -/// 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 f924874d829e06..4e500aa8d3c0b6 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 5c7423ad4fac54..10b39438567dbb 100644 --- a/clang/include/clang/CodeGenUtils/ModuleUtils.h +++ b/clang/include/clang/CodeGenUtils/ModuleUtils.h @@ -19,6 +19,21 @@ 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. +/// Return the AST address space of constant literal, which is used to emit +/// the constant literal as global variable in LLVM IR. +/// Note: This is not necessarily the address space of the constant literal +/// in AST. For address space agnostic language, e.g. C++, constant literal +/// in AST is always in default address space. +LangAS getGlobalConstantAddressSpace(const LangOptions &LangOpts, + const TargetInfo &Target); + +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 f32941a6630a09..1d1ada1644efc8 100644 --- a/clang/include/clang/CodeGenUtils/TargetUtils.h +++ b/clang/include/clang/CodeGenUtils/TargetUtils.h @@ -18,9 +18,15 @@ #include <cstdint> +namespace llvm { +class Triple; +} // namespace llvm + namespace clang { class Decl; class FunctionDecl; +class QualType; +class TargetInfo; } // namespace clang namespace clang::CodeGenUtils { @@ -54,6 +60,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); + //===----------------------------------------------------------------------===// // AMDGPU //===----------------------------------------------------------------------===// @@ -63,6 +72,15 @@ bool hasExtraNeonArgument(unsigned BuiltinID); /// visibility. bool requiresAMDGPUProtectedVisibility(const Decl *D, bool HasHiddenVisibility); +//===----------------------------------------------------------------------===// +// SPIR-V +//===----------------------------------------------------------------------===// + +/// Return true if a SPIR(-V) null pointer of type \p QT must be materialized +/// as an addrspacecast from a generic null pointer, as the null bit pattern in +/// non-generic address spaces is unspecified. +bool spirNullPointerNeedsGenericCast(QualType QT, const llvm::Triple &Triple); + } // namespace clang::CodeGenUtils #endif // LLVM_CLANG_CODEGENUTILS_TARGETUTILS_H diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 192ce77cc54bf4..9edbf04a55bb46 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 5b270e2b36a0e9..679fe082ac37ef 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 c03f7b355b6959..1db65c0d368816 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -30,9 +30,9 @@ #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/RecordLayoutUtils.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 2d8d4e802f84f8..5912072b30a8b1 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 1b17ad636829d5..0e459f59d9aaa6 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 "clang/CodeGenUtils/RecordLayoutUtils.h" #include "llvm/ADT/STLExtras.h" diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp index 4bb483fc57a962..7ecb316efecb58 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/CIR/CodeGen/Targets/SPIRV.cpp b/clang/lib/CIR/CodeGen/Targets/SPIRV.cpp index 3e6f41a46acc67..8e36b25301dc9e 100644 --- a/clang/lib/CIR/CodeGen/Targets/SPIRV.cpp +++ b/clang/lib/CIR/CodeGen/Targets/SPIRV.cpp @@ -16,7 +16,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" -#include "clang/CodeGenUtils/CodeGenUtils.h" +#include "clang/CodeGenUtils/TargetUtils.h" using namespace clang; using namespace clang::CIRGen; diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 7e832f8155aa72..2901233638ffee 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 "clang/CodeGenUtils/RecordLayoutUtils.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Metadata.h" diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 8323a170a1dbbc..7f72da4f0e4785 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -39,9 +39,9 @@ #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/RecordLayoutUtils.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 300fd521e36cf1..6e7df1395350c8 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 8fb9533cd78757..70586425974872 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 33339c43e8a165..92af8832f01ed8 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/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index 244dd10d1f7caa..207386759827f5 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -11,7 +11,7 @@ #include "TargetInfo.h" #include "clang/AST/DeclCXX.h" #include "clang/Basic/LangOptions.h" -#include "clang/CodeGenUtils/CodeGenUtils.h" +#include "clang/CodeGenUtils/TargetUtils.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/LLVMContext.h" diff --git a/clang/lib/CodeGenUtils/CMakeLists.txt b/clang/lib/CodeGenUtils/CMakeLists.txt index 7fb94a994bfedd..dc701f8dbc72f2 100644 --- a/clang/lib/CodeGenUtils/CMakeLists.txt +++ b/clang/lib/CodeGenUtils/CMakeLists.txt @@ -9,7 +9,6 @@ add_clang_library(clangCodeGenUtils BackendDiagnosticHandler.cpp 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 90bab38280c30b..5a504ca0b5beb0 100644 --- a/clang/lib/CodeGenUtils/ClassUtils.cpp +++ b/clang/lib/CodeGenUtils/ClassUtils.cpp @@ -36,4 +36,82 @@ bool baseInitializerUsesThis(ASTContext &Ctx, const Expr *Init) { return Checker.UsesThis; } +static bool +hasTrivialDestructorBody(ASTContext &Ctx, 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(Ctx, 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(Ctx, NonVirtualBase, MostDerivedClassDecl)) + return false; + } + + if (BaseClassDecl == MostDerivedClassDecl) { + // Check virtual bases. + for (const auto &I : BaseClassDecl->vbases()) { + const auto *VirtualBase = I.getType()->castAsCXXRecordDecl(); + if (!hasTrivialDestructorBody(Ctx, VirtualBase, MostDerivedClassDecl)) + return false; + } + } + + return true; +} + +bool fieldHasTrivialDestructorBody(ASTContext &Ctx, const FieldDecl *Field) { + QualType FieldBaseElementType = Ctx.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(Ctx, 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 fc1ceb006ec05f..00000000000000 --- a/clang/lib/CodeGenUtils/CodeGenUtils.cpp +++ /dev/null @@ -1,269 +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"); -} - -LangAS getGlobalConstantAddressSpace(const LangOptions &LangOpts, - const TargetInfo &Target) { - // OpenCL v1.2 s6.5.3: a string literal is in the constant address space. - if (LangOpts.OpenCL) - return LangAS::opencl_constant; - if (LangOpts.SYCLIsDevice) - return LangAS::sycl_global; - if (LangOpts.HIP && LangOpts.CUDAIsDevice && Target.getTriple().isSPIRV()) - // For HIPSPV map literals to cuda_device (maps to CrossWorkGroup in SPIR-V) - // instead of default AS (maps to Generic in SPIR-V). Otherwise, we end up - // with OpVariable instructions with Generic storage class which is not - // allowed (SPIR-V V1.6 s3.42.8). Also, mapping literals to SPIR-V - // UniformConstant storage class is not viable as pointers to it may not be - // casted to Generic pointers which are used to model HIP's "flat" pointers. - return LangAS::cuda_device; - if (auto AS = Target.getConstantAddressSpace()) - return *AS; - return LangAS::Default; -} - -bool spirNullPointerNeedsGenericCast(QualType QT, const llvm::Triple &Triple) { - // LLVM address space of the SPIR-V CodeSectionINTEL storage class. - constexpr unsigned SPIRVCodeSectionINTELAddrSpace = 9; - LangAS AS = QT->getUnqualifiedDesugaredType()->isNullPtrType() - ? LangAS::Default - : QT->getPointeeType().getAddressSpace(); - if (AS == LangAS::Default || AS == LangAS::opencl_generic || - AS == LangAS::opencl_constant) - return false; - // As per SPV_INTEL_function_pointers, it is illegal to addrspacecast - // function pointers to/from the generic AS. - return !(Triple.isSPIRV() && isTargetAddressSpace(AS) && - toTargetAddressSpace(AS) == SPIRVCodeSectionINTELAddrSpace); -} - -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 9f01745abbf82c..083c04d30bec4c 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 0d4882345e303d..93209970501c62 100644 --- a/clang/lib/CodeGenUtils/ModuleUtils.cpp +++ b/clang/lib/CodeGenUtils/ModuleUtils.cpp @@ -12,6 +12,43 @@ namespace clang::CodeGenUtils { +LangAS getGlobalConstantAddressSpace(const LangOptions &LangOpts, + const TargetInfo &Target) { + // OpenCL v1.2 s6.5.3: a string literal is in the constant address space. + if (LangOpts.OpenCL) + return LangAS::opencl_constant; + if (LangOpts.SYCLIsDevice) + return LangAS::sycl_global; + if (LangOpts.HIP && LangOpts.CUDAIsDevice && Target.getTriple().isSPIRV()) + // For HIPSPV map literals to cuda_device (maps to CrossWorkGroup in SPIR-V) + // instead of default AS (maps to Generic in SPIR-V). Otherwise, we end up + // with OpVariable instructions with Generic storage class which is not + // allowed (SPIR-V V1.6 s3.42.8). Also, mapping literals to SPIR-V + // UniformConstant storage class is not viable as pointers to it may not be + // casted to Generic pointers which are used to model HIP's "flat" pointers. + return LangAS::cuda_device; + if (auto AS = Target.getConstantAddressSpace()) + return *AS; + return LangAS::Default; +} + +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 779a03bcf9f44a..c2ddc7ec69da4b 100644 --- a/clang/lib/CodeGenUtils/TargetUtils.cpp +++ b/clang/lib/CodeGenUtils/TargetUtils.cpp @@ -9,7 +9,11 @@ #include "clang/CodeGenUtils/TargetUtils.h" #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" +#include "clang/AST/Type.h" +#include "clang/Basic/AddressSpaces.h" #include "clang/Basic/TargetBuiltins.h" +#include "clang/Basic/TargetInfo.h" +#include "llvm/TargetParser/Triple.h" namespace clang::CodeGenUtils { @@ -76,6 +80,10 @@ bool hasExtraNeonArgument(unsigned BuiltinID) { return mask != 0; } +bool isAAPCS(const TargetInfo &TargetInfo) { + return TargetInfo.getABI().starts_with("aapcs"); +} + //===----------------------------------------------------------------------===// // AMDGPU //===----------------------------------------------------------------------===// @@ -94,4 +102,23 @@ bool requiresAMDGPUProtectedVisibility(const Decl *D, cast<VarDecl>(D)->getType()->isCUDADeviceBuiltinTextureType()))); } +//===----------------------------------------------------------------------===// +// SPIR-V +//===----------------------------------------------------------------------===// + +bool spirNullPointerNeedsGenericCast(QualType QT, const llvm::Triple &Triple) { + // LLVM address space of the SPIR-V CodeSectionINTEL storage class. + constexpr unsigned SPIRVCodeSectionINTELAddrSpace = 9; + LangAS AS = QT->getUnqualifiedDesugaredType()->isNullPtrType() + ? LangAS::Default + : QT->getPointeeType().getAddressSpace(); + if (AS == LangAS::Default || AS == LangAS::opencl_generic || + AS == LangAS::opencl_constant) + return false; + // As per SPV_INTEL_function_pointers, it is illegal to addrspacecast + // function pointers to/from the generic AS. + return !(Triple.isSPIRV() && isTargetAddressSpace(AS) && + toTargetAddressSpace(AS) == SPIRVCodeSectionINTELAddrSpace); +} + } // namespace clang::CodeGenUtils _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
