1e5dd7070Spatrick //===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This contains code to emit Decl nodes as LLVM code.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick
13e5dd7070Spatrick #include "CGBlocks.h"
14e5dd7070Spatrick #include "CGCXXABI.h"
15e5dd7070Spatrick #include "CGCleanup.h"
16e5dd7070Spatrick #include "CGDebugInfo.h"
17e5dd7070Spatrick #include "CGOpenCLRuntime.h"
18e5dd7070Spatrick #include "CGOpenMPRuntime.h"
19e5dd7070Spatrick #include "CodeGenFunction.h"
20e5dd7070Spatrick #include "CodeGenModule.h"
21e5dd7070Spatrick #include "ConstantEmitter.h"
22e5dd7070Spatrick #include "PatternInit.h"
23e5dd7070Spatrick #include "TargetInfo.h"
24e5dd7070Spatrick #include "clang/AST/ASTContext.h"
25e5dd7070Spatrick #include "clang/AST/Attr.h"
26e5dd7070Spatrick #include "clang/AST/CharUnits.h"
27e5dd7070Spatrick #include "clang/AST/Decl.h"
28e5dd7070Spatrick #include "clang/AST/DeclObjC.h"
29e5dd7070Spatrick #include "clang/AST/DeclOpenMP.h"
30e5dd7070Spatrick #include "clang/Basic/CodeGenOptions.h"
31e5dd7070Spatrick #include "clang/Basic/SourceManager.h"
32e5dd7070Spatrick #include "clang/Basic/TargetInfo.h"
33e5dd7070Spatrick #include "clang/CodeGen/CGFunctionInfo.h"
34ec727ea7Spatrick #include "clang/Sema/Sema.h"
35e5dd7070Spatrick #include "llvm/Analysis/ValueTracking.h"
36e5dd7070Spatrick #include "llvm/IR/DataLayout.h"
37e5dd7070Spatrick #include "llvm/IR/GlobalVariable.h"
38e5dd7070Spatrick #include "llvm/IR/Intrinsics.h"
39e5dd7070Spatrick #include "llvm/IR/Type.h"
40*12c85518Srobert #include <optional>
41e5dd7070Spatrick
42e5dd7070Spatrick using namespace clang;
43e5dd7070Spatrick using namespace CodeGen;
44e5dd7070Spatrick
45ec727ea7Spatrick static_assert(clang::Sema::MaximumAlignment <= llvm::Value::MaximumAlignment,
46ec727ea7Spatrick "Clang max alignment greater than what LLVM supports?");
47ec727ea7Spatrick
EmitDecl(const Decl & D)48e5dd7070Spatrick void CodeGenFunction::EmitDecl(const Decl &D) {
49e5dd7070Spatrick switch (D.getKind()) {
50e5dd7070Spatrick case Decl::BuiltinTemplate:
51e5dd7070Spatrick case Decl::TranslationUnit:
52e5dd7070Spatrick case Decl::ExternCContext:
53e5dd7070Spatrick case Decl::Namespace:
54e5dd7070Spatrick case Decl::UnresolvedUsingTypename:
55e5dd7070Spatrick case Decl::ClassTemplateSpecialization:
56e5dd7070Spatrick case Decl::ClassTemplatePartialSpecialization:
57e5dd7070Spatrick case Decl::VarTemplateSpecialization:
58e5dd7070Spatrick case Decl::VarTemplatePartialSpecialization:
59e5dd7070Spatrick case Decl::TemplateTypeParm:
60e5dd7070Spatrick case Decl::UnresolvedUsingValue:
61e5dd7070Spatrick case Decl::NonTypeTemplateParm:
62e5dd7070Spatrick case Decl::CXXDeductionGuide:
63e5dd7070Spatrick case Decl::CXXMethod:
64e5dd7070Spatrick case Decl::CXXConstructor:
65e5dd7070Spatrick case Decl::CXXDestructor:
66e5dd7070Spatrick case Decl::CXXConversion:
67e5dd7070Spatrick case Decl::Field:
68e5dd7070Spatrick case Decl::MSProperty:
69e5dd7070Spatrick case Decl::IndirectField:
70e5dd7070Spatrick case Decl::ObjCIvar:
71e5dd7070Spatrick case Decl::ObjCAtDefsField:
72e5dd7070Spatrick case Decl::ParmVar:
73e5dd7070Spatrick case Decl::ImplicitParam:
74e5dd7070Spatrick case Decl::ClassTemplate:
75e5dd7070Spatrick case Decl::VarTemplate:
76e5dd7070Spatrick case Decl::FunctionTemplate:
77e5dd7070Spatrick case Decl::TypeAliasTemplate:
78e5dd7070Spatrick case Decl::TemplateTemplateParm:
79e5dd7070Spatrick case Decl::ObjCMethod:
80e5dd7070Spatrick case Decl::ObjCCategory:
81e5dd7070Spatrick case Decl::ObjCProtocol:
82e5dd7070Spatrick case Decl::ObjCInterface:
83e5dd7070Spatrick case Decl::ObjCCategoryImpl:
84e5dd7070Spatrick case Decl::ObjCImplementation:
85e5dd7070Spatrick case Decl::ObjCProperty:
86e5dd7070Spatrick case Decl::ObjCCompatibleAlias:
87e5dd7070Spatrick case Decl::PragmaComment:
88e5dd7070Spatrick case Decl::PragmaDetectMismatch:
89e5dd7070Spatrick case Decl::AccessSpec:
90e5dd7070Spatrick case Decl::LinkageSpec:
91e5dd7070Spatrick case Decl::Export:
92e5dd7070Spatrick case Decl::ObjCPropertyImpl:
93e5dd7070Spatrick case Decl::FileScopeAsm:
94*12c85518Srobert case Decl::TopLevelStmt:
95e5dd7070Spatrick case Decl::Friend:
96e5dd7070Spatrick case Decl::FriendTemplate:
97e5dd7070Spatrick case Decl::Block:
98e5dd7070Spatrick case Decl::Captured:
99e5dd7070Spatrick case Decl::ClassScopeFunctionSpecialization:
100e5dd7070Spatrick case Decl::UsingShadow:
101e5dd7070Spatrick case Decl::ConstructorUsingShadow:
102e5dd7070Spatrick case Decl::ObjCTypeParam:
103e5dd7070Spatrick case Decl::Binding:
104a9ac8606Spatrick case Decl::UnresolvedUsingIfExists:
105*12c85518Srobert case Decl::HLSLBuffer:
106e5dd7070Spatrick llvm_unreachable("Declaration should not be in declstmts!");
107e5dd7070Spatrick case Decl::Record: // struct/union/class X;
108e5dd7070Spatrick case Decl::CXXRecord: // struct/union/class X; [C++]
109a9ac8606Spatrick if (CGDebugInfo *DI = getDebugInfo())
110a9ac8606Spatrick if (cast<RecordDecl>(D).getDefinition())
111a9ac8606Spatrick DI->EmitAndRetainType(getContext().getRecordType(cast<RecordDecl>(&D)));
112a9ac8606Spatrick return;
113a9ac8606Spatrick case Decl::Enum: // enum X;
114a9ac8606Spatrick if (CGDebugInfo *DI = getDebugInfo())
115a9ac8606Spatrick if (cast<EnumDecl>(D).getDefinition())
116a9ac8606Spatrick DI->EmitAndRetainType(getContext().getEnumType(cast<EnumDecl>(&D)));
117a9ac8606Spatrick return;
118a9ac8606Spatrick case Decl::Function: // void X();
119a9ac8606Spatrick case Decl::EnumConstant: // enum ? { X = ? }
120e5dd7070Spatrick case Decl::StaticAssert: // static_assert(X, ""); [C++0x]
121e5dd7070Spatrick case Decl::Label: // __label__ x;
122e5dd7070Spatrick case Decl::Import:
123ec727ea7Spatrick case Decl::MSGuid: // __declspec(uuid("..."))
124*12c85518Srobert case Decl::UnnamedGlobalConstant:
125a9ac8606Spatrick case Decl::TemplateParamObject:
126e5dd7070Spatrick case Decl::OMPThreadPrivate:
127e5dd7070Spatrick case Decl::OMPAllocate:
128e5dd7070Spatrick case Decl::OMPCapturedExpr:
129e5dd7070Spatrick case Decl::OMPRequires:
130e5dd7070Spatrick case Decl::Empty:
131e5dd7070Spatrick case Decl::Concept:
132*12c85518Srobert case Decl::ImplicitConceptSpecialization:
133e5dd7070Spatrick case Decl::LifetimeExtendedTemporary:
134e5dd7070Spatrick case Decl::RequiresExprBody:
135e5dd7070Spatrick // None of these decls require codegen support.
136e5dd7070Spatrick return;
137e5dd7070Spatrick
138e5dd7070Spatrick case Decl::NamespaceAlias:
139e5dd7070Spatrick if (CGDebugInfo *DI = getDebugInfo())
140e5dd7070Spatrick DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(D));
141e5dd7070Spatrick return;
142e5dd7070Spatrick case Decl::Using: // using X; [C++]
143e5dd7070Spatrick if (CGDebugInfo *DI = getDebugInfo())
144e5dd7070Spatrick DI->EmitUsingDecl(cast<UsingDecl>(D));
145e5dd7070Spatrick return;
146a9ac8606Spatrick case Decl::UsingEnum: // using enum X; [C++]
147a9ac8606Spatrick if (CGDebugInfo *DI = getDebugInfo())
148a9ac8606Spatrick DI->EmitUsingEnumDecl(cast<UsingEnumDecl>(D));
149a9ac8606Spatrick return;
150e5dd7070Spatrick case Decl::UsingPack:
151e5dd7070Spatrick for (auto *Using : cast<UsingPackDecl>(D).expansions())
152e5dd7070Spatrick EmitDecl(*Using);
153e5dd7070Spatrick return;
154e5dd7070Spatrick case Decl::UsingDirective: // using namespace X; [C++]
155e5dd7070Spatrick if (CGDebugInfo *DI = getDebugInfo())
156e5dd7070Spatrick DI->EmitUsingDirective(cast<UsingDirectiveDecl>(D));
157e5dd7070Spatrick return;
158e5dd7070Spatrick case Decl::Var:
159e5dd7070Spatrick case Decl::Decomposition: {
160e5dd7070Spatrick const VarDecl &VD = cast<VarDecl>(D);
161e5dd7070Spatrick assert(VD.isLocalVarDecl() &&
162e5dd7070Spatrick "Should not see file-scope variables inside a function!");
163e5dd7070Spatrick EmitVarDecl(VD);
164e5dd7070Spatrick if (auto *DD = dyn_cast<DecompositionDecl>(&VD))
165e5dd7070Spatrick for (auto *B : DD->bindings())
166e5dd7070Spatrick if (auto *HD = B->getHoldingVar())
167e5dd7070Spatrick EmitVarDecl(*HD);
168e5dd7070Spatrick return;
169e5dd7070Spatrick }
170e5dd7070Spatrick
171e5dd7070Spatrick case Decl::OMPDeclareReduction:
172e5dd7070Spatrick return CGM.EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(&D), this);
173e5dd7070Spatrick
174e5dd7070Spatrick case Decl::OMPDeclareMapper:
175e5dd7070Spatrick return CGM.EmitOMPDeclareMapper(cast<OMPDeclareMapperDecl>(&D), this);
176e5dd7070Spatrick
177e5dd7070Spatrick case Decl::Typedef: // typedef int X;
178e5dd7070Spatrick case Decl::TypeAlias: { // using X = int; [C++0x]
179a9ac8606Spatrick QualType Ty = cast<TypedefNameDecl>(D).getUnderlyingType();
180a9ac8606Spatrick if (CGDebugInfo *DI = getDebugInfo())
181a9ac8606Spatrick DI->EmitAndRetainType(Ty);
182e5dd7070Spatrick if (Ty->isVariablyModifiedType())
183e5dd7070Spatrick EmitVariablyModifiedType(Ty);
184e5dd7070Spatrick return;
185e5dd7070Spatrick }
186e5dd7070Spatrick }
187e5dd7070Spatrick }
188e5dd7070Spatrick
189e5dd7070Spatrick /// EmitVarDecl - This method handles emission of any variable declaration
190e5dd7070Spatrick /// inside a function, including static vars etc.
EmitVarDecl(const VarDecl & D)191e5dd7070Spatrick void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
192e5dd7070Spatrick if (D.hasExternalStorage())
193e5dd7070Spatrick // Don't emit it now, allow it to be emitted lazily on its first use.
194e5dd7070Spatrick return;
195e5dd7070Spatrick
196e5dd7070Spatrick // Some function-scope variable does not have static storage but still
197e5dd7070Spatrick // needs to be emitted like a static variable, e.g. a function-scope
198e5dd7070Spatrick // variable in constant address space in OpenCL.
199e5dd7070Spatrick if (D.getStorageDuration() != SD_Automatic) {
200e5dd7070Spatrick // Static sampler variables translated to function calls.
201e5dd7070Spatrick if (D.getType()->isSamplerT())
202e5dd7070Spatrick return;
203e5dd7070Spatrick
204e5dd7070Spatrick llvm::GlobalValue::LinkageTypes Linkage =
205e5dd7070Spatrick CGM.getLLVMLinkageVarDefinition(&D, /*IsConstant=*/false);
206e5dd7070Spatrick
207e5dd7070Spatrick // FIXME: We need to force the emission/use of a guard variable for
208e5dd7070Spatrick // some variables even if we can constant-evaluate them because
209e5dd7070Spatrick // we can't guarantee every translation unit will constant-evaluate them.
210e5dd7070Spatrick
211e5dd7070Spatrick return EmitStaticVarDecl(D, Linkage);
212e5dd7070Spatrick }
213e5dd7070Spatrick
214e5dd7070Spatrick if (D.getType().getAddressSpace() == LangAS::opencl_local)
215e5dd7070Spatrick return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*this, D);
216e5dd7070Spatrick
217e5dd7070Spatrick assert(D.hasLocalStorage());
218e5dd7070Spatrick return EmitAutoVarDecl(D);
219e5dd7070Spatrick }
220e5dd7070Spatrick
getStaticDeclName(CodeGenModule & CGM,const VarDecl & D)221e5dd7070Spatrick static std::string getStaticDeclName(CodeGenModule &CGM, const VarDecl &D) {
222e5dd7070Spatrick if (CGM.getLangOpts().CPlusPlus)
223e5dd7070Spatrick return CGM.getMangledName(&D).str();
224e5dd7070Spatrick
225e5dd7070Spatrick // If this isn't C++, we don't need a mangled name, just a pretty one.
226e5dd7070Spatrick assert(!D.isExternallyVisible() && "name shouldn't matter");
227e5dd7070Spatrick std::string ContextName;
228e5dd7070Spatrick const DeclContext *DC = D.getDeclContext();
229e5dd7070Spatrick if (auto *CD = dyn_cast<CapturedDecl>(DC))
230e5dd7070Spatrick DC = cast<DeclContext>(CD->getNonClosureContext());
231e5dd7070Spatrick if (const auto *FD = dyn_cast<FunctionDecl>(DC))
232ec727ea7Spatrick ContextName = std::string(CGM.getMangledName(FD));
233e5dd7070Spatrick else if (const auto *BD = dyn_cast<BlockDecl>(DC))
234ec727ea7Spatrick ContextName = std::string(CGM.getBlockMangledName(GlobalDecl(), BD));
235e5dd7070Spatrick else if (const auto *OMD = dyn_cast<ObjCMethodDecl>(DC))
236e5dd7070Spatrick ContextName = OMD->getSelector().getAsString();
237e5dd7070Spatrick else
238e5dd7070Spatrick llvm_unreachable("Unknown context for static var decl");
239e5dd7070Spatrick
240e5dd7070Spatrick ContextName += "." + D.getNameAsString();
241e5dd7070Spatrick return ContextName;
242e5dd7070Spatrick }
243e5dd7070Spatrick
getOrCreateStaticVarDecl(const VarDecl & D,llvm::GlobalValue::LinkageTypes Linkage)244e5dd7070Spatrick llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl(
245e5dd7070Spatrick const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage) {
246e5dd7070Spatrick // In general, we don't always emit static var decls once before we reference
247e5dd7070Spatrick // them. It is possible to reference them before emitting the function that
248e5dd7070Spatrick // contains them, and it is possible to emit the containing function multiple
249e5dd7070Spatrick // times.
250e5dd7070Spatrick if (llvm::Constant *ExistingGV = StaticLocalDeclMap[&D])
251e5dd7070Spatrick return ExistingGV;
252e5dd7070Spatrick
253e5dd7070Spatrick QualType Ty = D.getType();
254e5dd7070Spatrick assert(Ty->isConstantSizeType() && "VLAs can't be static");
255e5dd7070Spatrick
256e5dd7070Spatrick // Use the label if the variable is renamed with the asm-label extension.
257e5dd7070Spatrick std::string Name;
258e5dd7070Spatrick if (D.hasAttr<AsmLabelAttr>())
259ec727ea7Spatrick Name = std::string(getMangledName(&D));
260e5dd7070Spatrick else
261e5dd7070Spatrick Name = getStaticDeclName(*this, D);
262e5dd7070Spatrick
263e5dd7070Spatrick llvm::Type *LTy = getTypes().ConvertTypeForMem(Ty);
264e5dd7070Spatrick LangAS AS = GetGlobalVarAddressSpace(&D);
265e5dd7070Spatrick unsigned TargetAS = getContext().getTargetAddressSpace(AS);
266e5dd7070Spatrick
267e5dd7070Spatrick // OpenCL variables in local address space and CUDA shared
268e5dd7070Spatrick // variables cannot have an initializer.
269e5dd7070Spatrick llvm::Constant *Init = nullptr;
270e5dd7070Spatrick if (Ty.getAddressSpace() == LangAS::opencl_local ||
271ec727ea7Spatrick D.hasAttr<CUDASharedAttr>() || D.hasAttr<LoaderUninitializedAttr>())
272e5dd7070Spatrick Init = llvm::UndefValue::get(LTy);
273e5dd7070Spatrick else
274e5dd7070Spatrick Init = EmitNullConstant(Ty);
275e5dd7070Spatrick
276e5dd7070Spatrick llvm::GlobalVariable *GV = new llvm::GlobalVariable(
277e5dd7070Spatrick getModule(), LTy, Ty.isConstant(getContext()), Linkage, Init, Name,
278e5dd7070Spatrick nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
279e5dd7070Spatrick GV->setAlignment(getContext().getDeclAlign(&D).getAsAlign());
280e5dd7070Spatrick
281e5dd7070Spatrick if (supportsCOMDAT() && GV->isWeakForLinker())
282e5dd7070Spatrick GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
283e5dd7070Spatrick
284e5dd7070Spatrick if (D.getTLSKind())
285e5dd7070Spatrick setTLSMode(GV, D);
286e5dd7070Spatrick
287e5dd7070Spatrick setGVProperties(GV, &D);
288e5dd7070Spatrick
289e5dd7070Spatrick // Make sure the result is of the correct type.
290e5dd7070Spatrick LangAS ExpectedAS = Ty.getAddressSpace();
291e5dd7070Spatrick llvm::Constant *Addr = GV;
292e5dd7070Spatrick if (AS != ExpectedAS) {
293e5dd7070Spatrick Addr = getTargetCodeGenInfo().performAddrSpaceCast(
294e5dd7070Spatrick *this, GV, AS, ExpectedAS,
295e5dd7070Spatrick LTy->getPointerTo(getContext().getTargetAddressSpace(ExpectedAS)));
296e5dd7070Spatrick }
297e5dd7070Spatrick
298e5dd7070Spatrick setStaticLocalDeclAddress(&D, Addr);
299e5dd7070Spatrick
300e5dd7070Spatrick // Ensure that the static local gets initialized by making sure the parent
301e5dd7070Spatrick // function gets emitted eventually.
302e5dd7070Spatrick const Decl *DC = cast<Decl>(D.getDeclContext());
303e5dd7070Spatrick
304e5dd7070Spatrick // We can't name blocks or captured statements directly, so try to emit their
305e5dd7070Spatrick // parents.
306e5dd7070Spatrick if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC)) {
307e5dd7070Spatrick DC = DC->getNonClosureContext();
308e5dd7070Spatrick // FIXME: Ensure that global blocks get emitted.
309e5dd7070Spatrick if (!DC)
310e5dd7070Spatrick return Addr;
311e5dd7070Spatrick }
312e5dd7070Spatrick
313e5dd7070Spatrick GlobalDecl GD;
314e5dd7070Spatrick if (const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
315e5dd7070Spatrick GD = GlobalDecl(CD, Ctor_Base);
316e5dd7070Spatrick else if (const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
317e5dd7070Spatrick GD = GlobalDecl(DD, Dtor_Base);
318e5dd7070Spatrick else if (const auto *FD = dyn_cast<FunctionDecl>(DC))
319e5dd7070Spatrick GD = GlobalDecl(FD);
320e5dd7070Spatrick else {
321e5dd7070Spatrick // Don't do anything for Obj-C method decls or global closures. We should
322e5dd7070Spatrick // never defer them.
323e5dd7070Spatrick assert(isa<ObjCMethodDecl>(DC) && "unexpected parent code decl");
324e5dd7070Spatrick }
325e5dd7070Spatrick if (GD.getDecl()) {
326e5dd7070Spatrick // Disable emission of the parent function for the OpenMP device codegen.
327e5dd7070Spatrick CGOpenMPRuntime::DisableAutoDeclareTargetRAII NoDeclTarget(*this);
328e5dd7070Spatrick (void)GetAddrOfGlobal(GD);
329e5dd7070Spatrick }
330e5dd7070Spatrick
331e5dd7070Spatrick return Addr;
332e5dd7070Spatrick }
333e5dd7070Spatrick
334e5dd7070Spatrick /// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the
335e5dd7070Spatrick /// global variable that has already been created for it. If the initializer
336e5dd7070Spatrick /// has a different type than GV does, this may free GV and return a different
337e5dd7070Spatrick /// one. Otherwise it just returns GV.
338e5dd7070Spatrick llvm::GlobalVariable *
AddInitializerToStaticVarDecl(const VarDecl & D,llvm::GlobalVariable * GV)339e5dd7070Spatrick CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
340e5dd7070Spatrick llvm::GlobalVariable *GV) {
341e5dd7070Spatrick ConstantEmitter emitter(*this);
342e5dd7070Spatrick llvm::Constant *Init = emitter.tryEmitForInitializer(D);
343e5dd7070Spatrick
344e5dd7070Spatrick // If constant emission failed, then this should be a C++ static
345e5dd7070Spatrick // initializer.
346e5dd7070Spatrick if (!Init) {
347e5dd7070Spatrick if (!getLangOpts().CPlusPlus)
348e5dd7070Spatrick CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");
349*12c85518Srobert else if (D.hasFlexibleArrayInit(getContext()))
350*12c85518Srobert CGM.ErrorUnsupported(D.getInit(), "flexible array initializer");
351e5dd7070Spatrick else if (HaveInsertPoint()) {
352e5dd7070Spatrick // Since we have a static initializer, this global variable can't
353e5dd7070Spatrick // be constant.
354e5dd7070Spatrick GV->setConstant(false);
355e5dd7070Spatrick
356e5dd7070Spatrick EmitCXXGuardedInit(D, GV, /*PerformInit*/true);
357e5dd7070Spatrick }
358e5dd7070Spatrick return GV;
359e5dd7070Spatrick }
360e5dd7070Spatrick
361*12c85518Srobert #ifndef NDEBUG
362*12c85518Srobert CharUnits VarSize = CGM.getContext().getTypeSizeInChars(D.getType()) +
363*12c85518Srobert D.getFlexibleArrayInitChars(getContext());
364*12c85518Srobert CharUnits CstSize = CharUnits::fromQuantity(
365*12c85518Srobert CGM.getDataLayout().getTypeAllocSize(Init->getType()));
366*12c85518Srobert assert(VarSize == CstSize && "Emitted constant has unexpected size");
367*12c85518Srobert #endif
368*12c85518Srobert
369e5dd7070Spatrick // The initializer may differ in type from the global. Rewrite
370e5dd7070Spatrick // the global to match the initializer. (We have to do this
371e5dd7070Spatrick // because some types, like unions, can't be completely represented
372e5dd7070Spatrick // in the LLVM type system.)
373ec727ea7Spatrick if (GV->getValueType() != Init->getType()) {
374e5dd7070Spatrick llvm::GlobalVariable *OldGV = GV;
375e5dd7070Spatrick
376a9ac8606Spatrick GV = new llvm::GlobalVariable(
377a9ac8606Spatrick CGM.getModule(), Init->getType(), OldGV->isConstant(),
378e5dd7070Spatrick OldGV->getLinkage(), Init, "",
379a9ac8606Spatrick /*InsertBefore*/ OldGV, OldGV->getThreadLocalMode(),
380a9ac8606Spatrick OldGV->getType()->getPointerAddressSpace());
381e5dd7070Spatrick GV->setVisibility(OldGV->getVisibility());
382e5dd7070Spatrick GV->setDSOLocal(OldGV->isDSOLocal());
383e5dd7070Spatrick GV->setComdat(OldGV->getComdat());
384e5dd7070Spatrick
385e5dd7070Spatrick // Steal the name of the old global
386e5dd7070Spatrick GV->takeName(OldGV);
387e5dd7070Spatrick
388e5dd7070Spatrick // Replace all uses of the old global with the new global
389e5dd7070Spatrick llvm::Constant *NewPtrForOldDecl =
390e5dd7070Spatrick llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
391e5dd7070Spatrick OldGV->replaceAllUsesWith(NewPtrForOldDecl);
392e5dd7070Spatrick
393e5dd7070Spatrick // Erase the old global, since it is no longer used.
394e5dd7070Spatrick OldGV->eraseFromParent();
395e5dd7070Spatrick }
396e5dd7070Spatrick
397e5dd7070Spatrick GV->setConstant(CGM.isTypeConstant(D.getType(), true));
398e5dd7070Spatrick GV->setInitializer(Init);
399e5dd7070Spatrick
400e5dd7070Spatrick emitter.finalize(GV);
401e5dd7070Spatrick
402e5dd7070Spatrick if (D.needsDestruction(getContext()) == QualType::DK_cxx_destructor &&
403e5dd7070Spatrick HaveInsertPoint()) {
404e5dd7070Spatrick // We have a constant initializer, but a nontrivial destructor. We still
405e5dd7070Spatrick // need to perform a guarded "initialization" in order to register the
406e5dd7070Spatrick // destructor.
407e5dd7070Spatrick EmitCXXGuardedInit(D, GV, /*PerformInit*/false);
408e5dd7070Spatrick }
409e5dd7070Spatrick
410e5dd7070Spatrick return GV;
411e5dd7070Spatrick }
412e5dd7070Spatrick
EmitStaticVarDecl(const VarDecl & D,llvm::GlobalValue::LinkageTypes Linkage)413e5dd7070Spatrick void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
414e5dd7070Spatrick llvm::GlobalValue::LinkageTypes Linkage) {
415e5dd7070Spatrick // Check to see if we already have a global variable for this
416e5dd7070Spatrick // declaration. This can happen when double-emitting function
417e5dd7070Spatrick // bodies, e.g. with complete and base constructors.
418e5dd7070Spatrick llvm::Constant *addr = CGM.getOrCreateStaticVarDecl(D, Linkage);
419e5dd7070Spatrick CharUnits alignment = getContext().getDeclAlign(&D);
420e5dd7070Spatrick
421e5dd7070Spatrick // Store into LocalDeclMap before generating initializer to handle
422e5dd7070Spatrick // circular references.
423*12c85518Srobert llvm::Type *elemTy = ConvertTypeForMem(D.getType());
424*12c85518Srobert setAddrOfLocalVar(&D, Address(addr, elemTy, alignment));
425e5dd7070Spatrick
426e5dd7070Spatrick // We can't have a VLA here, but we can have a pointer to a VLA,
427e5dd7070Spatrick // even though that doesn't really make any sense.
428e5dd7070Spatrick // Make sure to evaluate VLA bounds now so that we have them for later.
429e5dd7070Spatrick if (D.getType()->isVariablyModifiedType())
430e5dd7070Spatrick EmitVariablyModifiedType(D.getType());
431e5dd7070Spatrick
432e5dd7070Spatrick // Save the type in case adding the initializer forces a type change.
433e5dd7070Spatrick llvm::Type *expectedType = addr->getType();
434e5dd7070Spatrick
435e5dd7070Spatrick llvm::GlobalVariable *var =
436e5dd7070Spatrick cast<llvm::GlobalVariable>(addr->stripPointerCasts());
437e5dd7070Spatrick
438e5dd7070Spatrick // CUDA's local and local static __shared__ variables should not
439e5dd7070Spatrick // have any non-empty initializers. This is ensured by Sema.
440e5dd7070Spatrick // Whatever initializer such variable may have when it gets here is
441e5dd7070Spatrick // a no-op and should not be emitted.
442e5dd7070Spatrick bool isCudaSharedVar = getLangOpts().CUDA && getLangOpts().CUDAIsDevice &&
443e5dd7070Spatrick D.hasAttr<CUDASharedAttr>();
444e5dd7070Spatrick // If this value has an initializer, emit it.
445e5dd7070Spatrick if (D.getInit() && !isCudaSharedVar)
446e5dd7070Spatrick var = AddInitializerToStaticVarDecl(D, var);
447e5dd7070Spatrick
448e5dd7070Spatrick var->setAlignment(alignment.getAsAlign());
449e5dd7070Spatrick
450e5dd7070Spatrick if (D.hasAttr<AnnotateAttr>())
451e5dd7070Spatrick CGM.AddGlobalAnnotations(&D, var);
452e5dd7070Spatrick
453e5dd7070Spatrick if (auto *SA = D.getAttr<PragmaClangBSSSectionAttr>())
454e5dd7070Spatrick var->addAttribute("bss-section", SA->getName());
455e5dd7070Spatrick if (auto *SA = D.getAttr<PragmaClangDataSectionAttr>())
456e5dd7070Spatrick var->addAttribute("data-section", SA->getName());
457e5dd7070Spatrick if (auto *SA = D.getAttr<PragmaClangRodataSectionAttr>())
458e5dd7070Spatrick var->addAttribute("rodata-section", SA->getName());
459e5dd7070Spatrick if (auto *SA = D.getAttr<PragmaClangRelroSectionAttr>())
460e5dd7070Spatrick var->addAttribute("relro-section", SA->getName());
461e5dd7070Spatrick
462e5dd7070Spatrick if (const SectionAttr *SA = D.getAttr<SectionAttr>())
463e5dd7070Spatrick var->setSection(SA->getName());
464e5dd7070Spatrick
465a9ac8606Spatrick if (D.hasAttr<RetainAttr>())
466e5dd7070Spatrick CGM.addUsedGlobal(var);
467a9ac8606Spatrick else if (D.hasAttr<UsedAttr>())
468a9ac8606Spatrick CGM.addUsedOrCompilerUsedGlobal(var);
469e5dd7070Spatrick
470e5dd7070Spatrick // We may have to cast the constant because of the initializer
471e5dd7070Spatrick // mismatch above.
472e5dd7070Spatrick //
473e5dd7070Spatrick // FIXME: It is really dangerous to store this in the map; if anyone
474e5dd7070Spatrick // RAUW's the GV uses of this constant will be invalid.
475e5dd7070Spatrick llvm::Constant *castedAddr =
476e5dd7070Spatrick llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(var, expectedType);
477*12c85518Srobert LocalDeclMap.find(&D)->second = Address(castedAddr, elemTy, alignment);
478e5dd7070Spatrick CGM.setStaticLocalDeclAddress(&D, castedAddr);
479e5dd7070Spatrick
480*12c85518Srobert CGM.getSanitizerMetadata()->reportGlobal(var, D);
481e5dd7070Spatrick
482e5dd7070Spatrick // Emit global variable debug descriptor for static vars.
483e5dd7070Spatrick CGDebugInfo *DI = getDebugInfo();
484e5dd7070Spatrick if (DI && CGM.getCodeGenOpts().hasReducedDebugInfo()) {
485e5dd7070Spatrick DI->setLocation(D.getLocation());
486e5dd7070Spatrick DI->EmitGlobalVariable(var, &D);
487e5dd7070Spatrick }
488e5dd7070Spatrick }
489e5dd7070Spatrick
490e5dd7070Spatrick namespace {
491e5dd7070Spatrick struct DestroyObject final : EHScopeStack::Cleanup {
DestroyObject__anon67b25ad70111::DestroyObject492e5dd7070Spatrick DestroyObject(Address addr, QualType type,
493e5dd7070Spatrick CodeGenFunction::Destroyer *destroyer,
494e5dd7070Spatrick bool useEHCleanupForArray)
495e5dd7070Spatrick : addr(addr), type(type), destroyer(destroyer),
496e5dd7070Spatrick useEHCleanupForArray(useEHCleanupForArray) {}
497e5dd7070Spatrick
498e5dd7070Spatrick Address addr;
499e5dd7070Spatrick QualType type;
500e5dd7070Spatrick CodeGenFunction::Destroyer *destroyer;
501e5dd7070Spatrick bool useEHCleanupForArray;
502e5dd7070Spatrick
Emit__anon67b25ad70111::DestroyObject503e5dd7070Spatrick void Emit(CodeGenFunction &CGF, Flags flags) override {
504e5dd7070Spatrick // Don't use an EH cleanup recursively from an EH cleanup.
505e5dd7070Spatrick bool useEHCleanupForArray =
506e5dd7070Spatrick flags.isForNormalCleanup() && this->useEHCleanupForArray;
507e5dd7070Spatrick
508e5dd7070Spatrick CGF.emitDestroy(addr, type, destroyer, useEHCleanupForArray);
509e5dd7070Spatrick }
510e5dd7070Spatrick };
511e5dd7070Spatrick
512e5dd7070Spatrick template <class Derived>
513e5dd7070Spatrick struct DestroyNRVOVariable : EHScopeStack::Cleanup {
DestroyNRVOVariable__anon67b25ad70111::DestroyNRVOVariable514e5dd7070Spatrick DestroyNRVOVariable(Address addr, QualType type, llvm::Value *NRVOFlag)
515e5dd7070Spatrick : NRVOFlag(NRVOFlag), Loc(addr), Ty(type) {}
516e5dd7070Spatrick
517e5dd7070Spatrick llvm::Value *NRVOFlag;
518e5dd7070Spatrick Address Loc;
519e5dd7070Spatrick QualType Ty;
520e5dd7070Spatrick
Emit__anon67b25ad70111::DestroyNRVOVariable521e5dd7070Spatrick void Emit(CodeGenFunction &CGF, Flags flags) override {
522e5dd7070Spatrick // Along the exceptions path we always execute the dtor.
523e5dd7070Spatrick bool NRVO = flags.isForNormalCleanup() && NRVOFlag;
524e5dd7070Spatrick
525e5dd7070Spatrick llvm::BasicBlock *SkipDtorBB = nullptr;
526e5dd7070Spatrick if (NRVO) {
527e5dd7070Spatrick // If we exited via NRVO, we skip the destructor call.
528e5dd7070Spatrick llvm::BasicBlock *RunDtorBB = CGF.createBasicBlock("nrvo.unused");
529e5dd7070Spatrick SkipDtorBB = CGF.createBasicBlock("nrvo.skipdtor");
530e5dd7070Spatrick llvm::Value *DidNRVO =
531e5dd7070Spatrick CGF.Builder.CreateFlagLoad(NRVOFlag, "nrvo.val");
532e5dd7070Spatrick CGF.Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB);
533e5dd7070Spatrick CGF.EmitBlock(RunDtorBB);
534e5dd7070Spatrick }
535e5dd7070Spatrick
536e5dd7070Spatrick static_cast<Derived *>(this)->emitDestructorCall(CGF);
537e5dd7070Spatrick
538e5dd7070Spatrick if (NRVO) CGF.EmitBlock(SkipDtorBB);
539e5dd7070Spatrick }
540e5dd7070Spatrick
541e5dd7070Spatrick virtual ~DestroyNRVOVariable() = default;
542e5dd7070Spatrick };
543e5dd7070Spatrick
544e5dd7070Spatrick struct DestroyNRVOVariableCXX final
545e5dd7070Spatrick : DestroyNRVOVariable<DestroyNRVOVariableCXX> {
DestroyNRVOVariableCXX__anon67b25ad70111::DestroyNRVOVariableCXX546e5dd7070Spatrick DestroyNRVOVariableCXX(Address addr, QualType type,
547e5dd7070Spatrick const CXXDestructorDecl *Dtor, llvm::Value *NRVOFlag)
548e5dd7070Spatrick : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr, type, NRVOFlag),
549e5dd7070Spatrick Dtor(Dtor) {}
550e5dd7070Spatrick
551e5dd7070Spatrick const CXXDestructorDecl *Dtor;
552e5dd7070Spatrick
emitDestructorCall__anon67b25ad70111::DestroyNRVOVariableCXX553e5dd7070Spatrick void emitDestructorCall(CodeGenFunction &CGF) {
554e5dd7070Spatrick CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
555e5dd7070Spatrick /*ForVirtualBase=*/false,
556e5dd7070Spatrick /*Delegating=*/false, Loc, Ty);
557e5dd7070Spatrick }
558e5dd7070Spatrick };
559e5dd7070Spatrick
560e5dd7070Spatrick struct DestroyNRVOVariableC final
561e5dd7070Spatrick : DestroyNRVOVariable<DestroyNRVOVariableC> {
DestroyNRVOVariableC__anon67b25ad70111::DestroyNRVOVariableC562e5dd7070Spatrick DestroyNRVOVariableC(Address addr, llvm::Value *NRVOFlag, QualType Ty)
563e5dd7070Spatrick : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, Ty, NRVOFlag) {}
564e5dd7070Spatrick
emitDestructorCall__anon67b25ad70111::DestroyNRVOVariableC565e5dd7070Spatrick void emitDestructorCall(CodeGenFunction &CGF) {
566e5dd7070Spatrick CGF.destroyNonTrivialCStruct(CGF, Loc, Ty);
567e5dd7070Spatrick }
568e5dd7070Spatrick };
569e5dd7070Spatrick
570e5dd7070Spatrick struct CallStackRestore final : EHScopeStack::Cleanup {
571e5dd7070Spatrick Address Stack;
CallStackRestore__anon67b25ad70111::CallStackRestore572e5dd7070Spatrick CallStackRestore(Address Stack) : Stack(Stack) {}
isRedundantBeforeReturn__anon67b25ad70111::CallStackRestore573a9ac8606Spatrick bool isRedundantBeforeReturn() override { return true; }
Emit__anon67b25ad70111::CallStackRestore574e5dd7070Spatrick void Emit(CodeGenFunction &CGF, Flags flags) override {
575e5dd7070Spatrick llvm::Value *V = CGF.Builder.CreateLoad(Stack);
576e5dd7070Spatrick llvm::Function *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
577e5dd7070Spatrick CGF.Builder.CreateCall(F, V);
578e5dd7070Spatrick }
579e5dd7070Spatrick };
580e5dd7070Spatrick
581e5dd7070Spatrick struct ExtendGCLifetime final : EHScopeStack::Cleanup {
582e5dd7070Spatrick const VarDecl &Var;
ExtendGCLifetime__anon67b25ad70111::ExtendGCLifetime583e5dd7070Spatrick ExtendGCLifetime(const VarDecl *var) : Var(*var) {}
584e5dd7070Spatrick
Emit__anon67b25ad70111::ExtendGCLifetime585e5dd7070Spatrick void Emit(CodeGenFunction &CGF, Flags flags) override {
586e5dd7070Spatrick // Compute the address of the local variable, in case it's a
587e5dd7070Spatrick // byref or something.
588e5dd7070Spatrick DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false,
589e5dd7070Spatrick Var.getType(), VK_LValue, SourceLocation());
590e5dd7070Spatrick llvm::Value *value = CGF.EmitLoadOfScalar(CGF.EmitDeclRefLValue(&DRE),
591e5dd7070Spatrick SourceLocation());
592e5dd7070Spatrick CGF.EmitExtendGCLifetime(value);
593e5dd7070Spatrick }
594e5dd7070Spatrick };
595e5dd7070Spatrick
596e5dd7070Spatrick struct CallCleanupFunction final : EHScopeStack::Cleanup {
597e5dd7070Spatrick llvm::Constant *CleanupFn;
598e5dd7070Spatrick const CGFunctionInfo &FnInfo;
599e5dd7070Spatrick const VarDecl &Var;
600e5dd7070Spatrick
CallCleanupFunction__anon67b25ad70111::CallCleanupFunction601e5dd7070Spatrick CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info,
602e5dd7070Spatrick const VarDecl *Var)
603e5dd7070Spatrick : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}
604e5dd7070Spatrick
Emit__anon67b25ad70111::CallCleanupFunction605e5dd7070Spatrick void Emit(CodeGenFunction &CGF, Flags flags) override {
606e5dd7070Spatrick DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(&Var), false,
607e5dd7070Spatrick Var.getType(), VK_LValue, SourceLocation());
608e5dd7070Spatrick // Compute the address of the local variable, in case it's a byref
609e5dd7070Spatrick // or something.
610e5dd7070Spatrick llvm::Value *Addr = CGF.EmitDeclRefLValue(&DRE).getPointer(CGF);
611e5dd7070Spatrick
612e5dd7070Spatrick // In some cases, the type of the function argument will be different from
613e5dd7070Spatrick // the type of the pointer. An example of this is
614e5dd7070Spatrick // void f(void* arg);
615e5dd7070Spatrick // __attribute__((cleanup(f))) void *g;
616e5dd7070Spatrick //
617e5dd7070Spatrick // To fix this we insert a bitcast here.
618e5dd7070Spatrick QualType ArgTy = FnInfo.arg_begin()->type;
619e5dd7070Spatrick llvm::Value *Arg =
620e5dd7070Spatrick CGF.Builder.CreateBitCast(Addr, CGF.ConvertType(ArgTy));
621e5dd7070Spatrick
622e5dd7070Spatrick CallArgList Args;
623e5dd7070Spatrick Args.add(RValue::get(Arg),
624e5dd7070Spatrick CGF.getContext().getPointerType(Var.getType()));
625e5dd7070Spatrick auto Callee = CGCallee::forDirect(CleanupFn);
626e5dd7070Spatrick CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);
627e5dd7070Spatrick }
628e5dd7070Spatrick };
629e5dd7070Spatrick } // end anonymous namespace
630e5dd7070Spatrick
631e5dd7070Spatrick /// EmitAutoVarWithLifetime - Does the setup required for an automatic
632e5dd7070Spatrick /// variable with lifetime.
EmitAutoVarWithLifetime(CodeGenFunction & CGF,const VarDecl & var,Address addr,Qualifiers::ObjCLifetime lifetime)633e5dd7070Spatrick static void EmitAutoVarWithLifetime(CodeGenFunction &CGF, const VarDecl &var,
634e5dd7070Spatrick Address addr,
635e5dd7070Spatrick Qualifiers::ObjCLifetime lifetime) {
636e5dd7070Spatrick switch (lifetime) {
637e5dd7070Spatrick case Qualifiers::OCL_None:
638e5dd7070Spatrick llvm_unreachable("present but none");
639e5dd7070Spatrick
640e5dd7070Spatrick case Qualifiers::OCL_ExplicitNone:
641e5dd7070Spatrick // nothing to do
642e5dd7070Spatrick break;
643e5dd7070Spatrick
644e5dd7070Spatrick case Qualifiers::OCL_Strong: {
645e5dd7070Spatrick CodeGenFunction::Destroyer *destroyer =
646e5dd7070Spatrick (var.hasAttr<ObjCPreciseLifetimeAttr>()
647e5dd7070Spatrick ? CodeGenFunction::destroyARCStrongPrecise
648e5dd7070Spatrick : CodeGenFunction::destroyARCStrongImprecise);
649e5dd7070Spatrick
650e5dd7070Spatrick CleanupKind cleanupKind = CGF.getARCCleanupKind();
651e5dd7070Spatrick CGF.pushDestroy(cleanupKind, addr, var.getType(), destroyer,
652e5dd7070Spatrick cleanupKind & EHCleanup);
653e5dd7070Spatrick break;
654e5dd7070Spatrick }
655e5dd7070Spatrick case Qualifiers::OCL_Autoreleasing:
656e5dd7070Spatrick // nothing to do
657e5dd7070Spatrick break;
658e5dd7070Spatrick
659e5dd7070Spatrick case Qualifiers::OCL_Weak:
660e5dd7070Spatrick // __weak objects always get EH cleanups; otherwise, exceptions
661e5dd7070Spatrick // could cause really nasty crashes instead of mere leaks.
662e5dd7070Spatrick CGF.pushDestroy(NormalAndEHCleanup, addr, var.getType(),
663e5dd7070Spatrick CodeGenFunction::destroyARCWeak,
664e5dd7070Spatrick /*useEHCleanup*/ true);
665e5dd7070Spatrick break;
666e5dd7070Spatrick }
667e5dd7070Spatrick }
668e5dd7070Spatrick
isAccessedBy(const VarDecl & var,const Stmt * s)669e5dd7070Spatrick static bool isAccessedBy(const VarDecl &var, const Stmt *s) {
670e5dd7070Spatrick if (const Expr *e = dyn_cast<Expr>(s)) {
671e5dd7070Spatrick // Skip the most common kinds of expressions that make
672e5dd7070Spatrick // hierarchy-walking expensive.
673e5dd7070Spatrick s = e = e->IgnoreParenCasts();
674e5dd7070Spatrick
675e5dd7070Spatrick if (const DeclRefExpr *ref = dyn_cast<DeclRefExpr>(e))
676e5dd7070Spatrick return (ref->getDecl() == &var);
677e5dd7070Spatrick if (const BlockExpr *be = dyn_cast<BlockExpr>(e)) {
678e5dd7070Spatrick const BlockDecl *block = be->getBlockDecl();
679e5dd7070Spatrick for (const auto &I : block->captures()) {
680e5dd7070Spatrick if (I.getVariable() == &var)
681e5dd7070Spatrick return true;
682e5dd7070Spatrick }
683e5dd7070Spatrick }
684e5dd7070Spatrick }
685e5dd7070Spatrick
686e5dd7070Spatrick for (const Stmt *SubStmt : s->children())
687e5dd7070Spatrick // SubStmt might be null; as in missing decl or conditional of an if-stmt.
688e5dd7070Spatrick if (SubStmt && isAccessedBy(var, SubStmt))
689e5dd7070Spatrick return true;
690e5dd7070Spatrick
691e5dd7070Spatrick return false;
692e5dd7070Spatrick }
693e5dd7070Spatrick
isAccessedBy(const ValueDecl * decl,const Expr * e)694e5dd7070Spatrick static bool isAccessedBy(const ValueDecl *decl, const Expr *e) {
695e5dd7070Spatrick if (!decl) return false;
696e5dd7070Spatrick if (!isa<VarDecl>(decl)) return false;
697e5dd7070Spatrick const VarDecl *var = cast<VarDecl>(decl);
698e5dd7070Spatrick return isAccessedBy(*var, e);
699e5dd7070Spatrick }
700e5dd7070Spatrick
tryEmitARCCopyWeakInit(CodeGenFunction & CGF,const LValue & destLV,const Expr * init)701e5dd7070Spatrick static bool tryEmitARCCopyWeakInit(CodeGenFunction &CGF,
702e5dd7070Spatrick const LValue &destLV, const Expr *init) {
703e5dd7070Spatrick bool needsCast = false;
704e5dd7070Spatrick
705e5dd7070Spatrick while (auto castExpr = dyn_cast<CastExpr>(init->IgnoreParens())) {
706e5dd7070Spatrick switch (castExpr->getCastKind()) {
707e5dd7070Spatrick // Look through casts that don't require representation changes.
708e5dd7070Spatrick case CK_NoOp:
709e5dd7070Spatrick case CK_BitCast:
710e5dd7070Spatrick case CK_BlockPointerToObjCPointerCast:
711e5dd7070Spatrick needsCast = true;
712e5dd7070Spatrick break;
713e5dd7070Spatrick
714e5dd7070Spatrick // If we find an l-value to r-value cast from a __weak variable,
715e5dd7070Spatrick // emit this operation as a copy or move.
716e5dd7070Spatrick case CK_LValueToRValue: {
717e5dd7070Spatrick const Expr *srcExpr = castExpr->getSubExpr();
718e5dd7070Spatrick if (srcExpr->getType().getObjCLifetime() != Qualifiers::OCL_Weak)
719e5dd7070Spatrick return false;
720e5dd7070Spatrick
721e5dd7070Spatrick // Emit the source l-value.
722e5dd7070Spatrick LValue srcLV = CGF.EmitLValue(srcExpr);
723e5dd7070Spatrick
724e5dd7070Spatrick // Handle a formal type change to avoid asserting.
725e5dd7070Spatrick auto srcAddr = srcLV.getAddress(CGF);
726e5dd7070Spatrick if (needsCast) {
727e5dd7070Spatrick srcAddr = CGF.Builder.CreateElementBitCast(
728e5dd7070Spatrick srcAddr, destLV.getAddress(CGF).getElementType());
729e5dd7070Spatrick }
730e5dd7070Spatrick
731e5dd7070Spatrick // If it was an l-value, use objc_copyWeak.
732a9ac8606Spatrick if (srcExpr->isLValue()) {
733e5dd7070Spatrick CGF.EmitARCCopyWeak(destLV.getAddress(CGF), srcAddr);
734e5dd7070Spatrick } else {
735a9ac8606Spatrick assert(srcExpr->isXValue());
736e5dd7070Spatrick CGF.EmitARCMoveWeak(destLV.getAddress(CGF), srcAddr);
737e5dd7070Spatrick }
738e5dd7070Spatrick return true;
739e5dd7070Spatrick }
740e5dd7070Spatrick
741e5dd7070Spatrick // Stop at anything else.
742e5dd7070Spatrick default:
743e5dd7070Spatrick return false;
744e5dd7070Spatrick }
745e5dd7070Spatrick
746e5dd7070Spatrick init = castExpr->getSubExpr();
747e5dd7070Spatrick }
748e5dd7070Spatrick return false;
749e5dd7070Spatrick }
750e5dd7070Spatrick
drillIntoBlockVariable(CodeGenFunction & CGF,LValue & lvalue,const VarDecl * var)751e5dd7070Spatrick static void drillIntoBlockVariable(CodeGenFunction &CGF,
752e5dd7070Spatrick LValue &lvalue,
753e5dd7070Spatrick const VarDecl *var) {
754e5dd7070Spatrick lvalue.setAddress(CGF.emitBlockByrefAddress(lvalue.getAddress(CGF), var));
755e5dd7070Spatrick }
756e5dd7070Spatrick
EmitNullabilityCheck(LValue LHS,llvm::Value * RHS,SourceLocation Loc)757e5dd7070Spatrick void CodeGenFunction::EmitNullabilityCheck(LValue LHS, llvm::Value *RHS,
758e5dd7070Spatrick SourceLocation Loc) {
759e5dd7070Spatrick if (!SanOpts.has(SanitizerKind::NullabilityAssign))
760e5dd7070Spatrick return;
761e5dd7070Spatrick
762*12c85518Srobert auto Nullability = LHS.getType()->getNullability();
763e5dd7070Spatrick if (!Nullability || *Nullability != NullabilityKind::NonNull)
764e5dd7070Spatrick return;
765e5dd7070Spatrick
766e5dd7070Spatrick // Check if the right hand side of the assignment is nonnull, if the left
767e5dd7070Spatrick // hand side must be nonnull.
768e5dd7070Spatrick SanitizerScope SanScope(this);
769e5dd7070Spatrick llvm::Value *IsNotNull = Builder.CreateIsNotNull(RHS);
770e5dd7070Spatrick llvm::Constant *StaticData[] = {
771e5dd7070Spatrick EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(LHS.getType()),
772e5dd7070Spatrick llvm::ConstantInt::get(Int8Ty, 0), // The LogAlignment info is unused.
773e5dd7070Spatrick llvm::ConstantInt::get(Int8Ty, TCK_NonnullAssign)};
774e5dd7070Spatrick EmitCheck({{IsNotNull, SanitizerKind::NullabilityAssign}},
775e5dd7070Spatrick SanitizerHandler::TypeMismatch, StaticData, RHS);
776e5dd7070Spatrick }
777e5dd7070Spatrick
EmitScalarInit(const Expr * init,const ValueDecl * D,LValue lvalue,bool capturedByInit)778e5dd7070Spatrick void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
779e5dd7070Spatrick LValue lvalue, bool capturedByInit) {
780e5dd7070Spatrick Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime();
781e5dd7070Spatrick if (!lifetime) {
782e5dd7070Spatrick llvm::Value *value = EmitScalarExpr(init);
783e5dd7070Spatrick if (capturedByInit)
784e5dd7070Spatrick drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
785e5dd7070Spatrick EmitNullabilityCheck(lvalue, value, init->getExprLoc());
786e5dd7070Spatrick EmitStoreThroughLValue(RValue::get(value), lvalue, true);
787e5dd7070Spatrick return;
788e5dd7070Spatrick }
789e5dd7070Spatrick
790e5dd7070Spatrick if (const CXXDefaultInitExpr *DIE = dyn_cast<CXXDefaultInitExpr>(init))
791e5dd7070Spatrick init = DIE->getExpr();
792e5dd7070Spatrick
793e5dd7070Spatrick // If we're emitting a value with lifetime, we have to do the
794e5dd7070Spatrick // initialization *before* we leave the cleanup scopes.
795a9ac8606Spatrick if (auto *EWC = dyn_cast<ExprWithCleanups>(init)) {
796e5dd7070Spatrick CodeGenFunction::RunCleanupsScope Scope(*this);
797a9ac8606Spatrick return EmitScalarInit(EWC->getSubExpr(), D, lvalue, capturedByInit);
798a9ac8606Spatrick }
799e5dd7070Spatrick
800e5dd7070Spatrick // We have to maintain the illusion that the variable is
801e5dd7070Spatrick // zero-initialized. If the variable might be accessed in its
802e5dd7070Spatrick // initializer, zero-initialize before running the initializer, then
803e5dd7070Spatrick // actually perform the initialization with an assign.
804e5dd7070Spatrick bool accessedByInit = false;
805e5dd7070Spatrick if (lifetime != Qualifiers::OCL_ExplicitNone)
806e5dd7070Spatrick accessedByInit = (capturedByInit || isAccessedBy(D, init));
807e5dd7070Spatrick if (accessedByInit) {
808e5dd7070Spatrick LValue tempLV = lvalue;
809e5dd7070Spatrick // Drill down to the __block object if necessary.
810e5dd7070Spatrick if (capturedByInit) {
811e5dd7070Spatrick // We can use a simple GEP for this because it can't have been
812e5dd7070Spatrick // moved yet.
813e5dd7070Spatrick tempLV.setAddress(emitBlockByrefAddress(tempLV.getAddress(*this),
814e5dd7070Spatrick cast<VarDecl>(D),
815e5dd7070Spatrick /*follow*/ false));
816e5dd7070Spatrick }
817e5dd7070Spatrick
818e5dd7070Spatrick auto ty =
819e5dd7070Spatrick cast<llvm::PointerType>(tempLV.getAddress(*this).getElementType());
820e5dd7070Spatrick llvm::Value *zero = CGM.getNullPointer(ty, tempLV.getType());
821e5dd7070Spatrick
822e5dd7070Spatrick // If __weak, we want to use a barrier under certain conditions.
823e5dd7070Spatrick if (lifetime == Qualifiers::OCL_Weak)
824e5dd7070Spatrick EmitARCInitWeak(tempLV.getAddress(*this), zero);
825e5dd7070Spatrick
826e5dd7070Spatrick // Otherwise just do a simple store.
827e5dd7070Spatrick else
828e5dd7070Spatrick EmitStoreOfScalar(zero, tempLV, /* isInitialization */ true);
829e5dd7070Spatrick }
830e5dd7070Spatrick
831e5dd7070Spatrick // Emit the initializer.
832e5dd7070Spatrick llvm::Value *value = nullptr;
833e5dd7070Spatrick
834e5dd7070Spatrick switch (lifetime) {
835e5dd7070Spatrick case Qualifiers::OCL_None:
836e5dd7070Spatrick llvm_unreachable("present but none");
837e5dd7070Spatrick
838e5dd7070Spatrick case Qualifiers::OCL_Strong: {
839e5dd7070Spatrick if (!D || !isa<VarDecl>(D) || !cast<VarDecl>(D)->isARCPseudoStrong()) {
840e5dd7070Spatrick value = EmitARCRetainScalarExpr(init);
841e5dd7070Spatrick break;
842e5dd7070Spatrick }
843e5dd7070Spatrick // If D is pseudo-strong, treat it like __unsafe_unretained here. This means
844e5dd7070Spatrick // that we omit the retain, and causes non-autoreleased return values to be
845e5dd7070Spatrick // immediately released.
846*12c85518Srobert [[fallthrough]];
847e5dd7070Spatrick }
848e5dd7070Spatrick
849e5dd7070Spatrick case Qualifiers::OCL_ExplicitNone:
850e5dd7070Spatrick value = EmitARCUnsafeUnretainedScalarExpr(init);
851e5dd7070Spatrick break;
852e5dd7070Spatrick
853e5dd7070Spatrick case Qualifiers::OCL_Weak: {
854e5dd7070Spatrick // If it's not accessed by the initializer, try to emit the
855e5dd7070Spatrick // initialization with a copy or move.
856e5dd7070Spatrick if (!accessedByInit && tryEmitARCCopyWeakInit(*this, lvalue, init)) {
857e5dd7070Spatrick return;
858e5dd7070Spatrick }
859e5dd7070Spatrick
860e5dd7070Spatrick // No way to optimize a producing initializer into this. It's not
861e5dd7070Spatrick // worth optimizing for, because the value will immediately
862e5dd7070Spatrick // disappear in the common case.
863e5dd7070Spatrick value = EmitScalarExpr(init);
864e5dd7070Spatrick
865e5dd7070Spatrick if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
866e5dd7070Spatrick if (accessedByInit)
867e5dd7070Spatrick EmitARCStoreWeak(lvalue.getAddress(*this), value, /*ignored*/ true);
868e5dd7070Spatrick else
869e5dd7070Spatrick EmitARCInitWeak(lvalue.getAddress(*this), value);
870e5dd7070Spatrick return;
871e5dd7070Spatrick }
872e5dd7070Spatrick
873e5dd7070Spatrick case Qualifiers::OCL_Autoreleasing:
874e5dd7070Spatrick value = EmitARCRetainAutoreleaseScalarExpr(init);
875e5dd7070Spatrick break;
876e5dd7070Spatrick }
877e5dd7070Spatrick
878e5dd7070Spatrick if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
879e5dd7070Spatrick
880e5dd7070Spatrick EmitNullabilityCheck(lvalue, value, init->getExprLoc());
881e5dd7070Spatrick
882e5dd7070Spatrick // If the variable might have been accessed by its initializer, we
883e5dd7070Spatrick // might have to initialize with a barrier. We have to do this for
884e5dd7070Spatrick // both __weak and __strong, but __weak got filtered out above.
885e5dd7070Spatrick if (accessedByInit && lifetime == Qualifiers::OCL_Strong) {
886e5dd7070Spatrick llvm::Value *oldValue = EmitLoadOfScalar(lvalue, init->getExprLoc());
887e5dd7070Spatrick EmitStoreOfScalar(value, lvalue, /* isInitialization */ true);
888e5dd7070Spatrick EmitARCRelease(oldValue, ARCImpreciseLifetime);
889e5dd7070Spatrick return;
890e5dd7070Spatrick }
891e5dd7070Spatrick
892e5dd7070Spatrick EmitStoreOfScalar(value, lvalue, /* isInitialization */ true);
893e5dd7070Spatrick }
894e5dd7070Spatrick
895e5dd7070Spatrick /// Decide whether we can emit the non-zero parts of the specified initializer
896e5dd7070Spatrick /// with equal or fewer than NumStores scalar stores.
canEmitInitWithFewStoresAfterBZero(llvm::Constant * Init,unsigned & NumStores)897e5dd7070Spatrick static bool canEmitInitWithFewStoresAfterBZero(llvm::Constant *Init,
898e5dd7070Spatrick unsigned &NumStores) {
899e5dd7070Spatrick // Zero and Undef never requires any extra stores.
900e5dd7070Spatrick if (isa<llvm::ConstantAggregateZero>(Init) ||
901e5dd7070Spatrick isa<llvm::ConstantPointerNull>(Init) ||
902e5dd7070Spatrick isa<llvm::UndefValue>(Init))
903e5dd7070Spatrick return true;
904e5dd7070Spatrick if (isa<llvm::ConstantInt>(Init) || isa<llvm::ConstantFP>(Init) ||
905e5dd7070Spatrick isa<llvm::ConstantVector>(Init) || isa<llvm::BlockAddress>(Init) ||
906e5dd7070Spatrick isa<llvm::ConstantExpr>(Init))
907e5dd7070Spatrick return Init->isNullValue() || NumStores--;
908e5dd7070Spatrick
909e5dd7070Spatrick // See if we can emit each element.
910e5dd7070Spatrick if (isa<llvm::ConstantArray>(Init) || isa<llvm::ConstantStruct>(Init)) {
911e5dd7070Spatrick for (unsigned i = 0, e = Init->getNumOperands(); i != e; ++i) {
912e5dd7070Spatrick llvm::Constant *Elt = cast<llvm::Constant>(Init->getOperand(i));
913e5dd7070Spatrick if (!canEmitInitWithFewStoresAfterBZero(Elt, NumStores))
914e5dd7070Spatrick return false;
915e5dd7070Spatrick }
916e5dd7070Spatrick return true;
917e5dd7070Spatrick }
918e5dd7070Spatrick
919e5dd7070Spatrick if (llvm::ConstantDataSequential *CDS =
920e5dd7070Spatrick dyn_cast<llvm::ConstantDataSequential>(Init)) {
921e5dd7070Spatrick for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
922e5dd7070Spatrick llvm::Constant *Elt = CDS->getElementAsConstant(i);
923e5dd7070Spatrick if (!canEmitInitWithFewStoresAfterBZero(Elt, NumStores))
924e5dd7070Spatrick return false;
925e5dd7070Spatrick }
926e5dd7070Spatrick return true;
927e5dd7070Spatrick }
928e5dd7070Spatrick
929e5dd7070Spatrick // Anything else is hard and scary.
930e5dd7070Spatrick return false;
931e5dd7070Spatrick }
932e5dd7070Spatrick
933e5dd7070Spatrick /// For inits that canEmitInitWithFewStoresAfterBZero returned true for, emit
934e5dd7070Spatrick /// the scalar stores that would be required.
emitStoresForInitAfterBZero(CodeGenModule & CGM,llvm::Constant * Init,Address Loc,bool isVolatile,CGBuilderTy & Builder,bool IsAutoInit)935e5dd7070Spatrick static void emitStoresForInitAfterBZero(CodeGenModule &CGM,
936e5dd7070Spatrick llvm::Constant *Init, Address Loc,
937a9ac8606Spatrick bool isVolatile, CGBuilderTy &Builder,
938a9ac8606Spatrick bool IsAutoInit) {
939e5dd7070Spatrick assert(!Init->isNullValue() && !isa<llvm::UndefValue>(Init) &&
940e5dd7070Spatrick "called emitStoresForInitAfterBZero for zero or undef value.");
941e5dd7070Spatrick
942e5dd7070Spatrick if (isa<llvm::ConstantInt>(Init) || isa<llvm::ConstantFP>(Init) ||
943e5dd7070Spatrick isa<llvm::ConstantVector>(Init) || isa<llvm::BlockAddress>(Init) ||
944e5dd7070Spatrick isa<llvm::ConstantExpr>(Init)) {
945a9ac8606Spatrick auto *I = Builder.CreateStore(Init, Loc, isVolatile);
946a9ac8606Spatrick if (IsAutoInit)
947a9ac8606Spatrick I->addAnnotationMetadata("auto-init");
948e5dd7070Spatrick return;
949e5dd7070Spatrick }
950e5dd7070Spatrick
951e5dd7070Spatrick if (llvm::ConstantDataSequential *CDS =
952e5dd7070Spatrick dyn_cast<llvm::ConstantDataSequential>(Init)) {
953e5dd7070Spatrick for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
954e5dd7070Spatrick llvm::Constant *Elt = CDS->getElementAsConstant(i);
955e5dd7070Spatrick
956e5dd7070Spatrick // If necessary, get a pointer to the element and emit it.
957e5dd7070Spatrick if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt))
958e5dd7070Spatrick emitStoresForInitAfterBZero(
959e5dd7070Spatrick CGM, Elt, Builder.CreateConstInBoundsGEP2_32(Loc, 0, i), isVolatile,
960a9ac8606Spatrick Builder, IsAutoInit);
961e5dd7070Spatrick }
962e5dd7070Spatrick return;
963e5dd7070Spatrick }
964e5dd7070Spatrick
965e5dd7070Spatrick assert((isa<llvm::ConstantStruct>(Init) || isa<llvm::ConstantArray>(Init)) &&
966e5dd7070Spatrick "Unknown value type!");
967e5dd7070Spatrick
968e5dd7070Spatrick for (unsigned i = 0, e = Init->getNumOperands(); i != e; ++i) {
969e5dd7070Spatrick llvm::Constant *Elt = cast<llvm::Constant>(Init->getOperand(i));
970e5dd7070Spatrick
971e5dd7070Spatrick // If necessary, get a pointer to the element and emit it.
972e5dd7070Spatrick if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt))
973e5dd7070Spatrick emitStoresForInitAfterBZero(CGM, Elt,
974e5dd7070Spatrick Builder.CreateConstInBoundsGEP2_32(Loc, 0, i),
975a9ac8606Spatrick isVolatile, Builder, IsAutoInit);
976e5dd7070Spatrick }
977e5dd7070Spatrick }
978e5dd7070Spatrick
979e5dd7070Spatrick /// Decide whether we should use bzero plus some stores to initialize a local
980e5dd7070Spatrick /// variable instead of using a memcpy from a constant global. It is beneficial
981e5dd7070Spatrick /// to use bzero if the global is all zeros, or mostly zeros and large.
shouldUseBZeroPlusStoresToInitialize(llvm::Constant * Init,uint64_t GlobalSize)982e5dd7070Spatrick static bool shouldUseBZeroPlusStoresToInitialize(llvm::Constant *Init,
983e5dd7070Spatrick uint64_t GlobalSize) {
984e5dd7070Spatrick // If a global is all zeros, always use a bzero.
985e5dd7070Spatrick if (isa<llvm::ConstantAggregateZero>(Init)) return true;
986e5dd7070Spatrick
987e5dd7070Spatrick // If a non-zero global is <= 32 bytes, always use a memcpy. If it is large,
988e5dd7070Spatrick // do it if it will require 6 or fewer scalar stores.
989e5dd7070Spatrick // TODO: Should budget depends on the size? Avoiding a large global warrants
990e5dd7070Spatrick // plopping in more stores.
991e5dd7070Spatrick unsigned StoreBudget = 6;
992e5dd7070Spatrick uint64_t SizeLimit = 32;
993e5dd7070Spatrick
994e5dd7070Spatrick return GlobalSize > SizeLimit &&
995e5dd7070Spatrick canEmitInitWithFewStoresAfterBZero(Init, StoreBudget);
996e5dd7070Spatrick }
997e5dd7070Spatrick
998e5dd7070Spatrick /// Decide whether we should use memset to initialize a local variable instead
999e5dd7070Spatrick /// of using a memcpy from a constant global. Assumes we've already decided to
1000e5dd7070Spatrick /// not user bzero.
1001e5dd7070Spatrick /// FIXME We could be more clever, as we are for bzero above, and generate
1002e5dd7070Spatrick /// memset followed by stores. It's unclear that's worth the effort.
shouldUseMemSetToInitialize(llvm::Constant * Init,uint64_t GlobalSize,const llvm::DataLayout & DL)1003e5dd7070Spatrick static llvm::Value *shouldUseMemSetToInitialize(llvm::Constant *Init,
1004e5dd7070Spatrick uint64_t GlobalSize,
1005e5dd7070Spatrick const llvm::DataLayout &DL) {
1006e5dd7070Spatrick uint64_t SizeLimit = 32;
1007e5dd7070Spatrick if (GlobalSize <= SizeLimit)
1008e5dd7070Spatrick return nullptr;
1009e5dd7070Spatrick return llvm::isBytewiseValue(Init, DL);
1010e5dd7070Spatrick }
1011e5dd7070Spatrick
1012e5dd7070Spatrick /// Decide whether we want to split a constant structure or array store into a
1013e5dd7070Spatrick /// sequence of its fields' stores. This may cost us code size and compilation
1014e5dd7070Spatrick /// speed, but plays better with store optimizations.
shouldSplitConstantStore(CodeGenModule & CGM,uint64_t GlobalByteSize)1015e5dd7070Spatrick static bool shouldSplitConstantStore(CodeGenModule &CGM,
1016e5dd7070Spatrick uint64_t GlobalByteSize) {
1017e5dd7070Spatrick // Don't break things that occupy more than one cacheline.
1018e5dd7070Spatrick uint64_t ByteSizeLimit = 64;
1019e5dd7070Spatrick if (CGM.getCodeGenOpts().OptimizationLevel == 0)
1020e5dd7070Spatrick return false;
1021e5dd7070Spatrick if (GlobalByteSize <= ByteSizeLimit)
1022e5dd7070Spatrick return true;
1023e5dd7070Spatrick return false;
1024e5dd7070Spatrick }
1025e5dd7070Spatrick
1026e5dd7070Spatrick enum class IsPattern { No, Yes };
1027e5dd7070Spatrick
1028e5dd7070Spatrick /// Generate a constant filled with either a pattern or zeroes.
patternOrZeroFor(CodeGenModule & CGM,IsPattern isPattern,llvm::Type * Ty)1029e5dd7070Spatrick static llvm::Constant *patternOrZeroFor(CodeGenModule &CGM, IsPattern isPattern,
1030e5dd7070Spatrick llvm::Type *Ty) {
1031e5dd7070Spatrick if (isPattern == IsPattern::Yes)
1032e5dd7070Spatrick return initializationPatternFor(CGM, Ty);
1033e5dd7070Spatrick else
1034e5dd7070Spatrick return llvm::Constant::getNullValue(Ty);
1035e5dd7070Spatrick }
1036e5dd7070Spatrick
1037e5dd7070Spatrick static llvm::Constant *constWithPadding(CodeGenModule &CGM, IsPattern isPattern,
1038e5dd7070Spatrick llvm::Constant *constant);
1039e5dd7070Spatrick
1040e5dd7070Spatrick /// Helper function for constWithPadding() to deal with padding in structures.
constStructWithPadding(CodeGenModule & CGM,IsPattern isPattern,llvm::StructType * STy,llvm::Constant * constant)1041e5dd7070Spatrick static llvm::Constant *constStructWithPadding(CodeGenModule &CGM,
1042e5dd7070Spatrick IsPattern isPattern,
1043e5dd7070Spatrick llvm::StructType *STy,
1044e5dd7070Spatrick llvm::Constant *constant) {
1045e5dd7070Spatrick const llvm::DataLayout &DL = CGM.getDataLayout();
1046e5dd7070Spatrick const llvm::StructLayout *Layout = DL.getStructLayout(STy);
1047e5dd7070Spatrick llvm::Type *Int8Ty = llvm::IntegerType::getInt8Ty(CGM.getLLVMContext());
1048e5dd7070Spatrick unsigned SizeSoFar = 0;
1049e5dd7070Spatrick SmallVector<llvm::Constant *, 8> Values;
1050e5dd7070Spatrick bool NestedIntact = true;
1051e5dd7070Spatrick for (unsigned i = 0, e = STy->getNumElements(); i != e; i++) {
1052e5dd7070Spatrick unsigned CurOff = Layout->getElementOffset(i);
1053e5dd7070Spatrick if (SizeSoFar < CurOff) {
1054e5dd7070Spatrick assert(!STy->isPacked());
1055e5dd7070Spatrick auto *PadTy = llvm::ArrayType::get(Int8Ty, CurOff - SizeSoFar);
1056e5dd7070Spatrick Values.push_back(patternOrZeroFor(CGM, isPattern, PadTy));
1057e5dd7070Spatrick }
1058e5dd7070Spatrick llvm::Constant *CurOp;
1059e5dd7070Spatrick if (constant->isZeroValue())
1060e5dd7070Spatrick CurOp = llvm::Constant::getNullValue(STy->getElementType(i));
1061e5dd7070Spatrick else
1062e5dd7070Spatrick CurOp = cast<llvm::Constant>(constant->getAggregateElement(i));
1063e5dd7070Spatrick auto *NewOp = constWithPadding(CGM, isPattern, CurOp);
1064e5dd7070Spatrick if (CurOp != NewOp)
1065e5dd7070Spatrick NestedIntact = false;
1066e5dd7070Spatrick Values.push_back(NewOp);
1067e5dd7070Spatrick SizeSoFar = CurOff + DL.getTypeAllocSize(CurOp->getType());
1068e5dd7070Spatrick }
1069e5dd7070Spatrick unsigned TotalSize = Layout->getSizeInBytes();
1070e5dd7070Spatrick if (SizeSoFar < TotalSize) {
1071e5dd7070Spatrick auto *PadTy = llvm::ArrayType::get(Int8Ty, TotalSize - SizeSoFar);
1072e5dd7070Spatrick Values.push_back(patternOrZeroFor(CGM, isPattern, PadTy));
1073e5dd7070Spatrick }
1074e5dd7070Spatrick if (NestedIntact && Values.size() == STy->getNumElements())
1075e5dd7070Spatrick return constant;
1076e5dd7070Spatrick return llvm::ConstantStruct::getAnon(Values, STy->isPacked());
1077e5dd7070Spatrick }
1078e5dd7070Spatrick
1079e5dd7070Spatrick /// Replace all padding bytes in a given constant with either a pattern byte or
1080e5dd7070Spatrick /// 0x00.
constWithPadding(CodeGenModule & CGM,IsPattern isPattern,llvm::Constant * constant)1081e5dd7070Spatrick static llvm::Constant *constWithPadding(CodeGenModule &CGM, IsPattern isPattern,
1082e5dd7070Spatrick llvm::Constant *constant) {
1083e5dd7070Spatrick llvm::Type *OrigTy = constant->getType();
1084e5dd7070Spatrick if (const auto STy = dyn_cast<llvm::StructType>(OrigTy))
1085e5dd7070Spatrick return constStructWithPadding(CGM, isPattern, STy, constant);
1086ec727ea7Spatrick if (auto *ArrayTy = dyn_cast<llvm::ArrayType>(OrigTy)) {
1087e5dd7070Spatrick llvm::SmallVector<llvm::Constant *, 8> Values;
1088ec727ea7Spatrick uint64_t Size = ArrayTy->getNumElements();
1089e5dd7070Spatrick if (!Size)
1090e5dd7070Spatrick return constant;
1091ec727ea7Spatrick llvm::Type *ElemTy = ArrayTy->getElementType();
1092ec727ea7Spatrick bool ZeroInitializer = constant->isNullValue();
1093e5dd7070Spatrick llvm::Constant *OpValue, *PaddedOp;
1094e5dd7070Spatrick if (ZeroInitializer) {
1095e5dd7070Spatrick OpValue = llvm::Constant::getNullValue(ElemTy);
1096e5dd7070Spatrick PaddedOp = constWithPadding(CGM, isPattern, OpValue);
1097e5dd7070Spatrick }
1098e5dd7070Spatrick for (unsigned Op = 0; Op != Size; ++Op) {
1099e5dd7070Spatrick if (!ZeroInitializer) {
1100e5dd7070Spatrick OpValue = constant->getAggregateElement(Op);
1101e5dd7070Spatrick PaddedOp = constWithPadding(CGM, isPattern, OpValue);
1102e5dd7070Spatrick }
1103e5dd7070Spatrick Values.push_back(PaddedOp);
1104e5dd7070Spatrick }
1105e5dd7070Spatrick auto *NewElemTy = Values[0]->getType();
1106e5dd7070Spatrick if (NewElemTy == ElemTy)
1107e5dd7070Spatrick return constant;
1108ec727ea7Spatrick auto *NewArrayTy = llvm::ArrayType::get(NewElemTy, Size);
1109ec727ea7Spatrick return llvm::ConstantArray::get(NewArrayTy, Values);
1110e5dd7070Spatrick }
1111ec727ea7Spatrick // FIXME: Add handling for tail padding in vectors. Vectors don't
1112ec727ea7Spatrick // have padding between or inside elements, but the total amount of
1113ec727ea7Spatrick // data can be less than the allocated size.
1114e5dd7070Spatrick return constant;
1115e5dd7070Spatrick }
1116e5dd7070Spatrick
createUnnamedGlobalFrom(const VarDecl & D,llvm::Constant * Constant,CharUnits Align)1117e5dd7070Spatrick Address CodeGenModule::createUnnamedGlobalFrom(const VarDecl &D,
1118e5dd7070Spatrick llvm::Constant *Constant,
1119e5dd7070Spatrick CharUnits Align) {
1120e5dd7070Spatrick auto FunctionName = [&](const DeclContext *DC) -> std::string {
1121e5dd7070Spatrick if (const auto *FD = dyn_cast<FunctionDecl>(DC)) {
1122e5dd7070Spatrick if (const auto *CC = dyn_cast<CXXConstructorDecl>(FD))
1123e5dd7070Spatrick return CC->getNameAsString();
1124e5dd7070Spatrick if (const auto *CD = dyn_cast<CXXDestructorDecl>(FD))
1125e5dd7070Spatrick return CD->getNameAsString();
1126ec727ea7Spatrick return std::string(getMangledName(FD));
1127e5dd7070Spatrick } else if (const auto *OM = dyn_cast<ObjCMethodDecl>(DC)) {
1128e5dd7070Spatrick return OM->getNameAsString();
1129e5dd7070Spatrick } else if (isa<BlockDecl>(DC)) {
1130e5dd7070Spatrick return "<block>";
1131e5dd7070Spatrick } else if (isa<CapturedDecl>(DC)) {
1132e5dd7070Spatrick return "<captured>";
1133e5dd7070Spatrick } else {
1134e5dd7070Spatrick llvm_unreachable("expected a function or method");
1135e5dd7070Spatrick }
1136e5dd7070Spatrick };
1137e5dd7070Spatrick
1138e5dd7070Spatrick // Form a simple per-variable cache of these values in case we find we
1139e5dd7070Spatrick // want to reuse them.
1140e5dd7070Spatrick llvm::GlobalVariable *&CacheEntry = InitializerConstants[&D];
1141e5dd7070Spatrick if (!CacheEntry || CacheEntry->getInitializer() != Constant) {
1142e5dd7070Spatrick auto *Ty = Constant->getType();
1143e5dd7070Spatrick bool isConstant = true;
1144e5dd7070Spatrick llvm::GlobalVariable *InsertBefore = nullptr;
1145e5dd7070Spatrick unsigned AS =
1146a9ac8606Spatrick getContext().getTargetAddressSpace(GetGlobalConstantAddressSpace());
1147e5dd7070Spatrick std::string Name;
1148e5dd7070Spatrick if (D.hasGlobalStorage())
1149e5dd7070Spatrick Name = getMangledName(&D).str() + ".const";
1150e5dd7070Spatrick else if (const DeclContext *DC = D.getParentFunctionOrMethod())
1151e5dd7070Spatrick Name = ("__const." + FunctionName(DC) + "." + D.getName()).str();
1152e5dd7070Spatrick else
1153e5dd7070Spatrick llvm_unreachable("local variable has no parent function or method");
1154e5dd7070Spatrick llvm::GlobalVariable *GV = new llvm::GlobalVariable(
1155e5dd7070Spatrick getModule(), Ty, isConstant, llvm::GlobalValue::PrivateLinkage,
1156e5dd7070Spatrick Constant, Name, InsertBefore, llvm::GlobalValue::NotThreadLocal, AS);
1157e5dd7070Spatrick GV->setAlignment(Align.getAsAlign());
1158e5dd7070Spatrick GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1159e5dd7070Spatrick CacheEntry = GV;
1160*12c85518Srobert } else if (CacheEntry->getAlignment() < uint64_t(Align.getQuantity())) {
1161e5dd7070Spatrick CacheEntry->setAlignment(Align.getAsAlign());
1162e5dd7070Spatrick }
1163e5dd7070Spatrick
1164*12c85518Srobert return Address(CacheEntry, CacheEntry->getValueType(), Align);
1165e5dd7070Spatrick }
1166e5dd7070Spatrick
createUnnamedGlobalForMemcpyFrom(CodeGenModule & CGM,const VarDecl & D,CGBuilderTy & Builder,llvm::Constant * Constant,CharUnits Align)1167e5dd7070Spatrick static Address createUnnamedGlobalForMemcpyFrom(CodeGenModule &CGM,
1168e5dd7070Spatrick const VarDecl &D,
1169e5dd7070Spatrick CGBuilderTy &Builder,
1170e5dd7070Spatrick llvm::Constant *Constant,
1171e5dd7070Spatrick CharUnits Align) {
1172e5dd7070Spatrick Address SrcPtr = CGM.createUnnamedGlobalFrom(D, Constant, Align);
1173*12c85518Srobert return Builder.CreateElementBitCast(SrcPtr, CGM.Int8Ty);
1174e5dd7070Spatrick }
1175e5dd7070Spatrick
emitStoresForConstant(CodeGenModule & CGM,const VarDecl & D,Address Loc,bool isVolatile,CGBuilderTy & Builder,llvm::Constant * constant,bool IsAutoInit)1176e5dd7070Spatrick static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
1177e5dd7070Spatrick Address Loc, bool isVolatile,
1178e5dd7070Spatrick CGBuilderTy &Builder,
1179a9ac8606Spatrick llvm::Constant *constant, bool IsAutoInit) {
1180e5dd7070Spatrick auto *Ty = constant->getType();
1181e5dd7070Spatrick uint64_t ConstantSize = CGM.getDataLayout().getTypeAllocSize(Ty);
1182e5dd7070Spatrick if (!ConstantSize)
1183e5dd7070Spatrick return;
1184e5dd7070Spatrick
1185e5dd7070Spatrick bool canDoSingleStore = Ty->isIntOrIntVectorTy() ||
1186e5dd7070Spatrick Ty->isPtrOrPtrVectorTy() || Ty->isFPOrFPVectorTy();
1187e5dd7070Spatrick if (canDoSingleStore) {
1188a9ac8606Spatrick auto *I = Builder.CreateStore(constant, Loc, isVolatile);
1189a9ac8606Spatrick if (IsAutoInit)
1190a9ac8606Spatrick I->addAnnotationMetadata("auto-init");
1191e5dd7070Spatrick return;
1192e5dd7070Spatrick }
1193e5dd7070Spatrick
1194e5dd7070Spatrick auto *SizeVal = llvm::ConstantInt::get(CGM.IntPtrTy, ConstantSize);
1195e5dd7070Spatrick
1196e5dd7070Spatrick // If the initializer is all or mostly the same, codegen with bzero / memset
1197e5dd7070Spatrick // then do a few stores afterward.
1198e5dd7070Spatrick if (shouldUseBZeroPlusStoresToInitialize(constant, ConstantSize)) {
1199a9ac8606Spatrick auto *I = Builder.CreateMemSet(Loc, llvm::ConstantInt::get(CGM.Int8Ty, 0),
1200a9ac8606Spatrick SizeVal, isVolatile);
1201a9ac8606Spatrick if (IsAutoInit)
1202a9ac8606Spatrick I->addAnnotationMetadata("auto-init");
1203e5dd7070Spatrick
1204e5dd7070Spatrick bool valueAlreadyCorrect =
1205e5dd7070Spatrick constant->isNullValue() || isa<llvm::UndefValue>(constant);
1206e5dd7070Spatrick if (!valueAlreadyCorrect) {
1207*12c85518Srobert Loc = Builder.CreateElementBitCast(Loc, Ty);
1208a9ac8606Spatrick emitStoresForInitAfterBZero(CGM, constant, Loc, isVolatile, Builder,
1209a9ac8606Spatrick IsAutoInit);
1210e5dd7070Spatrick }
1211e5dd7070Spatrick return;
1212e5dd7070Spatrick }
1213e5dd7070Spatrick
1214e5dd7070Spatrick // If the initializer is a repeated byte pattern, use memset.
1215e5dd7070Spatrick llvm::Value *Pattern =
1216e5dd7070Spatrick shouldUseMemSetToInitialize(constant, ConstantSize, CGM.getDataLayout());
1217e5dd7070Spatrick if (Pattern) {
1218e5dd7070Spatrick uint64_t Value = 0x00;
1219e5dd7070Spatrick if (!isa<llvm::UndefValue>(Pattern)) {
1220e5dd7070Spatrick const llvm::APInt &AP = cast<llvm::ConstantInt>(Pattern)->getValue();
1221e5dd7070Spatrick assert(AP.getBitWidth() <= 8);
1222e5dd7070Spatrick Value = AP.getLimitedValue();
1223e5dd7070Spatrick }
1224a9ac8606Spatrick auto *I = Builder.CreateMemSet(
1225a9ac8606Spatrick Loc, llvm::ConstantInt::get(CGM.Int8Ty, Value), SizeVal, isVolatile);
1226a9ac8606Spatrick if (IsAutoInit)
1227a9ac8606Spatrick I->addAnnotationMetadata("auto-init");
1228e5dd7070Spatrick return;
1229e5dd7070Spatrick }
1230e5dd7070Spatrick
1231e5dd7070Spatrick // If the initializer is small, use a handful of stores.
1232e5dd7070Spatrick if (shouldSplitConstantStore(CGM, ConstantSize)) {
1233e5dd7070Spatrick if (auto *STy = dyn_cast<llvm::StructType>(Ty)) {
1234e5dd7070Spatrick // FIXME: handle the case when STy != Loc.getElementType().
1235e5dd7070Spatrick if (STy == Loc.getElementType()) {
1236e5dd7070Spatrick for (unsigned i = 0; i != constant->getNumOperands(); i++) {
1237e5dd7070Spatrick Address EltPtr = Builder.CreateStructGEP(Loc, i);
1238e5dd7070Spatrick emitStoresForConstant(
1239e5dd7070Spatrick CGM, D, EltPtr, isVolatile, Builder,
1240a9ac8606Spatrick cast<llvm::Constant>(Builder.CreateExtractValue(constant, i)),
1241a9ac8606Spatrick IsAutoInit);
1242e5dd7070Spatrick }
1243e5dd7070Spatrick return;
1244e5dd7070Spatrick }
1245e5dd7070Spatrick } else if (auto *ATy = dyn_cast<llvm::ArrayType>(Ty)) {
1246e5dd7070Spatrick // FIXME: handle the case when ATy != Loc.getElementType().
1247e5dd7070Spatrick if (ATy == Loc.getElementType()) {
1248e5dd7070Spatrick for (unsigned i = 0; i != ATy->getNumElements(); i++) {
1249e5dd7070Spatrick Address EltPtr = Builder.CreateConstArrayGEP(Loc, i);
1250e5dd7070Spatrick emitStoresForConstant(
1251e5dd7070Spatrick CGM, D, EltPtr, isVolatile, Builder,
1252a9ac8606Spatrick cast<llvm::Constant>(Builder.CreateExtractValue(constant, i)),
1253a9ac8606Spatrick IsAutoInit);
1254e5dd7070Spatrick }
1255e5dd7070Spatrick return;
1256e5dd7070Spatrick }
1257e5dd7070Spatrick }
1258e5dd7070Spatrick }
1259e5dd7070Spatrick
1260e5dd7070Spatrick // Copy from a global.
1261a9ac8606Spatrick auto *I =
1262e5dd7070Spatrick Builder.CreateMemCpy(Loc,
1263e5dd7070Spatrick createUnnamedGlobalForMemcpyFrom(
1264e5dd7070Spatrick CGM, D, Builder, constant, Loc.getAlignment()),
1265e5dd7070Spatrick SizeVal, isVolatile);
1266a9ac8606Spatrick if (IsAutoInit)
1267a9ac8606Spatrick I->addAnnotationMetadata("auto-init");
1268e5dd7070Spatrick }
1269e5dd7070Spatrick
emitStoresForZeroInit(CodeGenModule & CGM,const VarDecl & D,Address Loc,bool isVolatile,CGBuilderTy & Builder)1270e5dd7070Spatrick static void emitStoresForZeroInit(CodeGenModule &CGM, const VarDecl &D,
1271e5dd7070Spatrick Address Loc, bool isVolatile,
1272e5dd7070Spatrick CGBuilderTy &Builder) {
1273e5dd7070Spatrick llvm::Type *ElTy = Loc.getElementType();
1274e5dd7070Spatrick llvm::Constant *constant =
1275e5dd7070Spatrick constWithPadding(CGM, IsPattern::No, llvm::Constant::getNullValue(ElTy));
1276a9ac8606Spatrick emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant,
1277a9ac8606Spatrick /*IsAutoInit=*/true);
1278e5dd7070Spatrick }
1279e5dd7070Spatrick
emitStoresForPatternInit(CodeGenModule & CGM,const VarDecl & D,Address Loc,bool isVolatile,CGBuilderTy & Builder)1280e5dd7070Spatrick static void emitStoresForPatternInit(CodeGenModule &CGM, const VarDecl &D,
1281e5dd7070Spatrick Address Loc, bool isVolatile,
1282e5dd7070Spatrick CGBuilderTy &Builder) {
1283e5dd7070Spatrick llvm::Type *ElTy = Loc.getElementType();
1284e5dd7070Spatrick llvm::Constant *constant = constWithPadding(
1285e5dd7070Spatrick CGM, IsPattern::Yes, initializationPatternFor(CGM, ElTy));
1286e5dd7070Spatrick assert(!isa<llvm::UndefValue>(constant));
1287a9ac8606Spatrick emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant,
1288a9ac8606Spatrick /*IsAutoInit=*/true);
1289e5dd7070Spatrick }
1290e5dd7070Spatrick
containsUndef(llvm::Constant * constant)1291e5dd7070Spatrick static bool containsUndef(llvm::Constant *constant) {
1292e5dd7070Spatrick auto *Ty = constant->getType();
1293e5dd7070Spatrick if (isa<llvm::UndefValue>(constant))
1294e5dd7070Spatrick return true;
1295e5dd7070Spatrick if (Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy())
1296e5dd7070Spatrick for (llvm::Use &Op : constant->operands())
1297e5dd7070Spatrick if (containsUndef(cast<llvm::Constant>(Op)))
1298e5dd7070Spatrick return true;
1299e5dd7070Spatrick return false;
1300e5dd7070Spatrick }
1301e5dd7070Spatrick
replaceUndef(CodeGenModule & CGM,IsPattern isPattern,llvm::Constant * constant)1302e5dd7070Spatrick static llvm::Constant *replaceUndef(CodeGenModule &CGM, IsPattern isPattern,
1303e5dd7070Spatrick llvm::Constant *constant) {
1304e5dd7070Spatrick auto *Ty = constant->getType();
1305e5dd7070Spatrick if (isa<llvm::UndefValue>(constant))
1306e5dd7070Spatrick return patternOrZeroFor(CGM, isPattern, Ty);
1307e5dd7070Spatrick if (!(Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()))
1308e5dd7070Spatrick return constant;
1309e5dd7070Spatrick if (!containsUndef(constant))
1310e5dd7070Spatrick return constant;
1311e5dd7070Spatrick llvm::SmallVector<llvm::Constant *, 8> Values(constant->getNumOperands());
1312e5dd7070Spatrick for (unsigned Op = 0, NumOp = constant->getNumOperands(); Op != NumOp; ++Op) {
1313e5dd7070Spatrick auto *OpValue = cast<llvm::Constant>(constant->getOperand(Op));
1314e5dd7070Spatrick Values[Op] = replaceUndef(CGM, isPattern, OpValue);
1315e5dd7070Spatrick }
1316e5dd7070Spatrick if (Ty->isStructTy())
1317e5dd7070Spatrick return llvm::ConstantStruct::get(cast<llvm::StructType>(Ty), Values);
1318e5dd7070Spatrick if (Ty->isArrayTy())
1319e5dd7070Spatrick return llvm::ConstantArray::get(cast<llvm::ArrayType>(Ty), Values);
1320e5dd7070Spatrick assert(Ty->isVectorTy());
1321e5dd7070Spatrick return llvm::ConstantVector::get(Values);
1322e5dd7070Spatrick }
1323e5dd7070Spatrick
1324e5dd7070Spatrick /// EmitAutoVarDecl - Emit code and set up an entry in LocalDeclMap for a
1325e5dd7070Spatrick /// variable declaration with auto, register, or no storage class specifier.
1326e5dd7070Spatrick /// These turn into simple stack objects, or GlobalValues depending on target.
EmitAutoVarDecl(const VarDecl & D)1327e5dd7070Spatrick void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) {
1328e5dd7070Spatrick AutoVarEmission emission = EmitAutoVarAlloca(D);
1329e5dd7070Spatrick EmitAutoVarInit(emission);
1330e5dd7070Spatrick EmitAutoVarCleanups(emission);
1331e5dd7070Spatrick }
1332e5dd7070Spatrick
1333e5dd7070Spatrick /// Emit a lifetime.begin marker if some criteria are satisfied.
1334e5dd7070Spatrick /// \return a pointer to the temporary size Value if a marker was emitted, null
1335e5dd7070Spatrick /// otherwise
EmitLifetimeStart(llvm::TypeSize Size,llvm::Value * Addr)1336a9ac8606Spatrick llvm::Value *CodeGenFunction::EmitLifetimeStart(llvm::TypeSize Size,
1337e5dd7070Spatrick llvm::Value *Addr) {
1338e5dd7070Spatrick if (!ShouldEmitLifetimeMarkers)
1339e5dd7070Spatrick return nullptr;
1340e5dd7070Spatrick
1341e5dd7070Spatrick assert(Addr->getType()->getPointerAddressSpace() ==
1342e5dd7070Spatrick CGM.getDataLayout().getAllocaAddrSpace() &&
1343e5dd7070Spatrick "Pointer should be in alloca address space");
1344a9ac8606Spatrick llvm::Value *SizeV = llvm::ConstantInt::get(
1345a9ac8606Spatrick Int64Ty, Size.isScalable() ? -1 : Size.getFixedValue());
1346e5dd7070Spatrick Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy);
1347e5dd7070Spatrick llvm::CallInst *C =
1348e5dd7070Spatrick Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr});
1349e5dd7070Spatrick C->setDoesNotThrow();
1350e5dd7070Spatrick return SizeV;
1351e5dd7070Spatrick }
1352e5dd7070Spatrick
EmitLifetimeEnd(llvm::Value * Size,llvm::Value * Addr)1353e5dd7070Spatrick void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
1354e5dd7070Spatrick assert(Addr->getType()->getPointerAddressSpace() ==
1355e5dd7070Spatrick CGM.getDataLayout().getAllocaAddrSpace() &&
1356e5dd7070Spatrick "Pointer should be in alloca address space");
1357e5dd7070Spatrick Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy);
1358e5dd7070Spatrick llvm::CallInst *C =
1359e5dd7070Spatrick Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Size, Addr});
1360e5dd7070Spatrick C->setDoesNotThrow();
1361e5dd7070Spatrick }
1362e5dd7070Spatrick
EmitAndRegisterVariableArrayDimensions(CGDebugInfo * DI,const VarDecl & D,bool EmitDebugInfo)1363e5dd7070Spatrick void CodeGenFunction::EmitAndRegisterVariableArrayDimensions(
1364e5dd7070Spatrick CGDebugInfo *DI, const VarDecl &D, bool EmitDebugInfo) {
1365e5dd7070Spatrick // For each dimension stores its QualType and corresponding
1366e5dd7070Spatrick // size-expression Value.
1367e5dd7070Spatrick SmallVector<CodeGenFunction::VlaSizePair, 4> Dimensions;
1368e5dd7070Spatrick SmallVector<IdentifierInfo *, 4> VLAExprNames;
1369e5dd7070Spatrick
1370e5dd7070Spatrick // Break down the array into individual dimensions.
1371e5dd7070Spatrick QualType Type1D = D.getType();
1372e5dd7070Spatrick while (getContext().getAsVariableArrayType(Type1D)) {
1373e5dd7070Spatrick auto VlaSize = getVLAElements1D(Type1D);
1374e5dd7070Spatrick if (auto *C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
1375e5dd7070Spatrick Dimensions.emplace_back(C, Type1D.getUnqualifiedType());
1376e5dd7070Spatrick else {
1377e5dd7070Spatrick // Generate a locally unique name for the size expression.
1378e5dd7070Spatrick Twine Name = Twine("__vla_expr") + Twine(VLAExprCounter++);
1379e5dd7070Spatrick SmallString<12> Buffer;
1380e5dd7070Spatrick StringRef NameRef = Name.toStringRef(Buffer);
1381e5dd7070Spatrick auto &Ident = getContext().Idents.getOwn(NameRef);
1382e5dd7070Spatrick VLAExprNames.push_back(&Ident);
1383e5dd7070Spatrick auto SizeExprAddr =
1384e5dd7070Spatrick CreateDefaultAlignTempAlloca(VlaSize.NumElts->getType(), NameRef);
1385e5dd7070Spatrick Builder.CreateStore(VlaSize.NumElts, SizeExprAddr);
1386e5dd7070Spatrick Dimensions.emplace_back(SizeExprAddr.getPointer(),
1387e5dd7070Spatrick Type1D.getUnqualifiedType());
1388e5dd7070Spatrick }
1389e5dd7070Spatrick Type1D = VlaSize.Type;
1390e5dd7070Spatrick }
1391e5dd7070Spatrick
1392e5dd7070Spatrick if (!EmitDebugInfo)
1393e5dd7070Spatrick return;
1394e5dd7070Spatrick
1395e5dd7070Spatrick // Register each dimension's size-expression with a DILocalVariable,
1396e5dd7070Spatrick // so that it can be used by CGDebugInfo when instantiating a DISubrange
1397e5dd7070Spatrick // to describe this array.
1398e5dd7070Spatrick unsigned NameIdx = 0;
1399e5dd7070Spatrick for (auto &VlaSize : Dimensions) {
1400e5dd7070Spatrick llvm::Metadata *MD;
1401e5dd7070Spatrick if (auto *C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
1402e5dd7070Spatrick MD = llvm::ConstantAsMetadata::get(C);
1403e5dd7070Spatrick else {
1404e5dd7070Spatrick // Create an artificial VarDecl to generate debug info for.
1405e5dd7070Spatrick IdentifierInfo *NameIdent = VLAExprNames[NameIdx++];
1406*12c85518Srobert assert(cast<llvm::PointerType>(VlaSize.NumElts->getType())
1407*12c85518Srobert ->isOpaqueOrPointeeTypeMatches(SizeTy) &&
1408*12c85518Srobert "Number of VLA elements must be SizeTy");
1409e5dd7070Spatrick auto QT = getContext().getIntTypeForBitwidth(
1410*12c85518Srobert SizeTy->getScalarSizeInBits(), false);
1411e5dd7070Spatrick auto *ArtificialDecl = VarDecl::Create(
1412e5dd7070Spatrick getContext(), const_cast<DeclContext *>(D.getDeclContext()),
1413e5dd7070Spatrick D.getLocation(), D.getLocation(), NameIdent, QT,
1414e5dd7070Spatrick getContext().CreateTypeSourceInfo(QT), SC_Auto);
1415e5dd7070Spatrick ArtificialDecl->setImplicit();
1416e5dd7070Spatrick
1417e5dd7070Spatrick MD = DI->EmitDeclareOfAutoVariable(ArtificialDecl, VlaSize.NumElts,
1418e5dd7070Spatrick Builder);
1419e5dd7070Spatrick }
1420e5dd7070Spatrick assert(MD && "No Size expression debug node created");
1421e5dd7070Spatrick DI->registerVLASizeExpression(VlaSize.Type, MD);
1422e5dd7070Spatrick }
1423e5dd7070Spatrick }
1424e5dd7070Spatrick
1425e5dd7070Spatrick /// EmitAutoVarAlloca - Emit the alloca and debug information for a
1426e5dd7070Spatrick /// local variable. Does not emit initialization or destruction.
1427e5dd7070Spatrick CodeGenFunction::AutoVarEmission
EmitAutoVarAlloca(const VarDecl & D)1428e5dd7070Spatrick CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
1429e5dd7070Spatrick QualType Ty = D.getType();
1430e5dd7070Spatrick assert(
1431e5dd7070Spatrick Ty.getAddressSpace() == LangAS::Default ||
1432e5dd7070Spatrick (Ty.getAddressSpace() == LangAS::opencl_private && getLangOpts().OpenCL));
1433e5dd7070Spatrick
1434e5dd7070Spatrick AutoVarEmission emission(D);
1435e5dd7070Spatrick
1436e5dd7070Spatrick bool isEscapingByRef = D.isEscapingByref();
1437e5dd7070Spatrick emission.IsEscapingByRef = isEscapingByRef;
1438e5dd7070Spatrick
1439e5dd7070Spatrick CharUnits alignment = getContext().getDeclAlign(&D);
1440e5dd7070Spatrick
1441e5dd7070Spatrick // If the type is variably-modified, emit all the VLA sizes for it.
1442e5dd7070Spatrick if (Ty->isVariablyModifiedType())
1443e5dd7070Spatrick EmitVariablyModifiedType(Ty);
1444e5dd7070Spatrick
1445e5dd7070Spatrick auto *DI = getDebugInfo();
1446e5dd7070Spatrick bool EmitDebugInfo = DI && CGM.getCodeGenOpts().hasReducedDebugInfo();
1447e5dd7070Spatrick
1448e5dd7070Spatrick Address address = Address::invalid();
1449e5dd7070Spatrick Address AllocaAddr = Address::invalid();
1450ec727ea7Spatrick Address OpenMPLocalAddr = Address::invalid();
1451ec727ea7Spatrick if (CGM.getLangOpts().OpenMPIRBuilder)
1452ec727ea7Spatrick OpenMPLocalAddr = OMPBuilderCBHelpers::getAddressOfLocalVariable(*this, &D);
1453ec727ea7Spatrick else
1454ec727ea7Spatrick OpenMPLocalAddr =
1455e5dd7070Spatrick getLangOpts().OpenMP
1456e5dd7070Spatrick ? CGM.getOpenMPRuntime().getAddressOfLocalVariable(*this, &D)
1457e5dd7070Spatrick : Address::invalid();
1458ec727ea7Spatrick
1459e5dd7070Spatrick bool NRVO = getLangOpts().ElideConstructors && D.isNRVOVariable();
1460e5dd7070Spatrick
1461e5dd7070Spatrick if (getLangOpts().OpenMP && OpenMPLocalAddr.isValid()) {
1462e5dd7070Spatrick address = OpenMPLocalAddr;
1463*12c85518Srobert AllocaAddr = OpenMPLocalAddr;
1464e5dd7070Spatrick } else if (Ty->isConstantSizeType()) {
1465e5dd7070Spatrick // If this value is an array or struct with a statically determinable
1466e5dd7070Spatrick // constant initializer, there are optimizations we can do.
1467e5dd7070Spatrick //
1468e5dd7070Spatrick // TODO: We should constant-evaluate the initializer of any variable,
1469e5dd7070Spatrick // as long as it is initialized by a constant expression. Currently,
1470e5dd7070Spatrick // isConstantInitializer produces wrong answers for structs with
1471e5dd7070Spatrick // reference or bitfield members, and a few other cases, and checking
1472e5dd7070Spatrick // for POD-ness protects us from some of these.
1473e5dd7070Spatrick if (D.getInit() && (Ty->isArrayType() || Ty->isRecordType()) &&
1474e5dd7070Spatrick (D.isConstexpr() ||
1475e5dd7070Spatrick ((Ty.isPODType(getContext()) ||
1476e5dd7070Spatrick getContext().getBaseElementType(Ty)->isObjCObjectPointerType()) &&
1477e5dd7070Spatrick D.getInit()->isConstantInitializer(getContext(), false)))) {
1478e5dd7070Spatrick
1479e5dd7070Spatrick // If the variable's a const type, and it's neither an NRVO
1480e5dd7070Spatrick // candidate nor a __block variable and has no mutable members,
1481e5dd7070Spatrick // emit it as a global instead.
1482e5dd7070Spatrick // Exception is if a variable is located in non-constant address space
1483e5dd7070Spatrick // in OpenCL.
1484e5dd7070Spatrick if ((!getLangOpts().OpenCL ||
1485e5dd7070Spatrick Ty.getAddressSpace() == LangAS::opencl_constant) &&
1486e5dd7070Spatrick (CGM.getCodeGenOpts().MergeAllConstants && !NRVO &&
1487e5dd7070Spatrick !isEscapingByRef && CGM.isTypeConstant(Ty, true))) {
1488e5dd7070Spatrick EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);
1489e5dd7070Spatrick
1490e5dd7070Spatrick // Signal this condition to later callbacks.
1491e5dd7070Spatrick emission.Addr = Address::invalid();
1492e5dd7070Spatrick assert(emission.wasEmittedAsGlobal());
1493e5dd7070Spatrick return emission;
1494e5dd7070Spatrick }
1495e5dd7070Spatrick
1496e5dd7070Spatrick // Otherwise, tell the initialization code that we're in this case.
1497e5dd7070Spatrick emission.IsConstantAggregate = true;
1498e5dd7070Spatrick }
1499e5dd7070Spatrick
1500e5dd7070Spatrick // A normal fixed sized variable becomes an alloca in the entry block,
1501e5dd7070Spatrick // unless:
1502e5dd7070Spatrick // - it's an NRVO variable.
1503e5dd7070Spatrick // - we are compiling OpenMP and it's an OpenMP local variable.
1504e5dd7070Spatrick if (NRVO) {
1505e5dd7070Spatrick // The named return value optimization: allocate this variable in the
1506e5dd7070Spatrick // return slot, so that we can elide the copy when returning this
1507e5dd7070Spatrick // variable (C++0x [class.copy]p34).
1508e5dd7070Spatrick address = ReturnValue;
1509*12c85518Srobert AllocaAddr = ReturnValue;
1510e5dd7070Spatrick
1511e5dd7070Spatrick if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
1512e5dd7070Spatrick const auto *RD = RecordTy->getDecl();
1513e5dd7070Spatrick const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
1514e5dd7070Spatrick if ((CXXRD && !CXXRD->hasTrivialDestructor()) ||
1515e5dd7070Spatrick RD->isNonTrivialToPrimitiveDestroy()) {
1516e5dd7070Spatrick // Create a flag that is used to indicate when the NRVO was applied
1517e5dd7070Spatrick // to this variable. Set it to zero to indicate that NRVO was not
1518e5dd7070Spatrick // applied.
1519e5dd7070Spatrick llvm::Value *Zero = Builder.getFalse();
1520e5dd7070Spatrick Address NRVOFlag =
1521*12c85518Srobert CreateTempAlloca(Zero->getType(), CharUnits::One(), "nrvo",
1522*12c85518Srobert /*ArraySize=*/nullptr, &AllocaAddr);
1523e5dd7070Spatrick EnsureInsertPoint();
1524e5dd7070Spatrick Builder.CreateStore(Zero, NRVOFlag);
1525e5dd7070Spatrick
1526e5dd7070Spatrick // Record the NRVO flag for this variable.
1527e5dd7070Spatrick NRVOFlags[&D] = NRVOFlag.getPointer();
1528e5dd7070Spatrick emission.NRVOFlag = NRVOFlag.getPointer();
1529e5dd7070Spatrick }
1530e5dd7070Spatrick }
1531e5dd7070Spatrick } else {
1532e5dd7070Spatrick CharUnits allocaAlignment;
1533e5dd7070Spatrick llvm::Type *allocaTy;
1534e5dd7070Spatrick if (isEscapingByRef) {
1535e5dd7070Spatrick auto &byrefInfo = getBlockByrefInfo(&D);
1536e5dd7070Spatrick allocaTy = byrefInfo.Type;
1537e5dd7070Spatrick allocaAlignment = byrefInfo.ByrefAlignment;
1538e5dd7070Spatrick } else {
1539e5dd7070Spatrick allocaTy = ConvertTypeForMem(Ty);
1540e5dd7070Spatrick allocaAlignment = alignment;
1541e5dd7070Spatrick }
1542e5dd7070Spatrick
1543e5dd7070Spatrick // Create the alloca. Note that we set the name separately from
1544e5dd7070Spatrick // building the instruction so that it's there even in no-asserts
1545e5dd7070Spatrick // builds.
1546e5dd7070Spatrick address = CreateTempAlloca(allocaTy, allocaAlignment, D.getName(),
1547e5dd7070Spatrick /*ArraySize=*/nullptr, &AllocaAddr);
1548e5dd7070Spatrick
1549e5dd7070Spatrick // Don't emit lifetime markers for MSVC catch parameters. The lifetime of
1550e5dd7070Spatrick // the catch parameter starts in the catchpad instruction, and we can't
1551e5dd7070Spatrick // insert code in those basic blocks.
1552e5dd7070Spatrick bool IsMSCatchParam =
1553e5dd7070Spatrick D.isExceptionVariable() && getTarget().getCXXABI().isMicrosoft();
1554e5dd7070Spatrick
1555e5dd7070Spatrick // Emit a lifetime intrinsic if meaningful. There's no point in doing this
1556e5dd7070Spatrick // if we don't have a valid insertion point (?).
1557e5dd7070Spatrick if (HaveInsertPoint() && !IsMSCatchParam) {
1558e5dd7070Spatrick // If there's a jump into the lifetime of this variable, its lifetime
1559e5dd7070Spatrick // gets broken up into several regions in IR, which requires more work
1560e5dd7070Spatrick // to handle correctly. For now, just omit the intrinsics; this is a
1561e5dd7070Spatrick // rare case, and it's better to just be conservatively correct.
1562e5dd7070Spatrick // PR28267.
1563e5dd7070Spatrick //
1564e5dd7070Spatrick // We have to do this in all language modes if there's a jump past the
1565e5dd7070Spatrick // declaration. We also have to do it in C if there's a jump to an
1566e5dd7070Spatrick // earlier point in the current block because non-VLA lifetimes begin as
1567e5dd7070Spatrick // soon as the containing block is entered, not when its variables
1568e5dd7070Spatrick // actually come into scope; suppressing the lifetime annotations
1569e5dd7070Spatrick // completely in this case is unnecessarily pessimistic, but again, this
1570e5dd7070Spatrick // is rare.
1571e5dd7070Spatrick if (!Bypasses.IsBypassed(&D) &&
1572e5dd7070Spatrick !(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) {
1573a9ac8606Spatrick llvm::TypeSize Size = CGM.getDataLayout().getTypeAllocSize(allocaTy);
1574e5dd7070Spatrick emission.SizeForLifetimeMarkers =
1575a9ac8606Spatrick EmitLifetimeStart(Size, AllocaAddr.getPointer());
1576e5dd7070Spatrick }
1577e5dd7070Spatrick } else {
1578e5dd7070Spatrick assert(!emission.useLifetimeMarkers());
1579e5dd7070Spatrick }
1580e5dd7070Spatrick }
1581e5dd7070Spatrick } else {
1582e5dd7070Spatrick EnsureInsertPoint();
1583e5dd7070Spatrick
1584e5dd7070Spatrick if (!DidCallStackSave) {
1585e5dd7070Spatrick // Save the stack.
1586e5dd7070Spatrick Address Stack =
1587e5dd7070Spatrick CreateTempAlloca(Int8PtrTy, getPointerAlign(), "saved_stack");
1588e5dd7070Spatrick
1589e5dd7070Spatrick llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::stacksave);
1590e5dd7070Spatrick llvm::Value *V = Builder.CreateCall(F);
1591e5dd7070Spatrick Builder.CreateStore(V, Stack);
1592e5dd7070Spatrick
1593e5dd7070Spatrick DidCallStackSave = true;
1594e5dd7070Spatrick
1595e5dd7070Spatrick // Push a cleanup block and restore the stack there.
1596e5dd7070Spatrick // FIXME: in general circumstances, this should be an EH cleanup.
1597e5dd7070Spatrick pushStackRestore(NormalCleanup, Stack);
1598e5dd7070Spatrick }
1599e5dd7070Spatrick
1600e5dd7070Spatrick auto VlaSize = getVLASize(Ty);
1601e5dd7070Spatrick llvm::Type *llvmTy = ConvertTypeForMem(VlaSize.Type);
1602e5dd7070Spatrick
1603e5dd7070Spatrick // Allocate memory for the array.
1604e5dd7070Spatrick address = CreateTempAlloca(llvmTy, alignment, "vla", VlaSize.NumElts,
1605e5dd7070Spatrick &AllocaAddr);
1606e5dd7070Spatrick
1607e5dd7070Spatrick // If we have debug info enabled, properly describe the VLA dimensions for
1608e5dd7070Spatrick // this type by registering the vla size expression for each of the
1609e5dd7070Spatrick // dimensions.
1610e5dd7070Spatrick EmitAndRegisterVariableArrayDimensions(DI, D, EmitDebugInfo);
1611e5dd7070Spatrick }
1612e5dd7070Spatrick
1613e5dd7070Spatrick setAddrOfLocalVar(&D, address);
1614e5dd7070Spatrick emission.Addr = address;
1615e5dd7070Spatrick emission.AllocaAddr = AllocaAddr;
1616e5dd7070Spatrick
1617e5dd7070Spatrick // Emit debug info for local var declaration.
1618e5dd7070Spatrick if (EmitDebugInfo && HaveInsertPoint()) {
1619e5dd7070Spatrick Address DebugAddr = address;
1620e5dd7070Spatrick bool UsePointerValue = NRVO && ReturnValuePointer.isValid();
1621e5dd7070Spatrick DI->setLocation(D.getLocation());
1622e5dd7070Spatrick
1623e5dd7070Spatrick // If NRVO, use a pointer to the return address.
1624*12c85518Srobert if (UsePointerValue) {
1625e5dd7070Spatrick DebugAddr = ReturnValuePointer;
1626*12c85518Srobert AllocaAddr = ReturnValuePointer;
1627*12c85518Srobert }
1628*12c85518Srobert (void)DI->EmitDeclareOfAutoVariable(&D, AllocaAddr.getPointer(), Builder,
1629e5dd7070Spatrick UsePointerValue);
1630e5dd7070Spatrick }
1631e5dd7070Spatrick
1632e5dd7070Spatrick if (D.hasAttr<AnnotateAttr>() && HaveInsertPoint())
1633e5dd7070Spatrick EmitVarAnnotations(&D, address.getPointer());
1634e5dd7070Spatrick
1635e5dd7070Spatrick // Make sure we call @llvm.lifetime.end.
1636e5dd7070Spatrick if (emission.useLifetimeMarkers())
1637e5dd7070Spatrick EHStack.pushCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker,
1638e5dd7070Spatrick emission.getOriginalAllocatedAddress(),
1639e5dd7070Spatrick emission.getSizeForLifetimeMarkers());
1640e5dd7070Spatrick
1641e5dd7070Spatrick return emission;
1642e5dd7070Spatrick }
1643e5dd7070Spatrick
1644e5dd7070Spatrick static bool isCapturedBy(const VarDecl &, const Expr *);
1645e5dd7070Spatrick
1646e5dd7070Spatrick /// Determines whether the given __block variable is potentially
1647e5dd7070Spatrick /// captured by the given statement.
isCapturedBy(const VarDecl & Var,const Stmt * S)1648e5dd7070Spatrick static bool isCapturedBy(const VarDecl &Var, const Stmt *S) {
1649e5dd7070Spatrick if (const Expr *E = dyn_cast<Expr>(S))
1650e5dd7070Spatrick return isCapturedBy(Var, E);
1651e5dd7070Spatrick for (const Stmt *SubStmt : S->children())
1652e5dd7070Spatrick if (isCapturedBy(Var, SubStmt))
1653e5dd7070Spatrick return true;
1654e5dd7070Spatrick return false;
1655e5dd7070Spatrick }
1656e5dd7070Spatrick
1657e5dd7070Spatrick /// Determines whether the given __block variable is potentially
1658e5dd7070Spatrick /// captured by the given expression.
isCapturedBy(const VarDecl & Var,const Expr * E)1659e5dd7070Spatrick static bool isCapturedBy(const VarDecl &Var, const Expr *E) {
1660e5dd7070Spatrick // Skip the most common kinds of expressions that make
1661e5dd7070Spatrick // hierarchy-walking expensive.
1662e5dd7070Spatrick E = E->IgnoreParenCasts();
1663e5dd7070Spatrick
1664e5dd7070Spatrick if (const BlockExpr *BE = dyn_cast<BlockExpr>(E)) {
1665e5dd7070Spatrick const BlockDecl *Block = BE->getBlockDecl();
1666e5dd7070Spatrick for (const auto &I : Block->captures()) {
1667e5dd7070Spatrick if (I.getVariable() == &Var)
1668e5dd7070Spatrick return true;
1669e5dd7070Spatrick }
1670e5dd7070Spatrick
1671e5dd7070Spatrick // No need to walk into the subexpressions.
1672e5dd7070Spatrick return false;
1673e5dd7070Spatrick }
1674e5dd7070Spatrick
1675e5dd7070Spatrick if (const StmtExpr *SE = dyn_cast<StmtExpr>(E)) {
1676e5dd7070Spatrick const CompoundStmt *CS = SE->getSubStmt();
1677e5dd7070Spatrick for (const auto *BI : CS->body())
1678e5dd7070Spatrick if (const auto *BIE = dyn_cast<Expr>(BI)) {
1679e5dd7070Spatrick if (isCapturedBy(Var, BIE))
1680e5dd7070Spatrick return true;
1681e5dd7070Spatrick }
1682e5dd7070Spatrick else if (const auto *DS = dyn_cast<DeclStmt>(BI)) {
1683e5dd7070Spatrick // special case declarations
1684e5dd7070Spatrick for (const auto *I : DS->decls()) {
1685e5dd7070Spatrick if (const auto *VD = dyn_cast<VarDecl>((I))) {
1686e5dd7070Spatrick const Expr *Init = VD->getInit();
1687e5dd7070Spatrick if (Init && isCapturedBy(Var, Init))
1688e5dd7070Spatrick return true;
1689e5dd7070Spatrick }
1690e5dd7070Spatrick }
1691e5dd7070Spatrick }
1692e5dd7070Spatrick else
1693e5dd7070Spatrick // FIXME. Make safe assumption assuming arbitrary statements cause capturing.
1694e5dd7070Spatrick // Later, provide code to poke into statements for capture analysis.
1695e5dd7070Spatrick return true;
1696e5dd7070Spatrick return false;
1697e5dd7070Spatrick }
1698e5dd7070Spatrick
1699e5dd7070Spatrick for (const Stmt *SubStmt : E->children())
1700e5dd7070Spatrick if (isCapturedBy(Var, SubStmt))
1701e5dd7070Spatrick return true;
1702e5dd7070Spatrick
1703e5dd7070Spatrick return false;
1704e5dd7070Spatrick }
1705e5dd7070Spatrick
1706e5dd7070Spatrick /// Determine whether the given initializer is trivial in the sense
1707e5dd7070Spatrick /// that it requires no code to be generated.
isTrivialInitializer(const Expr * Init)1708e5dd7070Spatrick bool CodeGenFunction::isTrivialInitializer(const Expr *Init) {
1709e5dd7070Spatrick if (!Init)
1710e5dd7070Spatrick return true;
1711e5dd7070Spatrick
1712e5dd7070Spatrick if (const CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init))
1713e5dd7070Spatrick if (CXXConstructorDecl *Constructor = Construct->getConstructor())
1714e5dd7070Spatrick if (Constructor->isTrivial() &&
1715e5dd7070Spatrick Constructor->isDefaultConstructor() &&
1716e5dd7070Spatrick !Construct->requiresZeroInitialization())
1717e5dd7070Spatrick return true;
1718e5dd7070Spatrick
1719e5dd7070Spatrick return false;
1720e5dd7070Spatrick }
1721e5dd7070Spatrick
emitZeroOrPatternForAutoVarInit(QualType type,const VarDecl & D,Address Loc)1722e5dd7070Spatrick void CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type,
1723e5dd7070Spatrick const VarDecl &D,
1724e5dd7070Spatrick Address Loc) {
1725e5dd7070Spatrick auto trivialAutoVarInit = getContext().getLangOpts().getTrivialAutoVarInit();
1726e5dd7070Spatrick CharUnits Size = getContext().getTypeSizeInChars(type);
1727e5dd7070Spatrick bool isVolatile = type.isVolatileQualified();
1728e5dd7070Spatrick if (!Size.isZero()) {
1729e5dd7070Spatrick switch (trivialAutoVarInit) {
1730e5dd7070Spatrick case LangOptions::TrivialAutoVarInitKind::Uninitialized:
1731e5dd7070Spatrick llvm_unreachable("Uninitialized handled by caller");
1732e5dd7070Spatrick case LangOptions::TrivialAutoVarInitKind::Zero:
1733ec727ea7Spatrick if (CGM.stopAutoInit())
1734ec727ea7Spatrick return;
1735e5dd7070Spatrick emitStoresForZeroInit(CGM, D, Loc, isVolatile, Builder);
1736e5dd7070Spatrick break;
1737e5dd7070Spatrick case LangOptions::TrivialAutoVarInitKind::Pattern:
1738ec727ea7Spatrick if (CGM.stopAutoInit())
1739ec727ea7Spatrick return;
1740e5dd7070Spatrick emitStoresForPatternInit(CGM, D, Loc, isVolatile, Builder);
1741e5dd7070Spatrick break;
1742e5dd7070Spatrick }
1743e5dd7070Spatrick return;
1744e5dd7070Spatrick }
1745e5dd7070Spatrick
1746e5dd7070Spatrick // VLAs look zero-sized to getTypeInfo. We can't emit constant stores to
1747e5dd7070Spatrick // them, so emit a memcpy with the VLA size to initialize each element.
1748e5dd7070Spatrick // Technically zero-sized or negative-sized VLAs are undefined, and UBSan
1749e5dd7070Spatrick // will catch that code, but there exists code which generates zero-sized
1750e5dd7070Spatrick // VLAs. Be nice and initialize whatever they requested.
1751e5dd7070Spatrick const auto *VlaType = getContext().getAsVariableArrayType(type);
1752e5dd7070Spatrick if (!VlaType)
1753e5dd7070Spatrick return;
1754e5dd7070Spatrick auto VlaSize = getVLASize(VlaType);
1755e5dd7070Spatrick auto SizeVal = VlaSize.NumElts;
1756e5dd7070Spatrick CharUnits EltSize = getContext().getTypeSizeInChars(VlaSize.Type);
1757e5dd7070Spatrick switch (trivialAutoVarInit) {
1758e5dd7070Spatrick case LangOptions::TrivialAutoVarInitKind::Uninitialized:
1759e5dd7070Spatrick llvm_unreachable("Uninitialized handled by caller");
1760e5dd7070Spatrick
1761a9ac8606Spatrick case LangOptions::TrivialAutoVarInitKind::Zero: {
1762ec727ea7Spatrick if (CGM.stopAutoInit())
1763ec727ea7Spatrick return;
1764e5dd7070Spatrick if (!EltSize.isOne())
1765e5dd7070Spatrick SizeVal = Builder.CreateNUWMul(SizeVal, CGM.getSize(EltSize));
1766a9ac8606Spatrick auto *I = Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0),
1767a9ac8606Spatrick SizeVal, isVolatile);
1768a9ac8606Spatrick I->addAnnotationMetadata("auto-init");
1769e5dd7070Spatrick break;
1770a9ac8606Spatrick }
1771e5dd7070Spatrick
1772e5dd7070Spatrick case LangOptions::TrivialAutoVarInitKind::Pattern: {
1773ec727ea7Spatrick if (CGM.stopAutoInit())
1774ec727ea7Spatrick return;
1775e5dd7070Spatrick llvm::Type *ElTy = Loc.getElementType();
1776e5dd7070Spatrick llvm::Constant *Constant = constWithPadding(
1777e5dd7070Spatrick CGM, IsPattern::Yes, initializationPatternFor(CGM, ElTy));
1778e5dd7070Spatrick CharUnits ConstantAlign = getContext().getTypeAlignInChars(VlaSize.Type);
1779e5dd7070Spatrick llvm::BasicBlock *SetupBB = createBasicBlock("vla-setup.loop");
1780e5dd7070Spatrick llvm::BasicBlock *LoopBB = createBasicBlock("vla-init.loop");
1781e5dd7070Spatrick llvm::BasicBlock *ContBB = createBasicBlock("vla-init.cont");
1782e5dd7070Spatrick llvm::Value *IsZeroSizedVLA = Builder.CreateICmpEQ(
1783e5dd7070Spatrick SizeVal, llvm::ConstantInt::get(SizeVal->getType(), 0),
1784e5dd7070Spatrick "vla.iszerosized");
1785e5dd7070Spatrick Builder.CreateCondBr(IsZeroSizedVLA, ContBB, SetupBB);
1786e5dd7070Spatrick EmitBlock(SetupBB);
1787e5dd7070Spatrick if (!EltSize.isOne())
1788e5dd7070Spatrick SizeVal = Builder.CreateNUWMul(SizeVal, CGM.getSize(EltSize));
1789e5dd7070Spatrick llvm::Value *BaseSizeInChars =
1790e5dd7070Spatrick llvm::ConstantInt::get(IntPtrTy, EltSize.getQuantity());
1791e5dd7070Spatrick Address Begin = Builder.CreateElementBitCast(Loc, Int8Ty, "vla.begin");
1792a9ac8606Spatrick llvm::Value *End = Builder.CreateInBoundsGEP(
1793a9ac8606Spatrick Begin.getElementType(), Begin.getPointer(), SizeVal, "vla.end");
1794e5dd7070Spatrick llvm::BasicBlock *OriginBB = Builder.GetInsertBlock();
1795e5dd7070Spatrick EmitBlock(LoopBB);
1796e5dd7070Spatrick llvm::PHINode *Cur = Builder.CreatePHI(Begin.getType(), 2, "vla.cur");
1797e5dd7070Spatrick Cur->addIncoming(Begin.getPointer(), OriginBB);
1798e5dd7070Spatrick CharUnits CurAlign = Loc.getAlignment().alignmentOfArrayElement(EltSize);
1799a9ac8606Spatrick auto *I =
1800*12c85518Srobert Builder.CreateMemCpy(Address(Cur, Int8Ty, CurAlign),
1801e5dd7070Spatrick createUnnamedGlobalForMemcpyFrom(
1802e5dd7070Spatrick CGM, D, Builder, Constant, ConstantAlign),
1803e5dd7070Spatrick BaseSizeInChars, isVolatile);
1804a9ac8606Spatrick I->addAnnotationMetadata("auto-init");
1805e5dd7070Spatrick llvm::Value *Next =
1806e5dd7070Spatrick Builder.CreateInBoundsGEP(Int8Ty, Cur, BaseSizeInChars, "vla.next");
1807e5dd7070Spatrick llvm::Value *Done = Builder.CreateICmpEQ(Next, End, "vla-init.isdone");
1808e5dd7070Spatrick Builder.CreateCondBr(Done, ContBB, LoopBB);
1809e5dd7070Spatrick Cur->addIncoming(Next, LoopBB);
1810e5dd7070Spatrick EmitBlock(ContBB);
1811e5dd7070Spatrick } break;
1812e5dd7070Spatrick }
1813e5dd7070Spatrick }
1814e5dd7070Spatrick
EmitAutoVarInit(const AutoVarEmission & emission)1815e5dd7070Spatrick void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
1816e5dd7070Spatrick assert(emission.Variable && "emission was not valid!");
1817e5dd7070Spatrick
1818e5dd7070Spatrick // If this was emitted as a global constant, we're done.
1819e5dd7070Spatrick if (emission.wasEmittedAsGlobal()) return;
1820e5dd7070Spatrick
1821e5dd7070Spatrick const VarDecl &D = *emission.Variable;
1822e5dd7070Spatrick auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, D.getLocation());
1823e5dd7070Spatrick QualType type = D.getType();
1824e5dd7070Spatrick
1825e5dd7070Spatrick // If this local has an initializer, emit it now.
1826e5dd7070Spatrick const Expr *Init = D.getInit();
1827e5dd7070Spatrick
1828e5dd7070Spatrick // If we are at an unreachable point, we don't need to emit the initializer
1829e5dd7070Spatrick // unless it contains a label.
1830e5dd7070Spatrick if (!HaveInsertPoint()) {
1831e5dd7070Spatrick if (!Init || !ContainsLabel(Init)) return;
1832e5dd7070Spatrick EnsureInsertPoint();
1833e5dd7070Spatrick }
1834e5dd7070Spatrick
1835e5dd7070Spatrick // Initialize the structure of a __block variable.
1836e5dd7070Spatrick if (emission.IsEscapingByRef)
1837e5dd7070Spatrick emitByrefStructureInit(emission);
1838e5dd7070Spatrick
1839e5dd7070Spatrick // Initialize the variable here if it doesn't have a initializer and it is a
1840e5dd7070Spatrick // C struct that is non-trivial to initialize or an array containing such a
1841e5dd7070Spatrick // struct.
1842e5dd7070Spatrick if (!Init &&
1843e5dd7070Spatrick type.isNonTrivialToPrimitiveDefaultInitialize() ==
1844e5dd7070Spatrick QualType::PDIK_Struct) {
1845e5dd7070Spatrick LValue Dst = MakeAddrLValue(emission.getAllocatedAddress(), type);
1846e5dd7070Spatrick if (emission.IsEscapingByRef)
1847e5dd7070Spatrick drillIntoBlockVariable(*this, Dst, &D);
1848e5dd7070Spatrick defaultInitNonTrivialCStructVar(Dst);
1849e5dd7070Spatrick return;
1850e5dd7070Spatrick }
1851e5dd7070Spatrick
1852e5dd7070Spatrick // Check whether this is a byref variable that's potentially
1853e5dd7070Spatrick // captured and moved by its own initializer. If so, we'll need to
1854e5dd7070Spatrick // emit the initializer first, then copy into the variable.
1855e5dd7070Spatrick bool capturedByInit =
1856e5dd7070Spatrick Init && emission.IsEscapingByRef && isCapturedBy(D, Init);
1857e5dd7070Spatrick
1858e5dd7070Spatrick bool locIsByrefHeader = !capturedByInit;
1859e5dd7070Spatrick const Address Loc =
1860e5dd7070Spatrick locIsByrefHeader ? emission.getObjectAddress(*this) : emission.Addr;
1861e5dd7070Spatrick
1862e5dd7070Spatrick // Note: constexpr already initializes everything correctly.
1863e5dd7070Spatrick LangOptions::TrivialAutoVarInitKind trivialAutoVarInit =
1864e5dd7070Spatrick (D.isConstexpr()
1865e5dd7070Spatrick ? LangOptions::TrivialAutoVarInitKind::Uninitialized
1866e5dd7070Spatrick : (D.getAttr<UninitializedAttr>()
1867e5dd7070Spatrick ? LangOptions::TrivialAutoVarInitKind::Uninitialized
1868e5dd7070Spatrick : getContext().getLangOpts().getTrivialAutoVarInit()));
1869e5dd7070Spatrick
1870e5dd7070Spatrick auto initializeWhatIsTechnicallyUninitialized = [&](Address Loc) {
1871e5dd7070Spatrick if (trivialAutoVarInit ==
1872e5dd7070Spatrick LangOptions::TrivialAutoVarInitKind::Uninitialized)
1873e5dd7070Spatrick return;
1874e5dd7070Spatrick
1875e5dd7070Spatrick // Only initialize a __block's storage: we always initialize the header.
1876e5dd7070Spatrick if (emission.IsEscapingByRef && !locIsByrefHeader)
1877e5dd7070Spatrick Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false);
1878e5dd7070Spatrick
1879e5dd7070Spatrick return emitZeroOrPatternForAutoVarInit(type, D, Loc);
1880e5dd7070Spatrick };
1881e5dd7070Spatrick
1882e5dd7070Spatrick if (isTrivialInitializer(Init))
1883e5dd7070Spatrick return initializeWhatIsTechnicallyUninitialized(Loc);
1884e5dd7070Spatrick
1885e5dd7070Spatrick llvm::Constant *constant = nullptr;
1886e5dd7070Spatrick if (emission.IsConstantAggregate ||
1887e5dd7070Spatrick D.mightBeUsableInConstantExpressions(getContext())) {
1888e5dd7070Spatrick assert(!capturedByInit && "constant init contains a capturing block?");
1889e5dd7070Spatrick constant = ConstantEmitter(*this).tryEmitAbstractForInitializer(D);
1890e5dd7070Spatrick if (constant && !constant->isZeroValue() &&
1891e5dd7070Spatrick (trivialAutoVarInit !=
1892e5dd7070Spatrick LangOptions::TrivialAutoVarInitKind::Uninitialized)) {
1893e5dd7070Spatrick IsPattern isPattern =
1894e5dd7070Spatrick (trivialAutoVarInit == LangOptions::TrivialAutoVarInitKind::Pattern)
1895e5dd7070Spatrick ? IsPattern::Yes
1896e5dd7070Spatrick : IsPattern::No;
1897e5dd7070Spatrick // C guarantees that brace-init with fewer initializers than members in
1898e5dd7070Spatrick // the aggregate will initialize the rest of the aggregate as-if it were
1899e5dd7070Spatrick // static initialization. In turn static initialization guarantees that
1900e5dd7070Spatrick // padding is initialized to zero bits. We could instead pattern-init if D
1901e5dd7070Spatrick // has any ImplicitValueInitExpr, but that seems to be unintuitive
1902e5dd7070Spatrick // behavior.
1903e5dd7070Spatrick constant = constWithPadding(CGM, IsPattern::No,
1904e5dd7070Spatrick replaceUndef(CGM, isPattern, constant));
1905e5dd7070Spatrick }
1906e5dd7070Spatrick }
1907e5dd7070Spatrick
1908e5dd7070Spatrick if (!constant) {
1909e5dd7070Spatrick initializeWhatIsTechnicallyUninitialized(Loc);
1910e5dd7070Spatrick LValue lv = MakeAddrLValue(Loc, type);
1911e5dd7070Spatrick lv.setNonGC(true);
1912e5dd7070Spatrick return EmitExprAsInit(Init, &D, lv, capturedByInit);
1913e5dd7070Spatrick }
1914e5dd7070Spatrick
1915e5dd7070Spatrick if (!emission.IsConstantAggregate) {
1916e5dd7070Spatrick // For simple scalar/complex initialization, store the value directly.
1917e5dd7070Spatrick LValue lv = MakeAddrLValue(Loc, type);
1918e5dd7070Spatrick lv.setNonGC(true);
1919e5dd7070Spatrick return EmitStoreThroughLValue(RValue::get(constant), lv, true);
1920e5dd7070Spatrick }
1921e5dd7070Spatrick
1922*12c85518Srobert emitStoresForConstant(CGM, D, Builder.CreateElementBitCast(Loc, CGM.Int8Ty),
1923*12c85518Srobert type.isVolatileQualified(), Builder, constant,
1924*12c85518Srobert /*IsAutoInit=*/false);
1925e5dd7070Spatrick }
1926e5dd7070Spatrick
1927e5dd7070Spatrick /// Emit an expression as an initializer for an object (variable, field, etc.)
1928e5dd7070Spatrick /// at the given location. The expression is not necessarily the normal
1929e5dd7070Spatrick /// initializer for the object, and the address is not necessarily
1930e5dd7070Spatrick /// its normal location.
1931e5dd7070Spatrick ///
1932e5dd7070Spatrick /// \param init the initializing expression
1933e5dd7070Spatrick /// \param D the object to act as if we're initializing
1934ec727ea7Spatrick /// \param lvalue the lvalue to initialize
1935e5dd7070Spatrick /// \param capturedByInit true if \p D is a __block variable
1936e5dd7070Spatrick /// whose address is potentially changed by the initializer
EmitExprAsInit(const Expr * init,const ValueDecl * D,LValue lvalue,bool capturedByInit)1937e5dd7070Spatrick void CodeGenFunction::EmitExprAsInit(const Expr *init, const ValueDecl *D,
1938e5dd7070Spatrick LValue lvalue, bool capturedByInit) {
1939e5dd7070Spatrick QualType type = D->getType();
1940e5dd7070Spatrick
1941e5dd7070Spatrick if (type->isReferenceType()) {
1942e5dd7070Spatrick RValue rvalue = EmitReferenceBindingToExpr(init);
1943e5dd7070Spatrick if (capturedByInit)
1944e5dd7070Spatrick drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
1945e5dd7070Spatrick EmitStoreThroughLValue(rvalue, lvalue, true);
1946e5dd7070Spatrick return;
1947e5dd7070Spatrick }
1948e5dd7070Spatrick switch (getEvaluationKind(type)) {
1949e5dd7070Spatrick case TEK_Scalar:
1950e5dd7070Spatrick EmitScalarInit(init, D, lvalue, capturedByInit);
1951e5dd7070Spatrick return;
1952e5dd7070Spatrick case TEK_Complex: {
1953e5dd7070Spatrick ComplexPairTy complex = EmitComplexExpr(init);
1954e5dd7070Spatrick if (capturedByInit)
1955e5dd7070Spatrick drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
1956e5dd7070Spatrick EmitStoreOfComplex(complex, lvalue, /*init*/ true);
1957e5dd7070Spatrick return;
1958e5dd7070Spatrick }
1959e5dd7070Spatrick case TEK_Aggregate:
1960e5dd7070Spatrick if (type->isAtomicType()) {
1961e5dd7070Spatrick EmitAtomicInit(const_cast<Expr*>(init), lvalue);
1962e5dd7070Spatrick } else {
1963e5dd7070Spatrick AggValueSlot::Overlap_t Overlap = AggValueSlot::MayOverlap;
1964e5dd7070Spatrick if (isa<VarDecl>(D))
1965e5dd7070Spatrick Overlap = AggValueSlot::DoesNotOverlap;
1966e5dd7070Spatrick else if (auto *FD = dyn_cast<FieldDecl>(D))
1967e5dd7070Spatrick Overlap = getOverlapForFieldInit(FD);
1968e5dd7070Spatrick // TODO: how can we delay here if D is captured by its initializer?
1969e5dd7070Spatrick EmitAggExpr(init, AggValueSlot::forLValue(
1970e5dd7070Spatrick lvalue, *this, AggValueSlot::IsDestructed,
1971e5dd7070Spatrick AggValueSlot::DoesNotNeedGCBarriers,
1972e5dd7070Spatrick AggValueSlot::IsNotAliased, Overlap));
1973e5dd7070Spatrick }
1974e5dd7070Spatrick return;
1975e5dd7070Spatrick }
1976e5dd7070Spatrick llvm_unreachable("bad evaluation kind");
1977e5dd7070Spatrick }
1978e5dd7070Spatrick
1979e5dd7070Spatrick /// Enter a destroy cleanup for the given local variable.
emitAutoVarTypeCleanup(const CodeGenFunction::AutoVarEmission & emission,QualType::DestructionKind dtorKind)1980e5dd7070Spatrick void CodeGenFunction::emitAutoVarTypeCleanup(
1981e5dd7070Spatrick const CodeGenFunction::AutoVarEmission &emission,
1982e5dd7070Spatrick QualType::DestructionKind dtorKind) {
1983e5dd7070Spatrick assert(dtorKind != QualType::DK_none);
1984e5dd7070Spatrick
1985e5dd7070Spatrick // Note that for __block variables, we want to destroy the
1986e5dd7070Spatrick // original stack object, not the possibly forwarded object.
1987e5dd7070Spatrick Address addr = emission.getObjectAddress(*this);
1988e5dd7070Spatrick
1989e5dd7070Spatrick const VarDecl *var = emission.Variable;
1990e5dd7070Spatrick QualType type = var->getType();
1991e5dd7070Spatrick
1992e5dd7070Spatrick CleanupKind cleanupKind = NormalAndEHCleanup;
1993e5dd7070Spatrick CodeGenFunction::Destroyer *destroyer = nullptr;
1994e5dd7070Spatrick
1995e5dd7070Spatrick switch (dtorKind) {
1996e5dd7070Spatrick case QualType::DK_none:
1997e5dd7070Spatrick llvm_unreachable("no cleanup for trivially-destructible variable");
1998e5dd7070Spatrick
1999e5dd7070Spatrick case QualType::DK_cxx_destructor:
2000e5dd7070Spatrick // If there's an NRVO flag on the emission, we need a different
2001e5dd7070Spatrick // cleanup.
2002e5dd7070Spatrick if (emission.NRVOFlag) {
2003e5dd7070Spatrick assert(!type->isArrayType());
2004e5dd7070Spatrick CXXDestructorDecl *dtor = type->getAsCXXRecordDecl()->getDestructor();
2005e5dd7070Spatrick EHStack.pushCleanup<DestroyNRVOVariableCXX>(cleanupKind, addr, type, dtor,
2006e5dd7070Spatrick emission.NRVOFlag);
2007e5dd7070Spatrick return;
2008e5dd7070Spatrick }
2009e5dd7070Spatrick break;
2010e5dd7070Spatrick
2011e5dd7070Spatrick case QualType::DK_objc_strong_lifetime:
2012e5dd7070Spatrick // Suppress cleanups for pseudo-strong variables.
2013e5dd7070Spatrick if (var->isARCPseudoStrong()) return;
2014e5dd7070Spatrick
2015e5dd7070Spatrick // Otherwise, consider whether to use an EH cleanup or not.
2016e5dd7070Spatrick cleanupKind = getARCCleanupKind();
2017e5dd7070Spatrick
2018e5dd7070Spatrick // Use the imprecise destroyer by default.
2019e5dd7070Spatrick if (!var->hasAttr<ObjCPreciseLifetimeAttr>())
2020e5dd7070Spatrick destroyer = CodeGenFunction::destroyARCStrongImprecise;
2021e5dd7070Spatrick break;
2022e5dd7070Spatrick
2023e5dd7070Spatrick case QualType::DK_objc_weak_lifetime:
2024e5dd7070Spatrick break;
2025e5dd7070Spatrick
2026e5dd7070Spatrick case QualType::DK_nontrivial_c_struct:
2027e5dd7070Spatrick destroyer = CodeGenFunction::destroyNonTrivialCStruct;
2028e5dd7070Spatrick if (emission.NRVOFlag) {
2029e5dd7070Spatrick assert(!type->isArrayType());
2030e5dd7070Spatrick EHStack.pushCleanup<DestroyNRVOVariableC>(cleanupKind, addr,
2031e5dd7070Spatrick emission.NRVOFlag, type);
2032e5dd7070Spatrick return;
2033e5dd7070Spatrick }
2034e5dd7070Spatrick break;
2035e5dd7070Spatrick }
2036e5dd7070Spatrick
2037e5dd7070Spatrick // If we haven't chosen a more specific destroyer, use the default.
2038e5dd7070Spatrick if (!destroyer) destroyer = getDestroyer(dtorKind);
2039e5dd7070Spatrick
2040e5dd7070Spatrick // Use an EH cleanup in array destructors iff the destructor itself
2041e5dd7070Spatrick // is being pushed as an EH cleanup.
2042e5dd7070Spatrick bool useEHCleanup = (cleanupKind & EHCleanup);
2043e5dd7070Spatrick EHStack.pushCleanup<DestroyObject>(cleanupKind, addr, type, destroyer,
2044e5dd7070Spatrick useEHCleanup);
2045e5dd7070Spatrick }
2046e5dd7070Spatrick
EmitAutoVarCleanups(const AutoVarEmission & emission)2047e5dd7070Spatrick void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
2048e5dd7070Spatrick assert(emission.Variable && "emission was not valid!");
2049e5dd7070Spatrick
2050e5dd7070Spatrick // If this was emitted as a global constant, we're done.
2051e5dd7070Spatrick if (emission.wasEmittedAsGlobal()) return;
2052e5dd7070Spatrick
2053e5dd7070Spatrick // If we don't have an insertion point, we're done. Sema prevents
2054e5dd7070Spatrick // us from jumping into any of these scopes anyway.
2055e5dd7070Spatrick if (!HaveInsertPoint()) return;
2056e5dd7070Spatrick
2057e5dd7070Spatrick const VarDecl &D = *emission.Variable;
2058e5dd7070Spatrick
2059e5dd7070Spatrick // Check the type for a cleanup.
2060e5dd7070Spatrick if (QualType::DestructionKind dtorKind = D.needsDestruction(getContext()))
2061e5dd7070Spatrick emitAutoVarTypeCleanup(emission, dtorKind);
2062e5dd7070Spatrick
2063e5dd7070Spatrick // In GC mode, honor objc_precise_lifetime.
2064e5dd7070Spatrick if (getLangOpts().getGC() != LangOptions::NonGC &&
2065e5dd7070Spatrick D.hasAttr<ObjCPreciseLifetimeAttr>()) {
2066e5dd7070Spatrick EHStack.pushCleanup<ExtendGCLifetime>(NormalCleanup, &D);
2067e5dd7070Spatrick }
2068e5dd7070Spatrick
2069e5dd7070Spatrick // Handle the cleanup attribute.
2070e5dd7070Spatrick if (const CleanupAttr *CA = D.getAttr<CleanupAttr>()) {
2071e5dd7070Spatrick const FunctionDecl *FD = CA->getFunctionDecl();
2072e5dd7070Spatrick
2073e5dd7070Spatrick llvm::Constant *F = CGM.GetAddrOfFunction(FD);
2074e5dd7070Spatrick assert(F && "Could not find function!");
2075e5dd7070Spatrick
2076e5dd7070Spatrick const CGFunctionInfo &Info = CGM.getTypes().arrangeFunctionDeclaration(FD);
2077e5dd7070Spatrick EHStack.pushCleanup<CallCleanupFunction>(NormalAndEHCleanup, F, &Info, &D);
2078e5dd7070Spatrick }
2079e5dd7070Spatrick
2080e5dd7070Spatrick // If this is a block variable, call _Block_object_destroy
2081e5dd7070Spatrick // (on the unforwarded address). Don't enter this cleanup if we're in pure-GC
2082e5dd7070Spatrick // mode.
2083e5dd7070Spatrick if (emission.IsEscapingByRef &&
2084e5dd7070Spatrick CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
2085e5dd7070Spatrick BlockFieldFlags Flags = BLOCK_FIELD_IS_BYREF;
2086e5dd7070Spatrick if (emission.Variable->getType().isObjCGCWeak())
2087e5dd7070Spatrick Flags |= BLOCK_FIELD_IS_WEAK;
2088e5dd7070Spatrick enterByrefCleanup(NormalAndEHCleanup, emission.Addr, Flags,
2089e5dd7070Spatrick /*LoadBlockVarAddr*/ false,
2090e5dd7070Spatrick cxxDestructorCanThrow(emission.Variable->getType()));
2091e5dd7070Spatrick }
2092e5dd7070Spatrick }
2093e5dd7070Spatrick
2094e5dd7070Spatrick CodeGenFunction::Destroyer *
getDestroyer(QualType::DestructionKind kind)2095e5dd7070Spatrick CodeGenFunction::getDestroyer(QualType::DestructionKind kind) {
2096e5dd7070Spatrick switch (kind) {
2097e5dd7070Spatrick case QualType::DK_none: llvm_unreachable("no destroyer for trivial dtor");
2098e5dd7070Spatrick case QualType::DK_cxx_destructor:
2099e5dd7070Spatrick return destroyCXXObject;
2100e5dd7070Spatrick case QualType::DK_objc_strong_lifetime:
2101e5dd7070Spatrick return destroyARCStrongPrecise;
2102e5dd7070Spatrick case QualType::DK_objc_weak_lifetime:
2103e5dd7070Spatrick return destroyARCWeak;
2104e5dd7070Spatrick case QualType::DK_nontrivial_c_struct:
2105e5dd7070Spatrick return destroyNonTrivialCStruct;
2106e5dd7070Spatrick }
2107e5dd7070Spatrick llvm_unreachable("Unknown DestructionKind");
2108e5dd7070Spatrick }
2109e5dd7070Spatrick
2110e5dd7070Spatrick /// pushEHDestroy - Push the standard destructor for the given type as
2111e5dd7070Spatrick /// an EH-only cleanup.
pushEHDestroy(QualType::DestructionKind dtorKind,Address addr,QualType type)2112e5dd7070Spatrick void CodeGenFunction::pushEHDestroy(QualType::DestructionKind dtorKind,
2113e5dd7070Spatrick Address addr, QualType type) {
2114e5dd7070Spatrick assert(dtorKind && "cannot push destructor for trivial type");
2115e5dd7070Spatrick assert(needsEHCleanup(dtorKind));
2116e5dd7070Spatrick
2117e5dd7070Spatrick pushDestroy(EHCleanup, addr, type, getDestroyer(dtorKind), true);
2118e5dd7070Spatrick }
2119e5dd7070Spatrick
2120e5dd7070Spatrick /// pushDestroy - Push the standard destructor for the given type as
2121e5dd7070Spatrick /// at least a normal cleanup.
pushDestroy(QualType::DestructionKind dtorKind,Address addr,QualType type)2122e5dd7070Spatrick void CodeGenFunction::pushDestroy(QualType::DestructionKind dtorKind,
2123e5dd7070Spatrick Address addr, QualType type) {
2124e5dd7070Spatrick assert(dtorKind && "cannot push destructor for trivial type");
2125e5dd7070Spatrick
2126e5dd7070Spatrick CleanupKind cleanupKind = getCleanupKind(dtorKind);
2127e5dd7070Spatrick pushDestroy(cleanupKind, addr, type, getDestroyer(dtorKind),
2128e5dd7070Spatrick cleanupKind & EHCleanup);
2129e5dd7070Spatrick }
2130e5dd7070Spatrick
pushDestroy(CleanupKind cleanupKind,Address addr,QualType type,Destroyer * destroyer,bool useEHCleanupForArray)2131e5dd7070Spatrick void CodeGenFunction::pushDestroy(CleanupKind cleanupKind, Address addr,
2132e5dd7070Spatrick QualType type, Destroyer *destroyer,
2133e5dd7070Spatrick bool useEHCleanupForArray) {
2134e5dd7070Spatrick pushFullExprCleanup<DestroyObject>(cleanupKind, addr, type,
2135e5dd7070Spatrick destroyer, useEHCleanupForArray);
2136e5dd7070Spatrick }
2137e5dd7070Spatrick
pushStackRestore(CleanupKind Kind,Address SPMem)2138e5dd7070Spatrick void CodeGenFunction::pushStackRestore(CleanupKind Kind, Address SPMem) {
2139e5dd7070Spatrick EHStack.pushCleanup<CallStackRestore>(Kind, SPMem);
2140e5dd7070Spatrick }
2141e5dd7070Spatrick
pushLifetimeExtendedDestroy(CleanupKind cleanupKind,Address addr,QualType type,Destroyer * destroyer,bool useEHCleanupForArray)2142a9ac8606Spatrick void CodeGenFunction::pushLifetimeExtendedDestroy(CleanupKind cleanupKind,
2143a9ac8606Spatrick Address addr, QualType type,
2144a9ac8606Spatrick Destroyer *destroyer,
2145a9ac8606Spatrick bool useEHCleanupForArray) {
2146a9ac8606Spatrick // If we're not in a conditional branch, we don't need to bother generating a
2147a9ac8606Spatrick // conditional cleanup.
2148a9ac8606Spatrick if (!isInConditionalBranch()) {
2149e5dd7070Spatrick // Push an EH-only cleanup for the object now.
2150e5dd7070Spatrick // FIXME: When popping normal cleanups, we need to keep this EH cleanup
2151e5dd7070Spatrick // around in case a temporary's destructor throws an exception.
2152e5dd7070Spatrick if (cleanupKind & EHCleanup)
2153e5dd7070Spatrick EHStack.pushCleanup<DestroyObject>(
2154e5dd7070Spatrick static_cast<CleanupKind>(cleanupKind & ~NormalCleanup), addr, type,
2155e5dd7070Spatrick destroyer, useEHCleanupForArray);
2156e5dd7070Spatrick
2157a9ac8606Spatrick return pushCleanupAfterFullExprWithActiveFlag<DestroyObject>(
2158a9ac8606Spatrick cleanupKind, Address::invalid(), addr, type, destroyer, useEHCleanupForArray);
2159a9ac8606Spatrick }
2160a9ac8606Spatrick
2161a9ac8606Spatrick // Otherwise, we should only destroy the object if it's been initialized.
2162a9ac8606Spatrick // Re-use the active flag and saved address across both the EH and end of
2163a9ac8606Spatrick // scope cleanups.
2164a9ac8606Spatrick
2165a9ac8606Spatrick using SavedType = typename DominatingValue<Address>::saved_type;
2166a9ac8606Spatrick using ConditionalCleanupType =
2167a9ac8606Spatrick EHScopeStack::ConditionalCleanup<DestroyObject, Address, QualType,
2168a9ac8606Spatrick Destroyer *, bool>;
2169a9ac8606Spatrick
2170a9ac8606Spatrick Address ActiveFlag = createCleanupActiveFlag();
2171a9ac8606Spatrick SavedType SavedAddr = saveValueInCond(addr);
2172a9ac8606Spatrick
2173a9ac8606Spatrick if (cleanupKind & EHCleanup) {
2174a9ac8606Spatrick EHStack.pushCleanup<ConditionalCleanupType>(
2175a9ac8606Spatrick static_cast<CleanupKind>(cleanupKind & ~NormalCleanup), SavedAddr, type,
2176a9ac8606Spatrick destroyer, useEHCleanupForArray);
2177a9ac8606Spatrick initFullExprCleanupWithFlag(ActiveFlag);
2178a9ac8606Spatrick }
2179a9ac8606Spatrick
2180a9ac8606Spatrick pushCleanupAfterFullExprWithActiveFlag<ConditionalCleanupType>(
2181a9ac8606Spatrick cleanupKind, ActiveFlag, SavedAddr, type, destroyer,
2182a9ac8606Spatrick useEHCleanupForArray);
2183e5dd7070Spatrick }
2184e5dd7070Spatrick
2185e5dd7070Spatrick /// emitDestroy - Immediately perform the destruction of the given
2186e5dd7070Spatrick /// object.
2187e5dd7070Spatrick ///
2188e5dd7070Spatrick /// \param addr - the address of the object; a type*
2189e5dd7070Spatrick /// \param type - the type of the object; if an array type, all
2190e5dd7070Spatrick /// objects are destroyed in reverse order
2191e5dd7070Spatrick /// \param destroyer - the function to call to destroy individual
2192e5dd7070Spatrick /// elements
2193e5dd7070Spatrick /// \param useEHCleanupForArray - whether an EH cleanup should be
2194e5dd7070Spatrick /// used when destroying array elements, in case one of the
2195e5dd7070Spatrick /// destructions throws an exception
emitDestroy(Address addr,QualType type,Destroyer * destroyer,bool useEHCleanupForArray)2196e5dd7070Spatrick void CodeGenFunction::emitDestroy(Address addr, QualType type,
2197e5dd7070Spatrick Destroyer *destroyer,
2198e5dd7070Spatrick bool useEHCleanupForArray) {
2199e5dd7070Spatrick const ArrayType *arrayType = getContext().getAsArrayType(type);
2200e5dd7070Spatrick if (!arrayType)
2201e5dd7070Spatrick return destroyer(*this, addr, type);
2202e5dd7070Spatrick
2203e5dd7070Spatrick llvm::Value *length = emitArrayLength(arrayType, type, addr);
2204e5dd7070Spatrick
2205e5dd7070Spatrick CharUnits elementAlign =
2206e5dd7070Spatrick addr.getAlignment()
2207e5dd7070Spatrick .alignmentOfArrayElement(getContext().getTypeSizeInChars(type));
2208e5dd7070Spatrick
2209e5dd7070Spatrick // Normally we have to check whether the array is zero-length.
2210e5dd7070Spatrick bool checkZeroLength = true;
2211e5dd7070Spatrick
2212e5dd7070Spatrick // But if the array length is constant, we can suppress that.
2213e5dd7070Spatrick if (llvm::ConstantInt *constLength = dyn_cast<llvm::ConstantInt>(length)) {
2214e5dd7070Spatrick // ...and if it's constant zero, we can just skip the entire thing.
2215e5dd7070Spatrick if (constLength->isZero()) return;
2216e5dd7070Spatrick checkZeroLength = false;
2217e5dd7070Spatrick }
2218e5dd7070Spatrick
2219e5dd7070Spatrick llvm::Value *begin = addr.getPointer();
2220a9ac8606Spatrick llvm::Value *end =
2221a9ac8606Spatrick Builder.CreateInBoundsGEP(addr.getElementType(), begin, length);
2222e5dd7070Spatrick emitArrayDestroy(begin, end, type, elementAlign, destroyer,
2223e5dd7070Spatrick checkZeroLength, useEHCleanupForArray);
2224e5dd7070Spatrick }
2225e5dd7070Spatrick
2226e5dd7070Spatrick /// emitArrayDestroy - Destroys all the elements of the given array,
2227e5dd7070Spatrick /// beginning from last to first. The array cannot be zero-length.
2228e5dd7070Spatrick ///
2229e5dd7070Spatrick /// \param begin - a type* denoting the first element of the array
2230e5dd7070Spatrick /// \param end - a type* denoting one past the end of the array
2231e5dd7070Spatrick /// \param elementType - the element type of the array
2232e5dd7070Spatrick /// \param destroyer - the function to call to destroy elements
2233e5dd7070Spatrick /// \param useEHCleanup - whether to push an EH cleanup to destroy
2234e5dd7070Spatrick /// the remaining elements in case the destruction of a single
2235e5dd7070Spatrick /// element throws
emitArrayDestroy(llvm::Value * begin,llvm::Value * end,QualType elementType,CharUnits elementAlign,Destroyer * destroyer,bool checkZeroLength,bool useEHCleanup)2236e5dd7070Spatrick void CodeGenFunction::emitArrayDestroy(llvm::Value *begin,
2237e5dd7070Spatrick llvm::Value *end,
2238e5dd7070Spatrick QualType elementType,
2239e5dd7070Spatrick CharUnits elementAlign,
2240e5dd7070Spatrick Destroyer *destroyer,
2241e5dd7070Spatrick bool checkZeroLength,
2242e5dd7070Spatrick bool useEHCleanup) {
2243e5dd7070Spatrick assert(!elementType->isArrayType());
2244e5dd7070Spatrick
2245e5dd7070Spatrick // The basic structure here is a do-while loop, because we don't
2246e5dd7070Spatrick // need to check for the zero-element case.
2247e5dd7070Spatrick llvm::BasicBlock *bodyBB = createBasicBlock("arraydestroy.body");
2248e5dd7070Spatrick llvm::BasicBlock *doneBB = createBasicBlock("arraydestroy.done");
2249e5dd7070Spatrick
2250e5dd7070Spatrick if (checkZeroLength) {
2251e5dd7070Spatrick llvm::Value *isEmpty = Builder.CreateICmpEQ(begin, end,
2252e5dd7070Spatrick "arraydestroy.isempty");
2253e5dd7070Spatrick Builder.CreateCondBr(isEmpty, doneBB, bodyBB);
2254e5dd7070Spatrick }
2255e5dd7070Spatrick
2256e5dd7070Spatrick // Enter the loop body, making that address the current address.
2257e5dd7070Spatrick llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
2258e5dd7070Spatrick EmitBlock(bodyBB);
2259e5dd7070Spatrick llvm::PHINode *elementPast =
2260e5dd7070Spatrick Builder.CreatePHI(begin->getType(), 2, "arraydestroy.elementPast");
2261e5dd7070Spatrick elementPast->addIncoming(end, entryBB);
2262e5dd7070Spatrick
2263e5dd7070Spatrick // Shift the address back by one element.
2264e5dd7070Spatrick llvm::Value *negativeOne = llvm::ConstantInt::get(SizeTy, -1, true);
2265*12c85518Srobert llvm::Type *llvmElementType = ConvertTypeForMem(elementType);
2266a9ac8606Spatrick llvm::Value *element = Builder.CreateInBoundsGEP(
2267*12c85518Srobert llvmElementType, elementPast, negativeOne, "arraydestroy.element");
2268e5dd7070Spatrick
2269e5dd7070Spatrick if (useEHCleanup)
2270e5dd7070Spatrick pushRegularPartialArrayCleanup(begin, element, elementType, elementAlign,
2271e5dd7070Spatrick destroyer);
2272e5dd7070Spatrick
2273e5dd7070Spatrick // Perform the actual destruction there.
2274*12c85518Srobert destroyer(*this, Address(element, llvmElementType, elementAlign),
2275*12c85518Srobert elementType);
2276e5dd7070Spatrick
2277e5dd7070Spatrick if (useEHCleanup)
2278e5dd7070Spatrick PopCleanupBlock();
2279e5dd7070Spatrick
2280e5dd7070Spatrick // Check whether we've reached the end.
2281e5dd7070Spatrick llvm::Value *done = Builder.CreateICmpEQ(element, begin, "arraydestroy.done");
2282e5dd7070Spatrick Builder.CreateCondBr(done, doneBB, bodyBB);
2283e5dd7070Spatrick elementPast->addIncoming(element, Builder.GetInsertBlock());
2284e5dd7070Spatrick
2285e5dd7070Spatrick // Done.
2286e5dd7070Spatrick EmitBlock(doneBB);
2287e5dd7070Spatrick }
2288e5dd7070Spatrick
2289e5dd7070Spatrick /// Perform partial array destruction as if in an EH cleanup. Unlike
2290e5dd7070Spatrick /// emitArrayDestroy, the element type here may still be an array type.
emitPartialArrayDestroy(CodeGenFunction & CGF,llvm::Value * begin,llvm::Value * end,QualType type,CharUnits elementAlign,CodeGenFunction::Destroyer * destroyer)2291e5dd7070Spatrick static void emitPartialArrayDestroy(CodeGenFunction &CGF,
2292e5dd7070Spatrick llvm::Value *begin, llvm::Value *end,
2293e5dd7070Spatrick QualType type, CharUnits elementAlign,
2294e5dd7070Spatrick CodeGenFunction::Destroyer *destroyer) {
2295*12c85518Srobert llvm::Type *elemTy = CGF.ConvertTypeForMem(type);
2296*12c85518Srobert
2297e5dd7070Spatrick // If the element type is itself an array, drill down.
2298e5dd7070Spatrick unsigned arrayDepth = 0;
2299e5dd7070Spatrick while (const ArrayType *arrayType = CGF.getContext().getAsArrayType(type)) {
2300e5dd7070Spatrick // VLAs don't require a GEP index to walk into.
2301e5dd7070Spatrick if (!isa<VariableArrayType>(arrayType))
2302e5dd7070Spatrick arrayDepth++;
2303e5dd7070Spatrick type = arrayType->getElementType();
2304e5dd7070Spatrick }
2305e5dd7070Spatrick
2306e5dd7070Spatrick if (arrayDepth) {
2307e5dd7070Spatrick llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
2308e5dd7070Spatrick
2309e5dd7070Spatrick SmallVector<llvm::Value*,4> gepIndices(arrayDepth+1, zero);
2310a9ac8606Spatrick begin = CGF.Builder.CreateInBoundsGEP(
2311a9ac8606Spatrick elemTy, begin, gepIndices, "pad.arraybegin");
2312a9ac8606Spatrick end = CGF.Builder.CreateInBoundsGEP(
2313a9ac8606Spatrick elemTy, end, gepIndices, "pad.arrayend");
2314e5dd7070Spatrick }
2315e5dd7070Spatrick
2316e5dd7070Spatrick // Destroy the array. We don't ever need an EH cleanup because we
2317e5dd7070Spatrick // assume that we're in an EH cleanup ourselves, so a throwing
2318e5dd7070Spatrick // destructor causes an immediate terminate.
2319e5dd7070Spatrick CGF.emitArrayDestroy(begin, end, type, elementAlign, destroyer,
2320e5dd7070Spatrick /*checkZeroLength*/ true, /*useEHCleanup*/ false);
2321e5dd7070Spatrick }
2322e5dd7070Spatrick
2323e5dd7070Spatrick namespace {
2324e5dd7070Spatrick /// RegularPartialArrayDestroy - a cleanup which performs a partial
2325e5dd7070Spatrick /// array destroy where the end pointer is regularly determined and
2326e5dd7070Spatrick /// does not need to be loaded from a local.
2327e5dd7070Spatrick class RegularPartialArrayDestroy final : public EHScopeStack::Cleanup {
2328e5dd7070Spatrick llvm::Value *ArrayBegin;
2329e5dd7070Spatrick llvm::Value *ArrayEnd;
2330e5dd7070Spatrick QualType ElementType;
2331e5dd7070Spatrick CodeGenFunction::Destroyer *Destroyer;
2332e5dd7070Spatrick CharUnits ElementAlign;
2333e5dd7070Spatrick public:
RegularPartialArrayDestroy(llvm::Value * arrayBegin,llvm::Value * arrayEnd,QualType elementType,CharUnits elementAlign,CodeGenFunction::Destroyer * destroyer)2334e5dd7070Spatrick RegularPartialArrayDestroy(llvm::Value *arrayBegin, llvm::Value *arrayEnd,
2335e5dd7070Spatrick QualType elementType, CharUnits elementAlign,
2336e5dd7070Spatrick CodeGenFunction::Destroyer *destroyer)
2337e5dd7070Spatrick : ArrayBegin(arrayBegin), ArrayEnd(arrayEnd),
2338e5dd7070Spatrick ElementType(elementType), Destroyer(destroyer),
2339e5dd7070Spatrick ElementAlign(elementAlign) {}
2340e5dd7070Spatrick
Emit(CodeGenFunction & CGF,Flags flags)2341e5dd7070Spatrick void Emit(CodeGenFunction &CGF, Flags flags) override {
2342e5dd7070Spatrick emitPartialArrayDestroy(CGF, ArrayBegin, ArrayEnd,
2343e5dd7070Spatrick ElementType, ElementAlign, Destroyer);
2344e5dd7070Spatrick }
2345e5dd7070Spatrick };
2346e5dd7070Spatrick
2347e5dd7070Spatrick /// IrregularPartialArrayDestroy - a cleanup which performs a
2348e5dd7070Spatrick /// partial array destroy where the end pointer is irregularly
2349e5dd7070Spatrick /// determined and must be loaded from a local.
2350e5dd7070Spatrick class IrregularPartialArrayDestroy final : public EHScopeStack::Cleanup {
2351e5dd7070Spatrick llvm::Value *ArrayBegin;
2352e5dd7070Spatrick Address ArrayEndPointer;
2353e5dd7070Spatrick QualType ElementType;
2354e5dd7070Spatrick CodeGenFunction::Destroyer *Destroyer;
2355e5dd7070Spatrick CharUnits ElementAlign;
2356e5dd7070Spatrick public:
IrregularPartialArrayDestroy(llvm::Value * arrayBegin,Address arrayEndPointer,QualType elementType,CharUnits elementAlign,CodeGenFunction::Destroyer * destroyer)2357e5dd7070Spatrick IrregularPartialArrayDestroy(llvm::Value *arrayBegin,
2358e5dd7070Spatrick Address arrayEndPointer,
2359e5dd7070Spatrick QualType elementType,
2360e5dd7070Spatrick CharUnits elementAlign,
2361e5dd7070Spatrick CodeGenFunction::Destroyer *destroyer)
2362e5dd7070Spatrick : ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer),
2363e5dd7070Spatrick ElementType(elementType), Destroyer(destroyer),
2364e5dd7070Spatrick ElementAlign(elementAlign) {}
2365e5dd7070Spatrick
Emit(CodeGenFunction & CGF,Flags flags)2366e5dd7070Spatrick void Emit(CodeGenFunction &CGF, Flags flags) override {
2367e5dd7070Spatrick llvm::Value *arrayEnd = CGF.Builder.CreateLoad(ArrayEndPointer);
2368e5dd7070Spatrick emitPartialArrayDestroy(CGF, ArrayBegin, arrayEnd,
2369e5dd7070Spatrick ElementType, ElementAlign, Destroyer);
2370e5dd7070Spatrick }
2371e5dd7070Spatrick };
2372e5dd7070Spatrick } // end anonymous namespace
2373e5dd7070Spatrick
2374e5dd7070Spatrick /// pushIrregularPartialArrayCleanup - Push an EH cleanup to destroy
2375e5dd7070Spatrick /// already-constructed elements of the given array. The cleanup
2376e5dd7070Spatrick /// may be popped with DeactivateCleanupBlock or PopCleanupBlock.
2377e5dd7070Spatrick ///
2378e5dd7070Spatrick /// \param elementType - the immediate element type of the array;
2379e5dd7070Spatrick /// possibly still an array type
pushIrregularPartialArrayCleanup(llvm::Value * arrayBegin,Address arrayEndPointer,QualType elementType,CharUnits elementAlign,Destroyer * destroyer)2380e5dd7070Spatrick void CodeGenFunction::pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
2381e5dd7070Spatrick Address arrayEndPointer,
2382e5dd7070Spatrick QualType elementType,
2383e5dd7070Spatrick CharUnits elementAlign,
2384e5dd7070Spatrick Destroyer *destroyer) {
2385e5dd7070Spatrick pushFullExprCleanup<IrregularPartialArrayDestroy>(EHCleanup,
2386e5dd7070Spatrick arrayBegin, arrayEndPointer,
2387e5dd7070Spatrick elementType, elementAlign,
2388e5dd7070Spatrick destroyer);
2389e5dd7070Spatrick }
2390e5dd7070Spatrick
2391e5dd7070Spatrick /// pushRegularPartialArrayCleanup - Push an EH cleanup to destroy
2392e5dd7070Spatrick /// already-constructed elements of the given array. The cleanup
2393e5dd7070Spatrick /// may be popped with DeactivateCleanupBlock or PopCleanupBlock.
2394e5dd7070Spatrick ///
2395e5dd7070Spatrick /// \param elementType - the immediate element type of the array;
2396e5dd7070Spatrick /// possibly still an array type
pushRegularPartialArrayCleanup(llvm::Value * arrayBegin,llvm::Value * arrayEnd,QualType elementType,CharUnits elementAlign,Destroyer * destroyer)2397e5dd7070Spatrick void CodeGenFunction::pushRegularPartialArrayCleanup(llvm::Value *arrayBegin,
2398e5dd7070Spatrick llvm::Value *arrayEnd,
2399e5dd7070Spatrick QualType elementType,
2400e5dd7070Spatrick CharUnits elementAlign,
2401e5dd7070Spatrick Destroyer *destroyer) {
2402e5dd7070Spatrick pushFullExprCleanup<RegularPartialArrayDestroy>(EHCleanup,
2403e5dd7070Spatrick arrayBegin, arrayEnd,
2404e5dd7070Spatrick elementType, elementAlign,
2405e5dd7070Spatrick destroyer);
2406e5dd7070Spatrick }
2407e5dd7070Spatrick
2408e5dd7070Spatrick /// Lazily declare the @llvm.lifetime.start intrinsic.
getLLVMLifetimeStartFn()2409e5dd7070Spatrick llvm::Function *CodeGenModule::getLLVMLifetimeStartFn() {
2410e5dd7070Spatrick if (LifetimeStartFn)
2411e5dd7070Spatrick return LifetimeStartFn;
2412e5dd7070Spatrick LifetimeStartFn = llvm::Intrinsic::getDeclaration(&getModule(),
2413e5dd7070Spatrick llvm::Intrinsic::lifetime_start, AllocaInt8PtrTy);
2414e5dd7070Spatrick return LifetimeStartFn;
2415e5dd7070Spatrick }
2416e5dd7070Spatrick
2417e5dd7070Spatrick /// Lazily declare the @llvm.lifetime.end intrinsic.
getLLVMLifetimeEndFn()2418e5dd7070Spatrick llvm::Function *CodeGenModule::getLLVMLifetimeEndFn() {
2419e5dd7070Spatrick if (LifetimeEndFn)
2420e5dd7070Spatrick return LifetimeEndFn;
2421e5dd7070Spatrick LifetimeEndFn = llvm::Intrinsic::getDeclaration(&getModule(),
2422e5dd7070Spatrick llvm::Intrinsic::lifetime_end, AllocaInt8PtrTy);
2423e5dd7070Spatrick return LifetimeEndFn;
2424e5dd7070Spatrick }
2425e5dd7070Spatrick
2426e5dd7070Spatrick namespace {
2427e5dd7070Spatrick /// A cleanup to perform a release of an object at the end of a
2428e5dd7070Spatrick /// function. This is used to balance out the incoming +1 of a
2429e5dd7070Spatrick /// ns_consumed argument when we can't reasonably do that just by
2430e5dd7070Spatrick /// not doing the initial retain for a __block argument.
2431e5dd7070Spatrick struct ConsumeARCParameter final : EHScopeStack::Cleanup {
ConsumeARCParameter__anon67b25ad70511::ConsumeARCParameter2432e5dd7070Spatrick ConsumeARCParameter(llvm::Value *param,
2433e5dd7070Spatrick ARCPreciseLifetime_t precise)
2434e5dd7070Spatrick : Param(param), Precise(precise) {}
2435e5dd7070Spatrick
2436e5dd7070Spatrick llvm::Value *Param;
2437e5dd7070Spatrick ARCPreciseLifetime_t Precise;
2438e5dd7070Spatrick
Emit__anon67b25ad70511::ConsumeARCParameter2439e5dd7070Spatrick void Emit(CodeGenFunction &CGF, Flags flags) override {
2440e5dd7070Spatrick CGF.EmitARCRelease(Param, Precise);
2441e5dd7070Spatrick }
2442e5dd7070Spatrick };
2443e5dd7070Spatrick } // end anonymous namespace
2444e5dd7070Spatrick
2445e5dd7070Spatrick /// Emit an alloca (or GlobalValue depending on target)
2446e5dd7070Spatrick /// for the specified parameter and set up LocalDeclMap.
EmitParmDecl(const VarDecl & D,ParamValue Arg,unsigned ArgNo)2447e5dd7070Spatrick void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
2448e5dd7070Spatrick unsigned ArgNo) {
2449*12c85518Srobert bool NoDebugInfo = false;
2450e5dd7070Spatrick // FIXME: Why isn't ImplicitParamDecl a ParmVarDecl?
2451e5dd7070Spatrick assert((isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)) &&
2452e5dd7070Spatrick "Invalid argument to EmitParmDecl");
2453e5dd7070Spatrick
2454e5dd7070Spatrick Arg.getAnyValue()->setName(D.getName());
2455e5dd7070Spatrick
2456e5dd7070Spatrick QualType Ty = D.getType();
2457e5dd7070Spatrick
2458e5dd7070Spatrick // Use better IR generation for certain implicit parameters.
2459e5dd7070Spatrick if (auto IPD = dyn_cast<ImplicitParamDecl>(&D)) {
2460e5dd7070Spatrick // The only implicit argument a block has is its literal.
2461e5dd7070Spatrick // This may be passed as an inalloca'ed value on Windows x86.
2462e5dd7070Spatrick if (BlockInfo) {
2463e5dd7070Spatrick llvm::Value *V = Arg.isIndirect()
2464e5dd7070Spatrick ? Builder.CreateLoad(Arg.getIndirectAddress())
2465e5dd7070Spatrick : Arg.getDirectValue();
2466e5dd7070Spatrick setBlockContextParameter(IPD, ArgNo, V);
2467e5dd7070Spatrick return;
2468e5dd7070Spatrick }
2469*12c85518Srobert // Suppressing debug info for ThreadPrivateVar parameters, else it hides
2470*12c85518Srobert // debug info of TLS variables.
2471*12c85518Srobert NoDebugInfo =
2472*12c85518Srobert (IPD->getParameterKind() == ImplicitParamDecl::ThreadPrivateVar);
2473e5dd7070Spatrick }
2474e5dd7070Spatrick
2475e5dd7070Spatrick Address DeclPtr = Address::invalid();
2476*12c85518Srobert Address AllocaPtr = Address::invalid();
2477e5dd7070Spatrick bool DoStore = false;
2478e5dd7070Spatrick bool IsScalar = hasScalarEvaluationKind(Ty);
2479e5dd7070Spatrick // If we already have a pointer to the argument, reuse the input pointer.
2480e5dd7070Spatrick if (Arg.isIndirect()) {
2481e5dd7070Spatrick // If we have a prettier pointer type at this point, bitcast to that.
2482*12c85518Srobert DeclPtr = Arg.getIndirectAddress();
2483*12c85518Srobert DeclPtr = Builder.CreateElementBitCast(DeclPtr, ConvertTypeForMem(Ty),
2484*12c85518Srobert D.getName());
2485e5dd7070Spatrick // Indirect argument is in alloca address space, which may be different
2486e5dd7070Spatrick // from the default address space.
2487e5dd7070Spatrick auto AllocaAS = CGM.getASTAllocaAddressSpace();
2488e5dd7070Spatrick auto *V = DeclPtr.getPointer();
2489*12c85518Srobert AllocaPtr = DeclPtr;
2490e5dd7070Spatrick auto SrcLangAS = getLangOpts().OpenCL ? LangAS::opencl_private : AllocaAS;
2491e5dd7070Spatrick auto DestLangAS =
2492e5dd7070Spatrick getLangOpts().OpenCL ? LangAS::opencl_private : LangAS::Default;
2493e5dd7070Spatrick if (SrcLangAS != DestLangAS) {
2494e5dd7070Spatrick assert(getContext().getTargetAddressSpace(SrcLangAS) ==
2495e5dd7070Spatrick CGM.getDataLayout().getAllocaAddrSpace());
2496e5dd7070Spatrick auto DestAS = getContext().getTargetAddressSpace(DestLangAS);
2497*12c85518Srobert auto *T = DeclPtr.getElementType()->getPointerTo(DestAS);
2498*12c85518Srobert DeclPtr = DeclPtr.withPointer(getTargetHooks().performAddrSpaceCast(
2499*12c85518Srobert *this, V, SrcLangAS, DestLangAS, T, true));
2500e5dd7070Spatrick }
2501e5dd7070Spatrick
2502e5dd7070Spatrick // Push a destructor cleanup for this parameter if the ABI requires it.
2503e5dd7070Spatrick // Don't push a cleanup in a thunk for a method that will also emit a
2504e5dd7070Spatrick // cleanup.
2505a9ac8606Spatrick if (Ty->isRecordType() && !CurFuncIsThunk &&
2506e5dd7070Spatrick Ty->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee()) {
2507e5dd7070Spatrick if (QualType::DestructionKind DtorKind =
2508e5dd7070Spatrick D.needsDestruction(getContext())) {
2509e5dd7070Spatrick assert((DtorKind == QualType::DK_cxx_destructor ||
2510e5dd7070Spatrick DtorKind == QualType::DK_nontrivial_c_struct) &&
2511e5dd7070Spatrick "unexpected destructor type");
2512e5dd7070Spatrick pushDestroy(DtorKind, DeclPtr, Ty);
2513e5dd7070Spatrick CalleeDestructedParamCleanups[cast<ParmVarDecl>(&D)] =
2514e5dd7070Spatrick EHStack.stable_begin();
2515e5dd7070Spatrick }
2516e5dd7070Spatrick }
2517e5dd7070Spatrick } else {
2518e5dd7070Spatrick // Check if the parameter address is controlled by OpenMP runtime.
2519e5dd7070Spatrick Address OpenMPLocalAddr =
2520e5dd7070Spatrick getLangOpts().OpenMP
2521e5dd7070Spatrick ? CGM.getOpenMPRuntime().getAddressOfLocalVariable(*this, &D)
2522e5dd7070Spatrick : Address::invalid();
2523e5dd7070Spatrick if (getLangOpts().OpenMP && OpenMPLocalAddr.isValid()) {
2524e5dd7070Spatrick DeclPtr = OpenMPLocalAddr;
2525*12c85518Srobert AllocaPtr = DeclPtr;
2526e5dd7070Spatrick } else {
2527e5dd7070Spatrick // Otherwise, create a temporary to hold the value.
2528e5dd7070Spatrick DeclPtr = CreateMemTemp(Ty, getContext().getDeclAlign(&D),
2529*12c85518Srobert D.getName() + ".addr", &AllocaPtr);
2530e5dd7070Spatrick }
2531e5dd7070Spatrick DoStore = true;
2532e5dd7070Spatrick }
2533e5dd7070Spatrick
2534e5dd7070Spatrick llvm::Value *ArgVal = (DoStore ? Arg.getDirectValue() : nullptr);
2535e5dd7070Spatrick
2536e5dd7070Spatrick LValue lv = MakeAddrLValue(DeclPtr, Ty);
2537e5dd7070Spatrick if (IsScalar) {
2538e5dd7070Spatrick Qualifiers qs = Ty.getQualifiers();
2539e5dd7070Spatrick if (Qualifiers::ObjCLifetime lt = qs.getObjCLifetime()) {
2540e5dd7070Spatrick // We honor __attribute__((ns_consumed)) for types with lifetime.
2541e5dd7070Spatrick // For __strong, it's handled by just skipping the initial retain;
2542e5dd7070Spatrick // otherwise we have to balance out the initial +1 with an extra
2543e5dd7070Spatrick // cleanup to do the release at the end of the function.
2544e5dd7070Spatrick bool isConsumed = D.hasAttr<NSConsumedAttr>();
2545e5dd7070Spatrick
2546e5dd7070Spatrick // If a parameter is pseudo-strong then we can omit the implicit retain.
2547e5dd7070Spatrick if (D.isARCPseudoStrong()) {
2548e5dd7070Spatrick assert(lt == Qualifiers::OCL_Strong &&
2549e5dd7070Spatrick "pseudo-strong variable isn't strong?");
2550e5dd7070Spatrick assert(qs.hasConst() && "pseudo-strong variable should be const!");
2551e5dd7070Spatrick lt = Qualifiers::OCL_ExplicitNone;
2552e5dd7070Spatrick }
2553e5dd7070Spatrick
2554e5dd7070Spatrick // Load objects passed indirectly.
2555e5dd7070Spatrick if (Arg.isIndirect() && !ArgVal)
2556e5dd7070Spatrick ArgVal = Builder.CreateLoad(DeclPtr);
2557e5dd7070Spatrick
2558e5dd7070Spatrick if (lt == Qualifiers::OCL_Strong) {
2559e5dd7070Spatrick if (!isConsumed) {
2560e5dd7070Spatrick if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
2561e5dd7070Spatrick // use objc_storeStrong(&dest, value) for retaining the
2562e5dd7070Spatrick // object. But first, store a null into 'dest' because
2563e5dd7070Spatrick // objc_storeStrong attempts to release its old value.
2564e5dd7070Spatrick llvm::Value *Null = CGM.EmitNullConstant(D.getType());
2565e5dd7070Spatrick EmitStoreOfScalar(Null, lv, /* isInitialization */ true);
2566e5dd7070Spatrick EmitARCStoreStrongCall(lv.getAddress(*this), ArgVal, true);
2567e5dd7070Spatrick DoStore = false;
2568e5dd7070Spatrick }
2569e5dd7070Spatrick else
2570e5dd7070Spatrick // Don't use objc_retainBlock for block pointers, because we
2571e5dd7070Spatrick // don't want to Block_copy something just because we got it
2572e5dd7070Spatrick // as a parameter.
2573e5dd7070Spatrick ArgVal = EmitARCRetainNonBlock(ArgVal);
2574e5dd7070Spatrick }
2575e5dd7070Spatrick } else {
2576e5dd7070Spatrick // Push the cleanup for a consumed parameter.
2577e5dd7070Spatrick if (isConsumed) {
2578e5dd7070Spatrick ARCPreciseLifetime_t precise = (D.hasAttr<ObjCPreciseLifetimeAttr>()
2579e5dd7070Spatrick ? ARCPreciseLifetime : ARCImpreciseLifetime);
2580e5dd7070Spatrick EHStack.pushCleanup<ConsumeARCParameter>(getARCCleanupKind(), ArgVal,
2581e5dd7070Spatrick precise);
2582e5dd7070Spatrick }
2583e5dd7070Spatrick
2584e5dd7070Spatrick if (lt == Qualifiers::OCL_Weak) {
2585e5dd7070Spatrick EmitARCInitWeak(DeclPtr, ArgVal);
2586e5dd7070Spatrick DoStore = false; // The weak init is a store, no need to do two.
2587e5dd7070Spatrick }
2588e5dd7070Spatrick }
2589e5dd7070Spatrick
2590e5dd7070Spatrick // Enter the cleanup scope.
2591e5dd7070Spatrick EmitAutoVarWithLifetime(*this, D, DeclPtr, lt);
2592e5dd7070Spatrick }
2593e5dd7070Spatrick }
2594e5dd7070Spatrick
2595e5dd7070Spatrick // Store the initial value into the alloca.
2596e5dd7070Spatrick if (DoStore)
2597e5dd7070Spatrick EmitStoreOfScalar(ArgVal, lv, /* isInitialization */ true);
2598e5dd7070Spatrick
2599e5dd7070Spatrick setAddrOfLocalVar(&D, DeclPtr);
2600e5dd7070Spatrick
2601e5dd7070Spatrick // Emit debug info for param declarations in non-thunk functions.
2602e5dd7070Spatrick if (CGDebugInfo *DI = getDebugInfo()) {
2603*12c85518Srobert if (CGM.getCodeGenOpts().hasReducedDebugInfo() && !CurFuncIsThunk &&
2604*12c85518Srobert !NoDebugInfo) {
2605a9ac8606Spatrick llvm::DILocalVariable *DILocalVar = DI->EmitDeclareOfArgVariable(
2606*12c85518Srobert &D, AllocaPtr.getPointer(), ArgNo, Builder);
2607a9ac8606Spatrick if (const auto *Var = dyn_cast_or_null<ParmVarDecl>(&D))
2608a9ac8606Spatrick DI->getParamDbgMappings().insert({Var, DILocalVar});
2609e5dd7070Spatrick }
2610e5dd7070Spatrick }
2611e5dd7070Spatrick
2612e5dd7070Spatrick if (D.hasAttr<AnnotateAttr>())
2613e5dd7070Spatrick EmitVarAnnotations(&D, DeclPtr.getPointer());
2614e5dd7070Spatrick
2615e5dd7070Spatrick // We can only check return value nullability if all arguments to the
2616e5dd7070Spatrick // function satisfy their nullability preconditions. This makes it necessary
2617e5dd7070Spatrick // to emit null checks for args in the function body itself.
2618e5dd7070Spatrick if (requiresReturnValueNullabilityCheck()) {
2619*12c85518Srobert auto Nullability = Ty->getNullability();
2620e5dd7070Spatrick if (Nullability && *Nullability == NullabilityKind::NonNull) {
2621e5dd7070Spatrick SanitizerScope SanScope(this);
2622e5dd7070Spatrick RetValNullabilityPrecondition =
2623e5dd7070Spatrick Builder.CreateAnd(RetValNullabilityPrecondition,
2624e5dd7070Spatrick Builder.CreateIsNotNull(Arg.getAnyValue()));
2625e5dd7070Spatrick }
2626e5dd7070Spatrick }
2627e5dd7070Spatrick }
2628e5dd7070Spatrick
EmitOMPDeclareReduction(const OMPDeclareReductionDecl * D,CodeGenFunction * CGF)2629e5dd7070Spatrick void CodeGenModule::EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
2630e5dd7070Spatrick CodeGenFunction *CGF) {
2631e5dd7070Spatrick if (!LangOpts.OpenMP || (!LangOpts.EmitAllDecls && !D->isUsed()))
2632e5dd7070Spatrick return;
2633e5dd7070Spatrick getOpenMPRuntime().emitUserDefinedReduction(CGF, D);
2634e5dd7070Spatrick }
2635e5dd7070Spatrick
EmitOMPDeclareMapper(const OMPDeclareMapperDecl * D,CodeGenFunction * CGF)2636e5dd7070Spatrick void CodeGenModule::EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D,
2637e5dd7070Spatrick CodeGenFunction *CGF) {
2638e5dd7070Spatrick if (!LangOpts.OpenMP || LangOpts.OpenMPSimd ||
2639e5dd7070Spatrick (!LangOpts.EmitAllDecls && !D->isUsed()))
2640e5dd7070Spatrick return;
2641e5dd7070Spatrick getOpenMPRuntime().emitUserDefinedMapper(D, CGF);
2642e5dd7070Spatrick }
2643e5dd7070Spatrick
EmitOMPRequiresDecl(const OMPRequiresDecl * D)2644e5dd7070Spatrick void CodeGenModule::EmitOMPRequiresDecl(const OMPRequiresDecl *D) {
2645ec727ea7Spatrick getOpenMPRuntime().processRequiresDirective(D);
2646e5dd7070Spatrick }
2647a9ac8606Spatrick
EmitOMPAllocateDecl(const OMPAllocateDecl * D)2648a9ac8606Spatrick void CodeGenModule::EmitOMPAllocateDecl(const OMPAllocateDecl *D) {
2649a9ac8606Spatrick for (const Expr *E : D->varlists()) {
2650a9ac8606Spatrick const auto *DE = cast<DeclRefExpr>(E);
2651a9ac8606Spatrick const auto *VD = cast<VarDecl>(DE->getDecl());
2652a9ac8606Spatrick
2653a9ac8606Spatrick // Skip all but globals.
2654a9ac8606Spatrick if (!VD->hasGlobalStorage())
2655a9ac8606Spatrick continue;
2656a9ac8606Spatrick
2657a9ac8606Spatrick // Check if the global has been materialized yet or not. If not, we are done
2658a9ac8606Spatrick // as any later generation will utilize the OMPAllocateDeclAttr. However, if
2659a9ac8606Spatrick // we already emitted the global we might have done so before the
2660a9ac8606Spatrick // OMPAllocateDeclAttr was attached, leading to the wrong address space
2661a9ac8606Spatrick // (potentially). While not pretty, common practise is to remove the old IR
2662a9ac8606Spatrick // global and generate a new one, so we do that here too. Uses are replaced
2663a9ac8606Spatrick // properly.
2664a9ac8606Spatrick StringRef MangledName = getMangledName(VD);
2665a9ac8606Spatrick llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
2666a9ac8606Spatrick if (!Entry)
2667a9ac8606Spatrick continue;
2668a9ac8606Spatrick
2669a9ac8606Spatrick // We can also keep the existing global if the address space is what we
2670a9ac8606Spatrick // expect it to be, if not, it is replaced.
2671a9ac8606Spatrick QualType ASTTy = VD->getType();
2672a9ac8606Spatrick clang::LangAS GVAS = GetGlobalVarAddressSpace(VD);
2673a9ac8606Spatrick auto TargetAS = getContext().getTargetAddressSpace(GVAS);
2674a9ac8606Spatrick if (Entry->getType()->getAddressSpace() == TargetAS)
2675a9ac8606Spatrick continue;
2676a9ac8606Spatrick
2677a9ac8606Spatrick // Make a new global with the correct type / address space.
2678a9ac8606Spatrick llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy);
2679a9ac8606Spatrick llvm::PointerType *PTy = llvm::PointerType::get(Ty, TargetAS);
2680a9ac8606Spatrick
2681a9ac8606Spatrick // Replace all uses of the old global with a cast. Since we mutate the type
2682a9ac8606Spatrick // in place we neeed an intermediate that takes the spot of the old entry
2683a9ac8606Spatrick // until we can create the cast.
2684a9ac8606Spatrick llvm::GlobalVariable *DummyGV = new llvm::GlobalVariable(
2685a9ac8606Spatrick getModule(), Entry->getValueType(), false,
2686a9ac8606Spatrick llvm::GlobalValue::CommonLinkage, nullptr, "dummy", nullptr,
2687a9ac8606Spatrick llvm::GlobalVariable::NotThreadLocal, Entry->getAddressSpace());
2688a9ac8606Spatrick Entry->replaceAllUsesWith(DummyGV);
2689a9ac8606Spatrick
2690a9ac8606Spatrick Entry->mutateType(PTy);
2691a9ac8606Spatrick llvm::Constant *NewPtrForOldDecl =
2692a9ac8606Spatrick llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
2693a9ac8606Spatrick Entry, DummyGV->getType());
2694a9ac8606Spatrick
2695a9ac8606Spatrick // Now we have a casted version of the changed global, the dummy can be
2696a9ac8606Spatrick // replaced and deleted.
2697a9ac8606Spatrick DummyGV->replaceAllUsesWith(NewPtrForOldDecl);
2698a9ac8606Spatrick DummyGV->eraseFromParent();
2699a9ac8606Spatrick }
2700a9ac8606Spatrick }
2701*12c85518Srobert
2702*12c85518Srobert std::optional<CharUnits>
getOMPAllocateAlignment(const VarDecl * VD)2703*12c85518Srobert CodeGenModule::getOMPAllocateAlignment(const VarDecl *VD) {
2704*12c85518Srobert if (const auto *AA = VD->getAttr<OMPAllocateDeclAttr>()) {
2705*12c85518Srobert if (Expr *Alignment = AA->getAlignment()) {
2706*12c85518Srobert unsigned UserAlign =
2707*12c85518Srobert Alignment->EvaluateKnownConstInt(getContext()).getExtValue();
2708*12c85518Srobert CharUnits NaturalAlign =
2709*12c85518Srobert getNaturalTypeAlignment(VD->getType().getNonReferenceType());
2710*12c85518Srobert
2711*12c85518Srobert // OpenMP5.1 pg 185 lines 7-10
2712*12c85518Srobert // Each item in the align modifier list must be aligned to the maximum
2713*12c85518Srobert // of the specified alignment and the type's natural alignment.
2714*12c85518Srobert return CharUnits::fromQuantity(
2715*12c85518Srobert std::max<unsigned>(UserAlign, NaturalAlign.getQuantity()));
2716*12c85518Srobert }
2717*12c85518Srobert }
2718*12c85518Srobert return std::nullopt;
2719*12c85518Srobert }
2720