Files
TheRock/compiler/amd-llvm/clang/lib/CIR/CodeGen/CIRGenDeclCXX.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

122 lines
4.9 KiB
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 contains code dealing with code generation of C++ declarations
//
//===----------------------------------------------------------------------===//
#include "CIRGenCXXABI.h"
#include "CIRGenFunction.h"
#include "CIRGenModule.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Mangle.h"
#include "clang/Basic/LangOptions.h"
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
using namespace clang;
using namespace clang::CIRGen;
void CIRGenFunction::emitCXXGuardedInit(const VarDecl &varDecl,
cir::GlobalOp globalOp,
bool performInit) {
// If we've been asked to forbid guard variables, emit an error now.
// This diagnostic is hard-coded for Darwin's use case; we can find
// better phrasing if someone else needs it.
if (cgm.getCodeGenOpts().ForbidGuardVariables)
cgm.error(varDecl.getLocation(), "guard variables are forbidden");
// Compute the mangled guard variable name and set the static_local attribute
// BEFORE emitting initialization. This ensures that GetGlobalOps created
// during initialization (e.g., in the ctor region) will see the attribute
// and be marked with static_local accordingly.
llvm::SmallString<256> guardName;
{
llvm::raw_svector_ostream out(guardName);
cgm.getCXXABI().getMangleContext().mangleStaticGuardVariable(&varDecl, out);
}
// Mark the global as static local with the guard name. The emission of the
// guard/acquire is done during LoweringPrepare.
auto guardAttr = mlir::StringAttr::get(&cgm.getMLIRContext(), guardName);
if (!varDecl.isStaticLocal())
cgm.errorNYI(
varDecl.getSourceRange(),
"Static local guard attr only valid on static local variables");
globalOp.setStaticLocalGuardAttr(
cir::StaticLocalGuardAttr::get(&cgm.getMLIRContext(), guardAttr));
// Emit the initializer and add a global destructor if appropriate.
// TODO(cir): classic codegen calls emitCXXGlobalVarDeclInit for this as well,
// and this is meant to handle cases with weak linkage (see comment in
// emitCXXGlobalVarDeclInitFunc). At one point we'll have to do some level of
// split here depending on whether this is a global (which should/can have
// ctor/dtor regions), or should have in-function initialization.
cgm.emitCXXStaticLocalVarDeclInit(&varDecl, globalOp, performInit);
}
void CIRGenModule::setGlobalTlsReferences(const VarDecl &vd,
cir::GlobalOp globalOp) {
assert(!vd.isStaticLocal() && vd.getTLSKind());
// C doesn't need guarded thread-local init, because it can't have
// non-constant init.
if (!getLangOpts().CPlusPlus)
return;
if (globalOp.getTlsModel() != cir::TLS_Model::GeneralDynamic)
return;
llvm::SmallString<256> wrapperFuncName;
llvm::SmallString<256> initFuncName;
llvm::SmallString<256> guardName;
if (getCXXABI().getMangleContext().getKind() == MangleContext::MK_Itanium) {
llvm::raw_svector_ostream wrapperOut(wrapperFuncName);
llvm::raw_svector_ostream initOut(initFuncName);
llvm::raw_svector_ostream guardStream(guardName);
auto &mc = cast<ItaniumMangleContext>(getCXXABI().getMangleContext());
mc.mangleItaniumThreadLocalWrapper(&vd, wrapperOut);
mc.mangleItaniumThreadLocalInit(&vd, initOut);
if (globalOp.hasWeakLinkage() || globalOp.hasLinkOnceLinkage() ||
isTemplateInstantiation(vd.getTemplateSpecializationKind())) {
getCXXABI().getMangleContext().mangleStaticGuardVariable(&vd,
guardStream);
}
} else {
errorNYI(vd.getSourceRange(),
"setGlobalTlsReferences: non-itanium mangler");
return;
}
globalOp.setDynTlsRefsAttr(cir::ThreadLocalGlobalWrapperInitAttr::get(
&getMLIRContext(), wrapperFuncName, initFuncName, guardName));
}
void CIRGenModule::emitCXXGlobalVarDeclInitFunc(const VarDecl *vd,
cir::GlobalOp addr,
bool performInit) {
assert(!cir::MissingFeatures::cudaSupport());
assert(!cir::MissingFeatures::deferredCXXGlobalInit());
// TODO(cir): Classic codegen calls emitCXXGuardedInit in the following case:
// template<typename T> struct Templ {
// static T f;
// };
// template<typename T> T Templ<T>::f = get_i();
// auto func() {
// Templ<int> t;
// return decltype(t)::f;
// }
//
// However, at the moment it is only suitable for static-local variables, so
// we will have to modify it to work for this case as well.
emitCXXGlobalVarDeclInit(vd, addr, performInit);
}