clang 24.0.0git
CIRGenDeclCXX.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This contains code dealing with code generation of C++ declarations
10//
11//===----------------------------------------------------------------------===//
12
13#include "CIRGenCXXABI.h"
14#include "CIRGenFunction.h"
15#include "CIRGenModule.h"
16#include "clang/AST/Attr.h"
17#include "clang/AST/Mangle.h"
20
21using namespace clang;
22using namespace clang::CIRGen;
23
25 cir::GlobalOp globalOp,
26 bool performInit) {
27 // If we've been asked to forbid guard variables, emit an error now.
28 // This diagnostic is hard-coded for Darwin's use case; we can find
29 // better phrasing if someone else needs it.
30 if (cgm.getCodeGenOpts().ForbidGuardVariables)
31 cgm.error(varDecl.getLocation(), "guard variables are forbidden");
32
33 // Compute the mangled guard variable name and set the dynamic_init_guard
34 // attribute BEFORE emitting initialization. This ensures that GetGlobalOps
35 // created during initialization (e.g., in the ctor region) will see the
36 // attribute and be marked with static_local accordingly.
37 llvm::SmallString<256> guardName;
38 {
39 llvm::raw_svector_ostream out(guardName);
40 cgm.getCXXABI().getMangleContext().mangleStaticGuardVariable(&varDecl, out);
41 }
42
43 // Mark the global as requiring guarded dynamic initialization, with the
44 // guard name. The emission of the guard/acquire is done during
45 // LoweringPrepare.
46 auto guardAttr = mlir::StringAttr::get(&cgm.getMLIRContext(), guardName);
47
48 globalOp.setDynamicInitGuardAttr(
49 cir::DynamicInitGuardAttr::get(&cgm.getMLIRContext(), guardAttr));
50
51 if (varDecl.isStaticLocal())
52 cgm.emitCXXStaticLocalVarDeclInit(&varDecl, globalOp, performInit);
53 else
54 cgm.emitCXXGlobalVarDeclInit(&varDecl, globalOp, performInit);
55}
56
58 cir::GlobalOp globalOp) {
59 assert(!vd.isStaticLocal() && vd.getTLSKind());
60
61 // C doesn't need guarded thread-local init, because it can't have
62 // non-constant init.
64 return;
65
66 // TLS Static doesn't need a wrapper.
68 return;
69
70 llvm::SmallString<256> wrapperFuncName;
71 llvm::SmallString<256> initFuncName;
72 llvm::SmallString<256> guardName;
73
74 if (getCXXABI().getMangleContext().getKind() == MangleContext::MK_Itanium) {
75 llvm::raw_svector_ostream wrapperOut(wrapperFuncName);
76 llvm::raw_svector_ostream initOut(initFuncName);
77 llvm::raw_svector_ostream guardStream(guardName);
78
79 auto &mc = cast<ItaniumMangleContext>(getCXXABI().getMangleContext());
80 mc.mangleItaniumThreadLocalWrapper(&vd, wrapperOut);
81 mc.mangleItaniumThreadLocalInit(&vd, initOut);
82 if (globalOp.hasWeakLinkage() || globalOp.hasLinkOnceLinkage() ||
85 guardStream);
86 }
87
88 } else {
90 "setGlobalTlsReferences: non-itanium mangler");
91 return;
92 }
93 globalOp.setTlsRefsAttr(cir::ThreadLocalGlobalWrapperInitAttr::get(
94 &getMLIRContext(), wrapperFuncName, initFuncName, guardName));
95}
96
98 cir::GlobalOp addr,
99 bool performInit) {
100 // Sema has already checked that the initializers of device-side variables
101 // are empty, so they can be ignored.
102 if (getLangOpts().CUDAIsDevice && !getLangOpts().GPUAllowDeviceInit &&
103 (vd->hasAttr<CUDADeviceAttr>() || vd->hasAttr<CUDAConstantAttr>() ||
104 vd->hasAttr<CUDASharedAttr>()))
105 return;
106
107 // Classic CodeGen dispatches guarded initialization through
108 // CGCXXABI::EmitGuardedInit, which the Microsoft ABI overrides with a
109 // completely different (bitmask-based "magic statics") guard scheme
110 // instead of the Itanium __cxa_guard_acquire/__cxa_guard_release calls
111 // that emitCXXGuardedInit/LoweringPrepare unconditionally assume here.
113
114 if (addr.hasWeakLinkage() || addr.hasLinkOnceLinkage() ||
117 CIRGenFunction(*this, builder).emitCXXGuardedInit(*vd, addr, performInit);
118 } else {
119 emitCXXGlobalVarDeclInit(vd, addr, performInit);
120 }
121}
static Decl::Kind getKind(const Decl *D)
Defines the clang::LangOptions interface.
clang::MangleContext & getMangleContext()
Gets the mangle context.
void emitCXXGuardedInit(const VarDecl &varDecl, cir::GlobalOp globalOp, bool performInit)
Emit a guarded initializer for a static local variable.
void emitCXXGlobalVarDeclInit(const VarDecl *varDecl, cir::GlobalOp addr, bool performInit)
Emit the function that initializes the specified global.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
void setGlobalTlsReferences(const VarDecl &vd, cir::GlobalOp globalOp)
const clang::LangOptions & getLangOpts() const
void emitCXXGlobalVarDeclInitFunc(const VarDecl *vd, cir::GlobalOp addr, bool performInit)
mlir::MLIRContext & getMLIRContext()
CIRGenCXXABI & getCXXABI() const
bool hasAttr() const
Definition DeclBase.h:585
virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &)=0
Represents a variable declaration or definition.
Definition Decl.h:933
TLSKind getTLSKind() const
Definition Decl.cpp:2148
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2170
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition Decl.h:1215
@ TLS_Dynamic
TLS with a dynamic initializer.
Definition Decl.h:959
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
Definition Decl.cpp:2754
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
Top level wrappers for InstallAPI frontend operations.
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
Definition Specifiers.h:216
@ CPlusPlus
U cast(CodeGen::Address addr)
Definition Address.h:327