xref: /openbsd-src/gnu/llvm/clang/lib/CodeGen/CGDecl.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
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