clang 23.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 static_local attribute
34 // BEFORE emitting initialization. This ensures that GetGlobalOps created
35 // during initialization (e.g., in the ctor region) will see the attribute
36 // 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 static local with the guard name. The emission of the
44 // guard/acquire is done during LoweringPrepare.
45 auto guardAttr = mlir::StringAttr::get(&cgm.getMLIRContext(), guardName);
46 if (!varDecl.isStaticLocal())
47 cgm.errorNYI(
48 varDecl.getSourceRange(),
49 "Static local guard attr only valid on static local variables");
50 globalOp.setStaticLocalGuardAttr(
51 cir::StaticLocalGuardAttr::get(&cgm.getMLIRContext(), guardAttr));
52
53 // Emit the initializer and add a global destructor if appropriate.
54 // TODO(cir): classic codegen calls emitCXXGlobalVarDeclInit for this as well,
55 // and this is meant to handle cases with weak linkage (see comment in
56 // emitCXXGlobalVarDeclInitFunc). At one point we'll have to do some level of
57 // split here depending on whether this is a global (which should/can have
58 // ctor/dtor regions), or should have in-function initialization.
59 cgm.emitCXXStaticLocalVarDeclInit(&varDecl, globalOp, performInit);
60}
61
63 cir::GlobalOp globalOp) {
64 assert(!vd.isStaticLocal() && vd.getTLSKind());
65
66 // C doesn't need guarded thread-local init, because it can't have
67 // non-constant init.
69 return;
70
71 if (globalOp.getTlsModel() != cir::TLS_Model::GeneralDynamic)
72 return;
73
74 llvm::SmallString<256> wrapperFuncName;
75 llvm::SmallString<256> initFuncName;
76 llvm::SmallString<256> guardName;
77
78 if (getCXXABI().getMangleContext().getKind() == MangleContext::MK_Itanium) {
79 llvm::raw_svector_ostream wrapperOut(wrapperFuncName);
80 llvm::raw_svector_ostream initOut(initFuncName);
81 llvm::raw_svector_ostream guardStream(guardName);
82
83 auto &mc = cast<ItaniumMangleContext>(getCXXABI().getMangleContext());
84 mc.mangleItaniumThreadLocalWrapper(&vd, wrapperOut);
85 mc.mangleItaniumThreadLocalInit(&vd, initOut);
86 if (globalOp.hasWeakLinkage() || globalOp.hasLinkOnceLinkage() ||
89 guardStream);
90 }
91
92 } else {
94 "setGlobalTlsReferences: non-itanium mangler");
95 return;
96 }
97 globalOp.setDynTlsRefsAttr(cir::ThreadLocalGlobalWrapperInitAttr::get(
98 &getMLIRContext(), wrapperFuncName, initFuncName, guardName));
99}
100
102 cir::GlobalOp addr,
103 bool performInit) {
105
107
108 // TODO(cir): Classic codegen calls emitCXXGuardedInit in the following case:
109 // template<typename T> struct Templ {
110 // static T f;
111 // };
112 // template<typename T> T Templ<T>::f = get_i();
113 // auto func() {
114 // Templ<int> t;
115 // return decltype(t)::f;
116 // }
117 //
118 // However, at the moment it is only suitable for static-local variables, so
119 // we will have to modify it to work for this case as well.
120 emitCXXGlobalVarDeclInit(vd, addr, performInit);
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
virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &)=0
Represents a variable declaration or definition.
Definition Decl.h:924
TLSKind getTLSKind() const
Definition Decl.cpp:2147
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2169
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition Decl.h:1206
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:2737
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
The JSON file list parser is used to communicate input to InstallAPI.
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
Definition Specifiers.h:213
@ CPlusPlus
U cast(CodeGen::Address addr)
Definition Address.h:327
static bool deferredCXXGlobalInit()
static bool cudaSupport()