xref: /openbsd-src/gnu/llvm/clang/lib/CodeGen/CodeGenFunction.h (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===-- CodeGenFunction.h - Per-Function state for LLVM CodeGen -*- C++ -*-===//
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 is the internal per-function state used for llvm translation.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENFUNCTION_H
14e5dd7070Spatrick #define LLVM_CLANG_LIB_CODEGEN_CODEGENFUNCTION_H
15e5dd7070Spatrick 
16e5dd7070Spatrick #include "CGBuilder.h"
17e5dd7070Spatrick #include "CGDebugInfo.h"
18e5dd7070Spatrick #include "CGLoopInfo.h"
19e5dd7070Spatrick #include "CGValue.h"
20e5dd7070Spatrick #include "CodeGenModule.h"
21e5dd7070Spatrick #include "CodeGenPGO.h"
22e5dd7070Spatrick #include "EHScopeStack.h"
23e5dd7070Spatrick #include "VarBypassDetector.h"
24e5dd7070Spatrick #include "clang/AST/CharUnits.h"
25e5dd7070Spatrick #include "clang/AST/CurrentSourceLocExprScope.h"
26e5dd7070Spatrick #include "clang/AST/ExprCXX.h"
27e5dd7070Spatrick #include "clang/AST/ExprObjC.h"
28e5dd7070Spatrick #include "clang/AST/ExprOpenMP.h"
29ec727ea7Spatrick #include "clang/AST/StmtOpenMP.h"
30e5dd7070Spatrick #include "clang/AST/Type.h"
31e5dd7070Spatrick #include "clang/Basic/ABI.h"
32e5dd7070Spatrick #include "clang/Basic/CapturedStmt.h"
33e5dd7070Spatrick #include "clang/Basic/CodeGenOptions.h"
34e5dd7070Spatrick #include "clang/Basic/OpenMPKinds.h"
35e5dd7070Spatrick #include "clang/Basic/TargetInfo.h"
36e5dd7070Spatrick #include "llvm/ADT/ArrayRef.h"
37e5dd7070Spatrick #include "llvm/ADT/DenseMap.h"
38e5dd7070Spatrick #include "llvm/ADT/MapVector.h"
39e5dd7070Spatrick #include "llvm/ADT/SmallVector.h"
40ec727ea7Spatrick #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
41e5dd7070Spatrick #include "llvm/IR/ValueHandle.h"
42e5dd7070Spatrick #include "llvm/Support/Debug.h"
43e5dd7070Spatrick #include "llvm/Transforms/Utils/SanitizerStats.h"
44*12c85518Srobert #include <optional>
45e5dd7070Spatrick 
46e5dd7070Spatrick namespace llvm {
47e5dd7070Spatrick class BasicBlock;
48e5dd7070Spatrick class LLVMContext;
49e5dd7070Spatrick class MDNode;
50e5dd7070Spatrick class SwitchInst;
51e5dd7070Spatrick class Twine;
52e5dd7070Spatrick class Value;
53a9ac8606Spatrick class CanonicalLoopInfo;
54e5dd7070Spatrick }
55e5dd7070Spatrick 
56e5dd7070Spatrick namespace clang {
57e5dd7070Spatrick class ASTContext;
58e5dd7070Spatrick class CXXDestructorDecl;
59e5dd7070Spatrick class CXXForRangeStmt;
60e5dd7070Spatrick class CXXTryStmt;
61e5dd7070Spatrick class Decl;
62e5dd7070Spatrick class LabelDecl;
63e5dd7070Spatrick class FunctionDecl;
64e5dd7070Spatrick class FunctionProtoType;
65e5dd7070Spatrick class LabelStmt;
66e5dd7070Spatrick class ObjCContainerDecl;
67e5dd7070Spatrick class ObjCInterfaceDecl;
68e5dd7070Spatrick class ObjCIvarDecl;
69e5dd7070Spatrick class ObjCMethodDecl;
70e5dd7070Spatrick class ObjCImplementationDecl;
71e5dd7070Spatrick class ObjCPropertyImplDecl;
72e5dd7070Spatrick class TargetInfo;
73e5dd7070Spatrick class VarDecl;
74e5dd7070Spatrick class ObjCForCollectionStmt;
75e5dd7070Spatrick class ObjCAtTryStmt;
76e5dd7070Spatrick class ObjCAtThrowStmt;
77e5dd7070Spatrick class ObjCAtSynchronizedStmt;
78e5dd7070Spatrick class ObjCAutoreleasePoolStmt;
79ec727ea7Spatrick class OMPUseDevicePtrClause;
80ec727ea7Spatrick class OMPUseDeviceAddrClause;
81ec727ea7Spatrick class SVETypeFlags;
82ec727ea7Spatrick class OMPExecutableDirective;
83e5dd7070Spatrick 
84e5dd7070Spatrick namespace analyze_os_log {
85e5dd7070Spatrick class OSLogBufferLayout;
86e5dd7070Spatrick }
87e5dd7070Spatrick 
88e5dd7070Spatrick namespace CodeGen {
89e5dd7070Spatrick class CodeGenTypes;
90e5dd7070Spatrick class CGCallee;
91e5dd7070Spatrick class CGFunctionInfo;
92e5dd7070Spatrick class CGBlockInfo;
93e5dd7070Spatrick class CGCXXABI;
94e5dd7070Spatrick class BlockByrefHelpers;
95e5dd7070Spatrick class BlockByrefInfo;
96e5dd7070Spatrick class BlockFieldFlags;
97e5dd7070Spatrick class RegionCodeGenTy;
98e5dd7070Spatrick class TargetCodeGenInfo;
99e5dd7070Spatrick struct OMPTaskDataTy;
100e5dd7070Spatrick struct CGCoroData;
101e5dd7070Spatrick 
102e5dd7070Spatrick /// The kind of evaluation to perform on values of a particular
103e5dd7070Spatrick /// type.  Basically, is the code in CGExprScalar, CGExprComplex, or
104e5dd7070Spatrick /// CGExprAgg?
105e5dd7070Spatrick ///
106e5dd7070Spatrick /// TODO: should vectors maybe be split out into their own thing?
107e5dd7070Spatrick enum TypeEvaluationKind {
108e5dd7070Spatrick   TEK_Scalar,
109e5dd7070Spatrick   TEK_Complex,
110e5dd7070Spatrick   TEK_Aggregate
111e5dd7070Spatrick };
112e5dd7070Spatrick 
113e5dd7070Spatrick #define LIST_SANITIZER_CHECKS                                                  \
114e5dd7070Spatrick   SANITIZER_CHECK(AddOverflow, add_overflow, 0)                                \
115e5dd7070Spatrick   SANITIZER_CHECK(BuiltinUnreachable, builtin_unreachable, 0)                  \
116e5dd7070Spatrick   SANITIZER_CHECK(CFICheckFail, cfi_check_fail, 0)                             \
117e5dd7070Spatrick   SANITIZER_CHECK(DivremOverflow, divrem_overflow, 0)                          \
118e5dd7070Spatrick   SANITIZER_CHECK(DynamicTypeCacheMiss, dynamic_type_cache_miss, 0)            \
119e5dd7070Spatrick   SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0)                   \
120e5dd7070Spatrick   SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 1)             \
121e5dd7070Spatrick   SANITIZER_CHECK(ImplicitConversion, implicit_conversion, 0)                  \
122e5dd7070Spatrick   SANITIZER_CHECK(InvalidBuiltin, invalid_builtin, 0)                          \
123ec727ea7Spatrick   SANITIZER_CHECK(InvalidObjCCast, invalid_objc_cast, 0)                       \
124e5dd7070Spatrick   SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0)                     \
125e5dd7070Spatrick   SANITIZER_CHECK(MissingReturn, missing_return, 0)                            \
126e5dd7070Spatrick   SANITIZER_CHECK(MulOverflow, mul_overflow, 0)                                \
127e5dd7070Spatrick   SANITIZER_CHECK(NegateOverflow, negate_overflow, 0)                          \
128e5dd7070Spatrick   SANITIZER_CHECK(NullabilityArg, nullability_arg, 0)                          \
129e5dd7070Spatrick   SANITIZER_CHECK(NullabilityReturn, nullability_return, 1)                    \
130e5dd7070Spatrick   SANITIZER_CHECK(NonnullArg, nonnull_arg, 0)                                  \
131e5dd7070Spatrick   SANITIZER_CHECK(NonnullReturn, nonnull_return, 1)                            \
132e5dd7070Spatrick   SANITIZER_CHECK(OutOfBounds, out_of_bounds, 0)                               \
133e5dd7070Spatrick   SANITIZER_CHECK(PointerOverflow, pointer_overflow, 0)                        \
134e5dd7070Spatrick   SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0)                    \
135e5dd7070Spatrick   SANITIZER_CHECK(SubOverflow, sub_overflow, 0)                                \
136e5dd7070Spatrick   SANITIZER_CHECK(TypeMismatch, type_mismatch, 1)                              \
137e5dd7070Spatrick   SANITIZER_CHECK(AlignmentAssumption, alignment_assumption, 0)                \
138e5dd7070Spatrick   SANITIZER_CHECK(VLABoundNotPositive, vla_bound_not_positive, 0)
139e5dd7070Spatrick 
140e5dd7070Spatrick enum SanitizerHandler {
141e5dd7070Spatrick #define SANITIZER_CHECK(Enum, Name, Version) Enum,
142e5dd7070Spatrick   LIST_SANITIZER_CHECKS
143e5dd7070Spatrick #undef SANITIZER_CHECK
144e5dd7070Spatrick };
145e5dd7070Spatrick 
146e5dd7070Spatrick /// Helper class with most of the code for saving a value for a
147e5dd7070Spatrick /// conditional expression cleanup.
148e5dd7070Spatrick struct DominatingLLVMValue {
149e5dd7070Spatrick   typedef llvm::PointerIntPair<llvm::Value*, 1, bool> saved_type;
150e5dd7070Spatrick 
151e5dd7070Spatrick   /// Answer whether the given value needs extra work to be saved.
needsSavingDominatingLLVMValue152e5dd7070Spatrick   static bool needsSaving(llvm::Value *value) {
153e5dd7070Spatrick     // If it's not an instruction, we don't need to save.
154e5dd7070Spatrick     if (!isa<llvm::Instruction>(value)) return false;
155e5dd7070Spatrick 
156e5dd7070Spatrick     // If it's an instruction in the entry block, we don't need to save.
157e5dd7070Spatrick     llvm::BasicBlock *block = cast<llvm::Instruction>(value)->getParent();
158e5dd7070Spatrick     return (block != &block->getParent()->getEntryBlock());
159e5dd7070Spatrick   }
160e5dd7070Spatrick 
161e5dd7070Spatrick   static saved_type save(CodeGenFunction &CGF, llvm::Value *value);
162e5dd7070Spatrick   static llvm::Value *restore(CodeGenFunction &CGF, saved_type value);
163e5dd7070Spatrick };
164e5dd7070Spatrick 
165e5dd7070Spatrick /// A partial specialization of DominatingValue for llvm::Values that
166e5dd7070Spatrick /// might be llvm::Instructions.
167e5dd7070Spatrick template <class T> struct DominatingPointer<T,true> : DominatingLLVMValue {
168e5dd7070Spatrick   typedef T *type;
169e5dd7070Spatrick   static type restore(CodeGenFunction &CGF, saved_type value) {
170e5dd7070Spatrick     return static_cast<T*>(DominatingLLVMValue::restore(CGF, value));
171e5dd7070Spatrick   }
172e5dd7070Spatrick };
173e5dd7070Spatrick 
174e5dd7070Spatrick /// A specialization of DominatingValue for Address.
175e5dd7070Spatrick template <> struct DominatingValue<Address> {
176e5dd7070Spatrick   typedef Address type;
177e5dd7070Spatrick 
178e5dd7070Spatrick   struct saved_type {
179e5dd7070Spatrick     DominatingLLVMValue::saved_type SavedValue;
180*12c85518Srobert     llvm::Type *ElementType;
181e5dd7070Spatrick     CharUnits Alignment;
182e5dd7070Spatrick   };
183e5dd7070Spatrick 
184e5dd7070Spatrick   static bool needsSaving(type value) {
185e5dd7070Spatrick     return DominatingLLVMValue::needsSaving(value.getPointer());
186e5dd7070Spatrick   }
187e5dd7070Spatrick   static saved_type save(CodeGenFunction &CGF, type value) {
188e5dd7070Spatrick     return { DominatingLLVMValue::save(CGF, value.getPointer()),
189*12c85518Srobert              value.getElementType(), value.getAlignment() };
190e5dd7070Spatrick   }
191e5dd7070Spatrick   static type restore(CodeGenFunction &CGF, saved_type value) {
192e5dd7070Spatrick     return Address(DominatingLLVMValue::restore(CGF, value.SavedValue),
193*12c85518Srobert                    value.ElementType, value.Alignment);
194e5dd7070Spatrick   }
195e5dd7070Spatrick };
196e5dd7070Spatrick 
197e5dd7070Spatrick /// A specialization of DominatingValue for RValue.
198e5dd7070Spatrick template <> struct DominatingValue<RValue> {
199e5dd7070Spatrick   typedef RValue type;
200e5dd7070Spatrick   class saved_type {
201e5dd7070Spatrick     enum Kind { ScalarLiteral, ScalarAddress, AggregateLiteral,
202e5dd7070Spatrick                 AggregateAddress, ComplexAddress };
203e5dd7070Spatrick 
204e5dd7070Spatrick     llvm::Value *Value;
205*12c85518Srobert     llvm::Type *ElementType;
206e5dd7070Spatrick     unsigned K : 3;
207e5dd7070Spatrick     unsigned Align : 29;
208*12c85518Srobert     saved_type(llvm::Value *v, llvm::Type *e, Kind k, unsigned a = 0)
209*12c85518Srobert       : Value(v), ElementType(e), K(k), Align(a) {}
210e5dd7070Spatrick 
211e5dd7070Spatrick   public:
212e5dd7070Spatrick     static bool needsSaving(RValue value);
213e5dd7070Spatrick     static saved_type save(CodeGenFunction &CGF, RValue value);
214e5dd7070Spatrick     RValue restore(CodeGenFunction &CGF);
215e5dd7070Spatrick 
216e5dd7070Spatrick     // implementations in CGCleanup.cpp
217e5dd7070Spatrick   };
218e5dd7070Spatrick 
219e5dd7070Spatrick   static bool needsSaving(type value) {
220e5dd7070Spatrick     return saved_type::needsSaving(value);
221e5dd7070Spatrick   }
222e5dd7070Spatrick   static saved_type save(CodeGenFunction &CGF, type value) {
223e5dd7070Spatrick     return saved_type::save(CGF, value);
224e5dd7070Spatrick   }
225e5dd7070Spatrick   static type restore(CodeGenFunction &CGF, saved_type value) {
226e5dd7070Spatrick     return value.restore(CGF);
227e5dd7070Spatrick   }
228e5dd7070Spatrick };
229e5dd7070Spatrick 
230e5dd7070Spatrick /// CodeGenFunction - This class organizes the per-function state that is used
231e5dd7070Spatrick /// while generating LLVM code.
232e5dd7070Spatrick class CodeGenFunction : public CodeGenTypeCache {
233e5dd7070Spatrick   CodeGenFunction(const CodeGenFunction &) = delete;
234e5dd7070Spatrick   void operator=(const CodeGenFunction &) = delete;
235e5dd7070Spatrick 
236e5dd7070Spatrick   friend class CGCXXABI;
237e5dd7070Spatrick public:
238e5dd7070Spatrick   /// A jump destination is an abstract label, branching to which may
239e5dd7070Spatrick   /// require a jump out through normal cleanups.
240e5dd7070Spatrick   struct JumpDest {
241*12c85518Srobert     JumpDest() : Block(nullptr), Index(0) {}
242*12c85518Srobert     JumpDest(llvm::BasicBlock *Block, EHScopeStack::stable_iterator Depth,
243e5dd7070Spatrick              unsigned Index)
244e5dd7070Spatrick         : Block(Block), ScopeDepth(Depth), Index(Index) {}
245e5dd7070Spatrick 
246e5dd7070Spatrick     bool isValid() const { return Block != nullptr; }
247e5dd7070Spatrick     llvm::BasicBlock *getBlock() const { return Block; }
248e5dd7070Spatrick     EHScopeStack::stable_iterator getScopeDepth() const { return ScopeDepth; }
249e5dd7070Spatrick     unsigned getDestIndex() const { return Index; }
250e5dd7070Spatrick 
251e5dd7070Spatrick     // This should be used cautiously.
252e5dd7070Spatrick     void setScopeDepth(EHScopeStack::stable_iterator depth) {
253e5dd7070Spatrick       ScopeDepth = depth;
254e5dd7070Spatrick     }
255e5dd7070Spatrick 
256e5dd7070Spatrick   private:
257e5dd7070Spatrick     llvm::BasicBlock *Block;
258e5dd7070Spatrick     EHScopeStack::stable_iterator ScopeDepth;
259e5dd7070Spatrick     unsigned Index;
260e5dd7070Spatrick   };
261e5dd7070Spatrick 
262e5dd7070Spatrick   CodeGenModule &CGM;  // Per-module state.
263e5dd7070Spatrick   const TargetInfo &Target;
264e5dd7070Spatrick 
265ec727ea7Spatrick   // For EH/SEH outlined funclets, this field points to parent's CGF
266ec727ea7Spatrick   CodeGenFunction *ParentCGF = nullptr;
267ec727ea7Spatrick 
268e5dd7070Spatrick   typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
269e5dd7070Spatrick   LoopInfoStack LoopStack;
270e5dd7070Spatrick   CGBuilderTy Builder;
271e5dd7070Spatrick 
272e5dd7070Spatrick   // Stores variables for which we can't generate correct lifetime markers
273e5dd7070Spatrick   // because of jumps.
274e5dd7070Spatrick   VarBypassDetector Bypasses;
275e5dd7070Spatrick 
276a9ac8606Spatrick   /// List of recently emitted OMPCanonicalLoops.
277a9ac8606Spatrick   ///
278a9ac8606Spatrick   /// Since OMPCanonicalLoops are nested inside other statements (in particular
279a9ac8606Spatrick   /// CapturedStmt generated by OMPExecutableDirective and non-perfectly nested
280a9ac8606Spatrick   /// loops), we cannot directly call OMPEmitOMPCanonicalLoop and receive its
281a9ac8606Spatrick   /// llvm::CanonicalLoopInfo. Instead, we call EmitStmt and any
282a9ac8606Spatrick   /// OMPEmitOMPCanonicalLoop called by it will add its CanonicalLoopInfo to
283a9ac8606Spatrick   /// this stack when done. Entering a new loop requires clearing this list; it
284a9ac8606Spatrick   /// either means we start parsing a new loop nest (in which case the previous
285a9ac8606Spatrick   /// loop nest goes out of scope) or a second loop in the same level in which
286a9ac8606Spatrick   /// case it would be ambiguous into which of the two (or more) loops the loop
287a9ac8606Spatrick   /// nest would extend.
288a9ac8606Spatrick   SmallVector<llvm::CanonicalLoopInfo *, 4> OMPLoopNestStack;
289a9ac8606Spatrick 
290*12c85518Srobert   /// Number of nested loop to be consumed by the last surrounding
291*12c85518Srobert   /// loop-associated directive.
292*12c85518Srobert   int ExpectedOMPLoopDepth = 0;
293*12c85518Srobert 
294e5dd7070Spatrick   // CodeGen lambda for loops and support for ordered clause
295e5dd7070Spatrick   typedef llvm::function_ref<void(CodeGenFunction &, const OMPLoopDirective &,
296e5dd7070Spatrick                                   JumpDest)>
297e5dd7070Spatrick       CodeGenLoopTy;
298e5dd7070Spatrick   typedef llvm::function_ref<void(CodeGenFunction &, SourceLocation,
299e5dd7070Spatrick                                   const unsigned, const bool)>
300e5dd7070Spatrick       CodeGenOrderedTy;
301e5dd7070Spatrick 
302e5dd7070Spatrick   // Codegen lambda for loop bounds in worksharing loop constructs
303e5dd7070Spatrick   typedef llvm::function_ref<std::pair<LValue, LValue>(
304e5dd7070Spatrick       CodeGenFunction &, const OMPExecutableDirective &S)>
305e5dd7070Spatrick       CodeGenLoopBoundsTy;
306e5dd7070Spatrick 
307e5dd7070Spatrick   // Codegen lambda for loop bounds in dispatch-based loop implementation
308e5dd7070Spatrick   typedef llvm::function_ref<std::pair<llvm::Value *, llvm::Value *>(
309e5dd7070Spatrick       CodeGenFunction &, const OMPExecutableDirective &S, Address LB,
310e5dd7070Spatrick       Address UB)>
311e5dd7070Spatrick       CodeGenDispatchBoundsTy;
312e5dd7070Spatrick 
313e5dd7070Spatrick   /// CGBuilder insert helper. This function is called after an
314e5dd7070Spatrick   /// instruction is created using Builder.
315e5dd7070Spatrick   void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
316e5dd7070Spatrick                     llvm::BasicBlock *BB,
317e5dd7070Spatrick                     llvm::BasicBlock::iterator InsertPt) const;
318e5dd7070Spatrick 
319e5dd7070Spatrick   /// CurFuncDecl - Holds the Decl for the current outermost
320e5dd7070Spatrick   /// non-closure context.
321e5dd7070Spatrick   const Decl *CurFuncDecl;
322e5dd7070Spatrick   /// CurCodeDecl - This is the inner-most code context, which includes blocks.
323e5dd7070Spatrick   const Decl *CurCodeDecl;
324e5dd7070Spatrick   const CGFunctionInfo *CurFnInfo;
325e5dd7070Spatrick   QualType FnRetTy;
326e5dd7070Spatrick   llvm::Function *CurFn = nullptr;
327e5dd7070Spatrick 
328a9ac8606Spatrick   /// Save Parameter Decl for coroutine.
329a9ac8606Spatrick   llvm::SmallVector<const ParmVarDecl *, 4> FnArgs;
330a9ac8606Spatrick 
331e5dd7070Spatrick   // Holds coroutine data if the current function is a coroutine. We use a
332e5dd7070Spatrick   // wrapper to manage its lifetime, so that we don't have to define CGCoroData
333e5dd7070Spatrick   // in this header.
334e5dd7070Spatrick   struct CGCoroInfo {
335e5dd7070Spatrick     std::unique_ptr<CGCoroData> Data;
336e5dd7070Spatrick     CGCoroInfo();
337e5dd7070Spatrick     ~CGCoroInfo();
338e5dd7070Spatrick   };
339e5dd7070Spatrick   CGCoroInfo CurCoro;
340e5dd7070Spatrick 
341e5dd7070Spatrick   bool isCoroutine() const {
342e5dd7070Spatrick     return CurCoro.Data != nullptr;
343e5dd7070Spatrick   }
344e5dd7070Spatrick 
345e5dd7070Spatrick   /// CurGD - The GlobalDecl for the current function being compiled.
346e5dd7070Spatrick   GlobalDecl CurGD;
347e5dd7070Spatrick 
348e5dd7070Spatrick   /// PrologueCleanupDepth - The cleanup depth enclosing all the
349e5dd7070Spatrick   /// cleanups associated with the parameters.
350e5dd7070Spatrick   EHScopeStack::stable_iterator PrologueCleanupDepth;
351e5dd7070Spatrick 
352e5dd7070Spatrick   /// ReturnBlock - Unified return block.
353e5dd7070Spatrick   JumpDest ReturnBlock;
354e5dd7070Spatrick 
355e5dd7070Spatrick   /// ReturnValue - The temporary alloca to hold the return
356e5dd7070Spatrick   /// value. This is invalid iff the function has no return value.
357e5dd7070Spatrick   Address ReturnValue = Address::invalid();
358e5dd7070Spatrick 
359e5dd7070Spatrick   /// ReturnValuePointer - The temporary alloca to hold a pointer to sret.
360e5dd7070Spatrick   /// This is invalid if sret is not in use.
361e5dd7070Spatrick   Address ReturnValuePointer = Address::invalid();
362e5dd7070Spatrick 
363ec727ea7Spatrick   /// If a return statement is being visited, this holds the return statment's
364ec727ea7Spatrick   /// result expression.
365ec727ea7Spatrick   const Expr *RetExpr = nullptr;
366ec727ea7Spatrick 
367e5dd7070Spatrick   /// Return true if a label was seen in the current scope.
368e5dd7070Spatrick   bool hasLabelBeenSeenInCurrentScope() const {
369e5dd7070Spatrick     if (CurLexicalScope)
370e5dd7070Spatrick       return CurLexicalScope->hasLabels();
371e5dd7070Spatrick     return !LabelMap.empty();
372e5dd7070Spatrick   }
373e5dd7070Spatrick 
374e5dd7070Spatrick   /// AllocaInsertPoint - This is an instruction in the entry block before which
375e5dd7070Spatrick   /// we prefer to insert allocas.
376e5dd7070Spatrick   llvm::AssertingVH<llvm::Instruction> AllocaInsertPt;
377e5dd7070Spatrick 
378*12c85518Srobert private:
379*12c85518Srobert   /// PostAllocaInsertPt - This is a place in the prologue where code can be
380*12c85518Srobert   /// inserted that will be dominated by all the static allocas. This helps
381*12c85518Srobert   /// achieve two things:
382*12c85518Srobert   ///   1. Contiguity of all static allocas (within the prologue) is maintained.
383*12c85518Srobert   ///   2. All other prologue code (which are dominated by static allocas) do
384*12c85518Srobert   ///      appear in the source order immediately after all static allocas.
385*12c85518Srobert   ///
386*12c85518Srobert   /// PostAllocaInsertPt will be lazily created when it is *really* required.
387*12c85518Srobert   llvm::AssertingVH<llvm::Instruction> PostAllocaInsertPt = nullptr;
388*12c85518Srobert 
389*12c85518Srobert public:
390*12c85518Srobert   /// Return PostAllocaInsertPt. If it is not yet created, then insert it
391*12c85518Srobert   /// immediately after AllocaInsertPt.
392*12c85518Srobert   llvm::Instruction *getPostAllocaInsertPoint() {
393*12c85518Srobert     if (!PostAllocaInsertPt) {
394*12c85518Srobert       assert(AllocaInsertPt &&
395*12c85518Srobert              "Expected static alloca insertion point at function prologue");
396*12c85518Srobert       assert(AllocaInsertPt->getParent()->isEntryBlock() &&
397*12c85518Srobert              "EBB should be entry block of the current code gen function");
398*12c85518Srobert       PostAllocaInsertPt = AllocaInsertPt->clone();
399*12c85518Srobert       PostAllocaInsertPt->setName("postallocapt");
400*12c85518Srobert       PostAllocaInsertPt->insertAfter(AllocaInsertPt);
401*12c85518Srobert     }
402*12c85518Srobert 
403*12c85518Srobert     return PostAllocaInsertPt;
404*12c85518Srobert   }
405*12c85518Srobert 
406e5dd7070Spatrick   /// API for captured statement code generation.
407e5dd7070Spatrick   class CGCapturedStmtInfo {
408e5dd7070Spatrick   public:
409e5dd7070Spatrick     explicit CGCapturedStmtInfo(CapturedRegionKind K = CR_Default)
410e5dd7070Spatrick         : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {}
411e5dd7070Spatrick     explicit CGCapturedStmtInfo(const CapturedStmt &S,
412e5dd7070Spatrick                                 CapturedRegionKind K = CR_Default)
413e5dd7070Spatrick       : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {
414e5dd7070Spatrick 
415e5dd7070Spatrick       RecordDecl::field_iterator Field =
416e5dd7070Spatrick         S.getCapturedRecordDecl()->field_begin();
417e5dd7070Spatrick       for (CapturedStmt::const_capture_iterator I = S.capture_begin(),
418e5dd7070Spatrick                                                 E = S.capture_end();
419e5dd7070Spatrick            I != E; ++I, ++Field) {
420e5dd7070Spatrick         if (I->capturesThis())
421e5dd7070Spatrick           CXXThisFieldDecl = *Field;
422e5dd7070Spatrick         else if (I->capturesVariable())
423e5dd7070Spatrick           CaptureFields[I->getCapturedVar()->getCanonicalDecl()] = *Field;
424e5dd7070Spatrick         else if (I->capturesVariableByCopy())
425e5dd7070Spatrick           CaptureFields[I->getCapturedVar()->getCanonicalDecl()] = *Field;
426e5dd7070Spatrick       }
427e5dd7070Spatrick     }
428e5dd7070Spatrick 
429e5dd7070Spatrick     virtual ~CGCapturedStmtInfo();
430e5dd7070Spatrick 
431e5dd7070Spatrick     CapturedRegionKind getKind() const { return Kind; }
432e5dd7070Spatrick 
433e5dd7070Spatrick     virtual void setContextValue(llvm::Value *V) { ThisValue = V; }
434e5dd7070Spatrick     // Retrieve the value of the context parameter.
435e5dd7070Spatrick     virtual llvm::Value *getContextValue() const { return ThisValue; }
436e5dd7070Spatrick 
437e5dd7070Spatrick     /// Lookup the captured field decl for a variable.
438e5dd7070Spatrick     virtual const FieldDecl *lookup(const VarDecl *VD) const {
439e5dd7070Spatrick       return CaptureFields.lookup(VD->getCanonicalDecl());
440e5dd7070Spatrick     }
441e5dd7070Spatrick 
442e5dd7070Spatrick     bool isCXXThisExprCaptured() const { return getThisFieldDecl() != nullptr; }
443e5dd7070Spatrick     virtual FieldDecl *getThisFieldDecl() const { return CXXThisFieldDecl; }
444e5dd7070Spatrick 
445e5dd7070Spatrick     static bool classof(const CGCapturedStmtInfo *) {
446e5dd7070Spatrick       return true;
447e5dd7070Spatrick     }
448e5dd7070Spatrick 
449e5dd7070Spatrick     /// Emit the captured statement body.
450e5dd7070Spatrick     virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S) {
451e5dd7070Spatrick       CGF.incrementProfileCounter(S);
452e5dd7070Spatrick       CGF.EmitStmt(S);
453e5dd7070Spatrick     }
454e5dd7070Spatrick 
455e5dd7070Spatrick     /// Get the name of the capture helper.
456e5dd7070Spatrick     virtual StringRef getHelperName() const { return "__captured_stmt"; }
457e5dd7070Spatrick 
458*12c85518Srobert     /// Get the CaptureFields
459*12c85518Srobert     llvm::SmallDenseMap<const VarDecl *, FieldDecl *> getCaptureFields() {
460*12c85518Srobert       return CaptureFields;
461*12c85518Srobert     }
462*12c85518Srobert 
463e5dd7070Spatrick   private:
464e5dd7070Spatrick     /// The kind of captured statement being generated.
465e5dd7070Spatrick     CapturedRegionKind Kind;
466e5dd7070Spatrick 
467e5dd7070Spatrick     /// Keep the map between VarDecl and FieldDecl.
468e5dd7070Spatrick     llvm::SmallDenseMap<const VarDecl *, FieldDecl *> CaptureFields;
469e5dd7070Spatrick 
470e5dd7070Spatrick     /// The base address of the captured record, passed in as the first
471e5dd7070Spatrick     /// argument of the parallel region function.
472e5dd7070Spatrick     llvm::Value *ThisValue;
473e5dd7070Spatrick 
474e5dd7070Spatrick     /// Captured 'this' type.
475e5dd7070Spatrick     FieldDecl *CXXThisFieldDecl;
476e5dd7070Spatrick   };
477e5dd7070Spatrick   CGCapturedStmtInfo *CapturedStmtInfo = nullptr;
478e5dd7070Spatrick 
479e5dd7070Spatrick   /// RAII for correct setting/restoring of CapturedStmtInfo.
480e5dd7070Spatrick   class CGCapturedStmtRAII {
481e5dd7070Spatrick   private:
482e5dd7070Spatrick     CodeGenFunction &CGF;
483e5dd7070Spatrick     CGCapturedStmtInfo *PrevCapturedStmtInfo;
484e5dd7070Spatrick   public:
485e5dd7070Spatrick     CGCapturedStmtRAII(CodeGenFunction &CGF,
486e5dd7070Spatrick                        CGCapturedStmtInfo *NewCapturedStmtInfo)
487e5dd7070Spatrick         : CGF(CGF), PrevCapturedStmtInfo(CGF.CapturedStmtInfo) {
488e5dd7070Spatrick       CGF.CapturedStmtInfo = NewCapturedStmtInfo;
489e5dd7070Spatrick     }
490e5dd7070Spatrick     ~CGCapturedStmtRAII() { CGF.CapturedStmtInfo = PrevCapturedStmtInfo; }
491e5dd7070Spatrick   };
492e5dd7070Spatrick 
493e5dd7070Spatrick   /// An abstract representation of regular/ObjC call/message targets.
494e5dd7070Spatrick   class AbstractCallee {
495e5dd7070Spatrick     /// The function declaration of the callee.
496e5dd7070Spatrick     const Decl *CalleeDecl;
497e5dd7070Spatrick 
498e5dd7070Spatrick   public:
499e5dd7070Spatrick     AbstractCallee() : CalleeDecl(nullptr) {}
500e5dd7070Spatrick     AbstractCallee(const FunctionDecl *FD) : CalleeDecl(FD) {}
501e5dd7070Spatrick     AbstractCallee(const ObjCMethodDecl *OMD) : CalleeDecl(OMD) {}
502e5dd7070Spatrick     bool hasFunctionDecl() const {
503*12c85518Srobert       return isa_and_nonnull<FunctionDecl>(CalleeDecl);
504e5dd7070Spatrick     }
505e5dd7070Spatrick     const Decl *getDecl() const { return CalleeDecl; }
506e5dd7070Spatrick     unsigned getNumParams() const {
507e5dd7070Spatrick       if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl))
508e5dd7070Spatrick         return FD->getNumParams();
509e5dd7070Spatrick       return cast<ObjCMethodDecl>(CalleeDecl)->param_size();
510e5dd7070Spatrick     }
511e5dd7070Spatrick     const ParmVarDecl *getParamDecl(unsigned I) const {
512e5dd7070Spatrick       if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl))
513e5dd7070Spatrick         return FD->getParamDecl(I);
514e5dd7070Spatrick       return *(cast<ObjCMethodDecl>(CalleeDecl)->param_begin() + I);
515e5dd7070Spatrick     }
516e5dd7070Spatrick   };
517e5dd7070Spatrick 
518e5dd7070Spatrick   /// Sanitizers enabled for this function.
519e5dd7070Spatrick   SanitizerSet SanOpts;
520e5dd7070Spatrick 
521e5dd7070Spatrick   /// True if CodeGen currently emits code implementing sanitizer checks.
522e5dd7070Spatrick   bool IsSanitizerScope = false;
523e5dd7070Spatrick 
524e5dd7070Spatrick   /// RAII object to set/unset CodeGenFunction::IsSanitizerScope.
525e5dd7070Spatrick   class SanitizerScope {
526e5dd7070Spatrick     CodeGenFunction *CGF;
527e5dd7070Spatrick   public:
528e5dd7070Spatrick     SanitizerScope(CodeGenFunction *CGF);
529e5dd7070Spatrick     ~SanitizerScope();
530e5dd7070Spatrick   };
531e5dd7070Spatrick 
532e5dd7070Spatrick   /// In C++, whether we are code generating a thunk.  This controls whether we
533e5dd7070Spatrick   /// should emit cleanups.
534e5dd7070Spatrick   bool CurFuncIsThunk = false;
535e5dd7070Spatrick 
536e5dd7070Spatrick   /// In ARC, whether we should autorelease the return value.
537e5dd7070Spatrick   bool AutoreleaseResult = false;
538e5dd7070Spatrick 
539e5dd7070Spatrick   /// Whether we processed a Microsoft-style asm block during CodeGen. These can
540e5dd7070Spatrick   /// potentially set the return value.
541e5dd7070Spatrick   bool SawAsmBlock = false;
542e5dd7070Spatrick 
543*12c85518Srobert   GlobalDecl CurSEHParent;
544e5dd7070Spatrick 
545e5dd7070Spatrick   /// True if the current function is an outlined SEH helper. This can be a
546e5dd7070Spatrick   /// finally block or filter expression.
547e5dd7070Spatrick   bool IsOutlinedSEHHelper = false;
548e5dd7070Spatrick 
549e5dd7070Spatrick   /// True if CodeGen currently emits code inside presereved access index
550e5dd7070Spatrick   /// region.
551e5dd7070Spatrick   bool IsInPreservedAIRegion = false;
552e5dd7070Spatrick 
553ec727ea7Spatrick   /// True if the current statement has nomerge attribute.
554ec727ea7Spatrick   bool InNoMergeAttributedStmt = false;
555ec727ea7Spatrick 
556*12c85518Srobert   /// True if the current statement has noinline attribute.
557*12c85518Srobert   bool InNoInlineAttributedStmt = false;
558*12c85518Srobert 
559*12c85518Srobert   /// True if the current statement has always_inline attribute.
560*12c85518Srobert   bool InAlwaysInlineAttributedStmt = false;
561*12c85518Srobert 
562a9ac8606Spatrick   // The CallExpr within the current statement that the musttail attribute
563a9ac8606Spatrick   // applies to.  nullptr if there is no 'musttail' on the current statement.
564a9ac8606Spatrick   const CallExpr *MustTailCall = nullptr;
565a9ac8606Spatrick 
566a9ac8606Spatrick   /// Returns true if a function must make progress, which means the
567a9ac8606Spatrick   /// mustprogress attribute can be added.
568a9ac8606Spatrick   bool checkIfFunctionMustProgress() {
569a9ac8606Spatrick     if (CGM.getCodeGenOpts().getFiniteLoops() ==
570a9ac8606Spatrick         CodeGenOptions::FiniteLoopsKind::Never)
571a9ac8606Spatrick       return false;
572a9ac8606Spatrick 
573a9ac8606Spatrick     // C++11 and later guarantees that a thread eventually will do one of the
574*12c85518Srobert     // following (C++11 [intro.multithread]p24 and C++17 [intro.progress]p1):
575a9ac8606Spatrick     // - terminate,
576a9ac8606Spatrick     //  - make a call to a library I/O function,
577a9ac8606Spatrick     //  - perform an access through a volatile glvalue, or
578a9ac8606Spatrick     //  - perform a synchronization operation or an atomic operation.
579a9ac8606Spatrick     //
580a9ac8606Spatrick     // Hence each function is 'mustprogress' in C++11 or later.
581a9ac8606Spatrick     return getLangOpts().CPlusPlus11;
582a9ac8606Spatrick   }
583a9ac8606Spatrick 
584a9ac8606Spatrick   /// Returns true if a loop must make progress, which means the mustprogress
585a9ac8606Spatrick   /// attribute can be added. \p HasConstantCond indicates whether the branch
586a9ac8606Spatrick   /// condition is a known constant.
587a9ac8606Spatrick   bool checkIfLoopMustProgress(bool HasConstantCond) {
588a9ac8606Spatrick     if (CGM.getCodeGenOpts().getFiniteLoops() ==
589a9ac8606Spatrick         CodeGenOptions::FiniteLoopsKind::Always)
590a9ac8606Spatrick       return true;
591a9ac8606Spatrick     if (CGM.getCodeGenOpts().getFiniteLoops() ==
592a9ac8606Spatrick         CodeGenOptions::FiniteLoopsKind::Never)
593a9ac8606Spatrick       return false;
594a9ac8606Spatrick 
595a9ac8606Spatrick     // If the containing function must make progress, loops also must make
596a9ac8606Spatrick     // progress (as in C++11 and later).
597a9ac8606Spatrick     if (checkIfFunctionMustProgress())
598a9ac8606Spatrick       return true;
599a9ac8606Spatrick 
600a9ac8606Spatrick     // Now apply rules for plain C (see  6.8.5.6 in C11).
601a9ac8606Spatrick     // Loops with constant conditions do not have to make progress in any C
602a9ac8606Spatrick     // version.
603a9ac8606Spatrick     if (HasConstantCond)
604a9ac8606Spatrick       return false;
605a9ac8606Spatrick 
606a9ac8606Spatrick     // Loops with non-constant conditions must make progress in C11 and later.
607a9ac8606Spatrick     return getLangOpts().C11;
608a9ac8606Spatrick   }
609a9ac8606Spatrick 
610e5dd7070Spatrick   const CodeGen::CGBlockInfo *BlockInfo = nullptr;
611e5dd7070Spatrick   llvm::Value *BlockPointer = nullptr;
612e5dd7070Spatrick 
613*12c85518Srobert   llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
614e5dd7070Spatrick   FieldDecl *LambdaThisCaptureField = nullptr;
615e5dd7070Spatrick 
616e5dd7070Spatrick   /// A mapping from NRVO variables to the flags used to indicate
617e5dd7070Spatrick   /// when the NRVO has been applied to this variable.
618e5dd7070Spatrick   llvm::DenseMap<const VarDecl *, llvm::Value *> NRVOFlags;
619e5dd7070Spatrick 
620e5dd7070Spatrick   EHScopeStack EHStack;
621e5dd7070Spatrick   llvm::SmallVector<char, 256> LifetimeExtendedCleanupStack;
622e5dd7070Spatrick   llvm::SmallVector<const JumpDest *, 2> SEHTryEpilogueStack;
623e5dd7070Spatrick 
624e5dd7070Spatrick   llvm::Instruction *CurrentFuncletPad = nullptr;
625e5dd7070Spatrick 
626e5dd7070Spatrick   class CallLifetimeEnd final : public EHScopeStack::Cleanup {
627a9ac8606Spatrick     bool isRedundantBeforeReturn() override { return true; }
628a9ac8606Spatrick 
629e5dd7070Spatrick     llvm::Value *Addr;
630e5dd7070Spatrick     llvm::Value *Size;
631e5dd7070Spatrick 
632e5dd7070Spatrick   public:
633e5dd7070Spatrick     CallLifetimeEnd(Address addr, llvm::Value *size)
634e5dd7070Spatrick         : Addr(addr.getPointer()), Size(size) {}
635e5dd7070Spatrick 
636e5dd7070Spatrick     void Emit(CodeGenFunction &CGF, Flags flags) override {
637e5dd7070Spatrick       CGF.EmitLifetimeEnd(Size, Addr);
638e5dd7070Spatrick     }
639e5dd7070Spatrick   };
640e5dd7070Spatrick 
641e5dd7070Spatrick   /// Header for data within LifetimeExtendedCleanupStack.
642e5dd7070Spatrick   struct LifetimeExtendedCleanupHeader {
643e5dd7070Spatrick     /// The size of the following cleanup object.
644e5dd7070Spatrick     unsigned Size;
645e5dd7070Spatrick     /// The kind of cleanup to push: a value from the CleanupKind enumeration.
646e5dd7070Spatrick     unsigned Kind : 31;
647e5dd7070Spatrick     /// Whether this is a conditional cleanup.
648e5dd7070Spatrick     unsigned IsConditional : 1;
649e5dd7070Spatrick 
650e5dd7070Spatrick     size_t getSize() const { return Size; }
651e5dd7070Spatrick     CleanupKind getKind() const { return (CleanupKind)Kind; }
652e5dd7070Spatrick     bool isConditional() const { return IsConditional; }
653e5dd7070Spatrick   };
654e5dd7070Spatrick 
655e5dd7070Spatrick   /// i32s containing the indexes of the cleanup destinations.
656e5dd7070Spatrick   Address NormalCleanupDest = Address::invalid();
657e5dd7070Spatrick 
658e5dd7070Spatrick   unsigned NextCleanupDestIndex = 1;
659e5dd7070Spatrick 
660e5dd7070Spatrick   /// EHResumeBlock - Unified block containing a call to llvm.eh.resume.
661e5dd7070Spatrick   llvm::BasicBlock *EHResumeBlock = nullptr;
662e5dd7070Spatrick 
663e5dd7070Spatrick   /// The exception slot.  All landing pads write the current exception pointer
664e5dd7070Spatrick   /// into this alloca.
665e5dd7070Spatrick   llvm::Value *ExceptionSlot = nullptr;
666e5dd7070Spatrick 
667e5dd7070Spatrick   /// The selector slot.  Under the MandatoryCleanup model, all landing pads
668e5dd7070Spatrick   /// write the current selector value into this alloca.
669e5dd7070Spatrick   llvm::AllocaInst *EHSelectorSlot = nullptr;
670e5dd7070Spatrick 
671e5dd7070Spatrick   /// A stack of exception code slots. Entering an __except block pushes a slot
672e5dd7070Spatrick   /// on the stack and leaving pops one. The __exception_code() intrinsic loads
673e5dd7070Spatrick   /// a value from the top of the stack.
674e5dd7070Spatrick   SmallVector<Address, 1> SEHCodeSlotStack;
675e5dd7070Spatrick 
676e5dd7070Spatrick   /// Value returned by __exception_info intrinsic.
677e5dd7070Spatrick   llvm::Value *SEHInfo = nullptr;
678e5dd7070Spatrick 
679e5dd7070Spatrick   /// Emits a landing pad for the current EH stack.
680e5dd7070Spatrick   llvm::BasicBlock *EmitLandingPad();
681e5dd7070Spatrick 
682e5dd7070Spatrick   llvm::BasicBlock *getInvokeDestImpl();
683e5dd7070Spatrick 
684ec727ea7Spatrick   /// Parent loop-based directive for scan directive.
685ec727ea7Spatrick   const OMPExecutableDirective *OMPParentLoopDirectiveForScan = nullptr;
686ec727ea7Spatrick   llvm::BasicBlock *OMPBeforeScanBlock = nullptr;
687ec727ea7Spatrick   llvm::BasicBlock *OMPAfterScanBlock = nullptr;
688ec727ea7Spatrick   llvm::BasicBlock *OMPScanExitBlock = nullptr;
689ec727ea7Spatrick   llvm::BasicBlock *OMPScanDispatch = nullptr;
690ec727ea7Spatrick   bool OMPFirstScanLoop = false;
691ec727ea7Spatrick 
692ec727ea7Spatrick   /// Manages parent directive for scan directives.
693ec727ea7Spatrick   class ParentLoopDirectiveForScanRegion {
694ec727ea7Spatrick     CodeGenFunction &CGF;
695ec727ea7Spatrick     const OMPExecutableDirective *ParentLoopDirectiveForScan;
696ec727ea7Spatrick 
697ec727ea7Spatrick   public:
698ec727ea7Spatrick     ParentLoopDirectiveForScanRegion(
699ec727ea7Spatrick         CodeGenFunction &CGF,
700ec727ea7Spatrick         const OMPExecutableDirective &ParentLoopDirectiveForScan)
701ec727ea7Spatrick         : CGF(CGF),
702ec727ea7Spatrick           ParentLoopDirectiveForScan(CGF.OMPParentLoopDirectiveForScan) {
703ec727ea7Spatrick       CGF.OMPParentLoopDirectiveForScan = &ParentLoopDirectiveForScan;
704ec727ea7Spatrick     }
705ec727ea7Spatrick     ~ParentLoopDirectiveForScanRegion() {
706ec727ea7Spatrick       CGF.OMPParentLoopDirectiveForScan = ParentLoopDirectiveForScan;
707ec727ea7Spatrick     }
708ec727ea7Spatrick   };
709ec727ea7Spatrick 
710e5dd7070Spatrick   template <class T>
711e5dd7070Spatrick   typename DominatingValue<T>::saved_type saveValueInCond(T value) {
712e5dd7070Spatrick     return DominatingValue<T>::save(*this, value);
713e5dd7070Spatrick   }
714e5dd7070Spatrick 
715ec727ea7Spatrick   class CGFPOptionsRAII {
716ec727ea7Spatrick   public:
717ec727ea7Spatrick     CGFPOptionsRAII(CodeGenFunction &CGF, FPOptions FPFeatures);
718a9ac8606Spatrick     CGFPOptionsRAII(CodeGenFunction &CGF, const Expr *E);
719ec727ea7Spatrick     ~CGFPOptionsRAII();
720ec727ea7Spatrick 
721ec727ea7Spatrick   private:
722a9ac8606Spatrick     void ConstructorHelper(FPOptions FPFeatures);
723ec727ea7Spatrick     CodeGenFunction &CGF;
724ec727ea7Spatrick     FPOptions OldFPFeatures;
725a9ac8606Spatrick     llvm::fp::ExceptionBehavior OldExcept;
726a9ac8606Spatrick     llvm::RoundingMode OldRounding;
727*12c85518Srobert     std::optional<CGBuilderTy::FastMathFlagGuard> FMFGuard;
728ec727ea7Spatrick   };
729ec727ea7Spatrick   FPOptions CurFPFeatures;
730ec727ea7Spatrick 
731e5dd7070Spatrick public:
732e5dd7070Spatrick   /// ObjCEHValueStack - Stack of Objective-C exception values, used for
733e5dd7070Spatrick   /// rethrows.
734e5dd7070Spatrick   SmallVector<llvm::Value*, 8> ObjCEHValueStack;
735e5dd7070Spatrick 
736e5dd7070Spatrick   /// A class controlling the emission of a finally block.
737e5dd7070Spatrick   class FinallyInfo {
738e5dd7070Spatrick     /// Where the catchall's edge through the cleanup should go.
739e5dd7070Spatrick     JumpDest RethrowDest;
740e5dd7070Spatrick 
741e5dd7070Spatrick     /// A function to call to enter the catch.
742e5dd7070Spatrick     llvm::FunctionCallee BeginCatchFn;
743e5dd7070Spatrick 
744e5dd7070Spatrick     /// An i1 variable indicating whether or not the @finally is
745e5dd7070Spatrick     /// running for an exception.
746e5dd7070Spatrick     llvm::AllocaInst *ForEHVar;
747e5dd7070Spatrick 
748e5dd7070Spatrick     /// An i8* variable into which the exception pointer to rethrow
749e5dd7070Spatrick     /// has been saved.
750e5dd7070Spatrick     llvm::AllocaInst *SavedExnVar;
751e5dd7070Spatrick 
752e5dd7070Spatrick   public:
753e5dd7070Spatrick     void enter(CodeGenFunction &CGF, const Stmt *Finally,
754e5dd7070Spatrick                llvm::FunctionCallee beginCatchFn,
755e5dd7070Spatrick                llvm::FunctionCallee endCatchFn, llvm::FunctionCallee rethrowFn);
756e5dd7070Spatrick     void exit(CodeGenFunction &CGF);
757e5dd7070Spatrick   };
758e5dd7070Spatrick 
759e5dd7070Spatrick   /// Returns true inside SEH __try blocks.
760e5dd7070Spatrick   bool isSEHTryScope() const { return !SEHTryEpilogueStack.empty(); }
761e5dd7070Spatrick 
762e5dd7070Spatrick   /// Returns true while emitting a cleanuppad.
763e5dd7070Spatrick   bool isCleanupPadScope() const {
764e5dd7070Spatrick     return CurrentFuncletPad && isa<llvm::CleanupPadInst>(CurrentFuncletPad);
765e5dd7070Spatrick   }
766e5dd7070Spatrick 
767e5dd7070Spatrick   /// pushFullExprCleanup - Push a cleanup to be run at the end of the
768e5dd7070Spatrick   /// current full-expression.  Safe against the possibility that
769e5dd7070Spatrick   /// we're currently inside a conditionally-evaluated expression.
770e5dd7070Spatrick   template <class T, class... As>
771e5dd7070Spatrick   void pushFullExprCleanup(CleanupKind kind, As... A) {
772e5dd7070Spatrick     // If we're not in a conditional branch, or if none of the
773e5dd7070Spatrick     // arguments requires saving, then use the unconditional cleanup.
774e5dd7070Spatrick     if (!isInConditionalBranch())
775e5dd7070Spatrick       return EHStack.pushCleanup<T>(kind, A...);
776e5dd7070Spatrick 
777e5dd7070Spatrick     // Stash values in a tuple so we can guarantee the order of saves.
778e5dd7070Spatrick     typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple;
779e5dd7070Spatrick     SavedTuple Saved{saveValueInCond(A)...};
780e5dd7070Spatrick 
781e5dd7070Spatrick     typedef EHScopeStack::ConditionalCleanup<T, As...> CleanupType;
782e5dd7070Spatrick     EHStack.pushCleanupTuple<CleanupType>(kind, Saved);
783e5dd7070Spatrick     initFullExprCleanup();
784e5dd7070Spatrick   }
785e5dd7070Spatrick 
786a9ac8606Spatrick   /// Queue a cleanup to be pushed after finishing the current full-expression,
787a9ac8606Spatrick   /// potentially with an active flag.
788e5dd7070Spatrick   template <class T, class... As>
789e5dd7070Spatrick   void pushCleanupAfterFullExpr(CleanupKind Kind, As... A) {
790e5dd7070Spatrick     if (!isInConditionalBranch())
791a9ac8606Spatrick       return pushCleanupAfterFullExprWithActiveFlag<T>(Kind, Address::invalid(),
792a9ac8606Spatrick                                                        A...);
793e5dd7070Spatrick 
794e5dd7070Spatrick     Address ActiveFlag = createCleanupActiveFlag();
795e5dd7070Spatrick     assert(!DominatingValue<Address>::needsSaving(ActiveFlag) &&
796e5dd7070Spatrick            "cleanup active flag should never need saving");
797e5dd7070Spatrick 
798e5dd7070Spatrick     typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple;
799e5dd7070Spatrick     SavedTuple Saved{saveValueInCond(A)...};
800e5dd7070Spatrick 
801e5dd7070Spatrick     typedef EHScopeStack::ConditionalCleanup<T, As...> CleanupType;
802a9ac8606Spatrick     pushCleanupAfterFullExprWithActiveFlag<CleanupType>(Kind, ActiveFlag, Saved);
803e5dd7070Spatrick   }
804e5dd7070Spatrick 
805e5dd7070Spatrick   template <class T, class... As>
806a9ac8606Spatrick   void pushCleanupAfterFullExprWithActiveFlag(CleanupKind Kind,
807a9ac8606Spatrick                                               Address ActiveFlag, As... A) {
808e5dd7070Spatrick     LifetimeExtendedCleanupHeader Header = {sizeof(T), Kind,
809e5dd7070Spatrick                                             ActiveFlag.isValid()};
810e5dd7070Spatrick 
811e5dd7070Spatrick     size_t OldSize = LifetimeExtendedCleanupStack.size();
812e5dd7070Spatrick     LifetimeExtendedCleanupStack.resize(
813e5dd7070Spatrick         LifetimeExtendedCleanupStack.size() + sizeof(Header) + Header.Size +
814e5dd7070Spatrick         (Header.IsConditional ? sizeof(ActiveFlag) : 0));
815e5dd7070Spatrick 
816e5dd7070Spatrick     static_assert(sizeof(Header) % alignof(T) == 0,
817e5dd7070Spatrick                   "Cleanup will be allocated on misaligned address");
818e5dd7070Spatrick     char *Buffer = &LifetimeExtendedCleanupStack[OldSize];
819e5dd7070Spatrick     new (Buffer) LifetimeExtendedCleanupHeader(Header);
820e5dd7070Spatrick     new (Buffer + sizeof(Header)) T(A...);
821e5dd7070Spatrick     if (Header.IsConditional)
822e5dd7070Spatrick       new (Buffer + sizeof(Header) + sizeof(T)) Address(ActiveFlag);
823e5dd7070Spatrick   }
824e5dd7070Spatrick 
825e5dd7070Spatrick   /// Set up the last cleanup that was pushed as a conditional
826e5dd7070Spatrick   /// full-expression cleanup.
827e5dd7070Spatrick   void initFullExprCleanup() {
828e5dd7070Spatrick     initFullExprCleanupWithFlag(createCleanupActiveFlag());
829e5dd7070Spatrick   }
830e5dd7070Spatrick 
831e5dd7070Spatrick   void initFullExprCleanupWithFlag(Address ActiveFlag);
832e5dd7070Spatrick   Address createCleanupActiveFlag();
833e5dd7070Spatrick 
834e5dd7070Spatrick   /// PushDestructorCleanup - Push a cleanup to call the
835e5dd7070Spatrick   /// complete-object destructor of an object of the given type at the
836e5dd7070Spatrick   /// given address.  Does nothing if T is not a C++ class type with a
837e5dd7070Spatrick   /// non-trivial destructor.
838e5dd7070Spatrick   void PushDestructorCleanup(QualType T, Address Addr);
839e5dd7070Spatrick 
840e5dd7070Spatrick   /// PushDestructorCleanup - Push a cleanup to call the
841e5dd7070Spatrick   /// complete-object variant of the given destructor on the object at
842e5dd7070Spatrick   /// the given address.
843e5dd7070Spatrick   void PushDestructorCleanup(const CXXDestructorDecl *Dtor, QualType T,
844e5dd7070Spatrick                              Address Addr);
845e5dd7070Spatrick 
846e5dd7070Spatrick   /// PopCleanupBlock - Will pop the cleanup entry on the stack and
847e5dd7070Spatrick   /// process all branch fixups.
848e5dd7070Spatrick   void PopCleanupBlock(bool FallThroughIsBranchThrough = false);
849e5dd7070Spatrick 
850e5dd7070Spatrick   /// DeactivateCleanupBlock - Deactivates the given cleanup block.
851e5dd7070Spatrick   /// The block cannot be reactivated.  Pops it if it's the top of the
852e5dd7070Spatrick   /// stack.
853e5dd7070Spatrick   ///
854e5dd7070Spatrick   /// \param DominatingIP - An instruction which is known to
855e5dd7070Spatrick   ///   dominate the current IP (if set) and which lies along
856e5dd7070Spatrick   ///   all paths of execution between the current IP and the
857e5dd7070Spatrick   ///   the point at which the cleanup comes into scope.
858e5dd7070Spatrick   void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup,
859e5dd7070Spatrick                               llvm::Instruction *DominatingIP);
860e5dd7070Spatrick 
861e5dd7070Spatrick   /// ActivateCleanupBlock - Activates an initially-inactive cleanup.
862e5dd7070Spatrick   /// Cannot be used to resurrect a deactivated cleanup.
863e5dd7070Spatrick   ///
864e5dd7070Spatrick   /// \param DominatingIP - An instruction which is known to
865e5dd7070Spatrick   ///   dominate the current IP (if set) and which lies along
866e5dd7070Spatrick   ///   all paths of execution between the current IP and the
867e5dd7070Spatrick   ///   the point at which the cleanup comes into scope.
868e5dd7070Spatrick   void ActivateCleanupBlock(EHScopeStack::stable_iterator Cleanup,
869e5dd7070Spatrick                             llvm::Instruction *DominatingIP);
870e5dd7070Spatrick 
871e5dd7070Spatrick   /// Enters a new scope for capturing cleanups, all of which
872e5dd7070Spatrick   /// will be executed once the scope is exited.
873e5dd7070Spatrick   class RunCleanupsScope {
874e5dd7070Spatrick     EHScopeStack::stable_iterator CleanupStackDepth, OldCleanupScopeDepth;
875e5dd7070Spatrick     size_t LifetimeExtendedCleanupStackSize;
876e5dd7070Spatrick     bool OldDidCallStackSave;
877e5dd7070Spatrick   protected:
878e5dd7070Spatrick     bool PerformCleanup;
879e5dd7070Spatrick   private:
880e5dd7070Spatrick 
881e5dd7070Spatrick     RunCleanupsScope(const RunCleanupsScope &) = delete;
882e5dd7070Spatrick     void operator=(const RunCleanupsScope &) = delete;
883e5dd7070Spatrick 
884e5dd7070Spatrick   protected:
885e5dd7070Spatrick     CodeGenFunction& CGF;
886e5dd7070Spatrick 
887e5dd7070Spatrick   public:
888e5dd7070Spatrick     /// Enter a new cleanup scope.
889e5dd7070Spatrick     explicit RunCleanupsScope(CodeGenFunction &CGF)
890e5dd7070Spatrick       : PerformCleanup(true), CGF(CGF)
891e5dd7070Spatrick     {
892e5dd7070Spatrick       CleanupStackDepth = CGF.EHStack.stable_begin();
893e5dd7070Spatrick       LifetimeExtendedCleanupStackSize =
894e5dd7070Spatrick           CGF.LifetimeExtendedCleanupStack.size();
895e5dd7070Spatrick       OldDidCallStackSave = CGF.DidCallStackSave;
896e5dd7070Spatrick       CGF.DidCallStackSave = false;
897e5dd7070Spatrick       OldCleanupScopeDepth = CGF.CurrentCleanupScopeDepth;
898e5dd7070Spatrick       CGF.CurrentCleanupScopeDepth = CleanupStackDepth;
899e5dd7070Spatrick     }
900e5dd7070Spatrick 
901e5dd7070Spatrick     /// Exit this cleanup scope, emitting any accumulated cleanups.
902e5dd7070Spatrick     ~RunCleanupsScope() {
903e5dd7070Spatrick       if (PerformCleanup)
904e5dd7070Spatrick         ForceCleanup();
905e5dd7070Spatrick     }
906e5dd7070Spatrick 
907e5dd7070Spatrick     /// Determine whether this scope requires any cleanups.
908e5dd7070Spatrick     bool requiresCleanups() const {
909e5dd7070Spatrick       return CGF.EHStack.stable_begin() != CleanupStackDepth;
910e5dd7070Spatrick     }
911e5dd7070Spatrick 
912e5dd7070Spatrick     /// Force the emission of cleanups now, instead of waiting
913e5dd7070Spatrick     /// until this object is destroyed.
914e5dd7070Spatrick     /// \param ValuesToReload - A list of values that need to be available at
915e5dd7070Spatrick     /// the insertion point after cleanup emission. If cleanup emission created
916e5dd7070Spatrick     /// a shared cleanup block, these value pointers will be rewritten.
917e5dd7070Spatrick     /// Otherwise, they not will be modified.
918e5dd7070Spatrick     void ForceCleanup(std::initializer_list<llvm::Value**> ValuesToReload = {}) {
919e5dd7070Spatrick       assert(PerformCleanup && "Already forced cleanup");
920e5dd7070Spatrick       CGF.DidCallStackSave = OldDidCallStackSave;
921e5dd7070Spatrick       CGF.PopCleanupBlocks(CleanupStackDepth, LifetimeExtendedCleanupStackSize,
922e5dd7070Spatrick                            ValuesToReload);
923e5dd7070Spatrick       PerformCleanup = false;
924e5dd7070Spatrick       CGF.CurrentCleanupScopeDepth = OldCleanupScopeDepth;
925e5dd7070Spatrick     }
926e5dd7070Spatrick   };
927e5dd7070Spatrick 
928e5dd7070Spatrick   // Cleanup stack depth of the RunCleanupsScope that was pushed most recently.
929e5dd7070Spatrick   EHScopeStack::stable_iterator CurrentCleanupScopeDepth =
930e5dd7070Spatrick       EHScopeStack::stable_end();
931e5dd7070Spatrick 
932e5dd7070Spatrick   class LexicalScope : public RunCleanupsScope {
933e5dd7070Spatrick     SourceRange Range;
934e5dd7070Spatrick     SmallVector<const LabelDecl*, 4> Labels;
935e5dd7070Spatrick     LexicalScope *ParentScope;
936e5dd7070Spatrick 
937e5dd7070Spatrick     LexicalScope(const LexicalScope &) = delete;
938e5dd7070Spatrick     void operator=(const LexicalScope &) = delete;
939e5dd7070Spatrick 
940e5dd7070Spatrick   public:
941e5dd7070Spatrick     /// Enter a new cleanup scope.
942e5dd7070Spatrick     explicit LexicalScope(CodeGenFunction &CGF, SourceRange Range)
943e5dd7070Spatrick       : RunCleanupsScope(CGF), Range(Range), ParentScope(CGF.CurLexicalScope) {
944e5dd7070Spatrick       CGF.CurLexicalScope = this;
945e5dd7070Spatrick       if (CGDebugInfo *DI = CGF.getDebugInfo())
946e5dd7070Spatrick         DI->EmitLexicalBlockStart(CGF.Builder, Range.getBegin());
947e5dd7070Spatrick     }
948e5dd7070Spatrick 
949e5dd7070Spatrick     void addLabel(const LabelDecl *label) {
950e5dd7070Spatrick       assert(PerformCleanup && "adding label to dead scope?");
951e5dd7070Spatrick       Labels.push_back(label);
952e5dd7070Spatrick     }
953e5dd7070Spatrick 
954e5dd7070Spatrick     /// Exit this cleanup scope, emitting any accumulated
955e5dd7070Spatrick     /// cleanups.
956e5dd7070Spatrick     ~LexicalScope() {
957e5dd7070Spatrick       if (CGDebugInfo *DI = CGF.getDebugInfo())
958e5dd7070Spatrick         DI->EmitLexicalBlockEnd(CGF.Builder, Range.getEnd());
959e5dd7070Spatrick 
960e5dd7070Spatrick       // If we should perform a cleanup, force them now.  Note that
961e5dd7070Spatrick       // this ends the cleanup scope before rescoping any labels.
962e5dd7070Spatrick       if (PerformCleanup) {
963e5dd7070Spatrick         ApplyDebugLocation DL(CGF, Range.getEnd());
964e5dd7070Spatrick         ForceCleanup();
965e5dd7070Spatrick       }
966e5dd7070Spatrick     }
967e5dd7070Spatrick 
968e5dd7070Spatrick     /// Force the emission of cleanups now, instead of waiting
969e5dd7070Spatrick     /// until this object is destroyed.
970e5dd7070Spatrick     void ForceCleanup() {
971e5dd7070Spatrick       CGF.CurLexicalScope = ParentScope;
972e5dd7070Spatrick       RunCleanupsScope::ForceCleanup();
973e5dd7070Spatrick 
974e5dd7070Spatrick       if (!Labels.empty())
975e5dd7070Spatrick         rescopeLabels();
976e5dd7070Spatrick     }
977e5dd7070Spatrick 
978e5dd7070Spatrick     bool hasLabels() const {
979e5dd7070Spatrick       return !Labels.empty();
980e5dd7070Spatrick     }
981e5dd7070Spatrick 
982e5dd7070Spatrick     void rescopeLabels();
983e5dd7070Spatrick   };
984e5dd7070Spatrick 
985e5dd7070Spatrick   typedef llvm::DenseMap<const Decl *, Address> DeclMapTy;
986e5dd7070Spatrick 
987e5dd7070Spatrick   /// The class used to assign some variables some temporarily addresses.
988e5dd7070Spatrick   class OMPMapVars {
989e5dd7070Spatrick     DeclMapTy SavedLocals;
990e5dd7070Spatrick     DeclMapTy SavedTempAddresses;
991e5dd7070Spatrick     OMPMapVars(const OMPMapVars &) = delete;
992e5dd7070Spatrick     void operator=(const OMPMapVars &) = delete;
993e5dd7070Spatrick 
994e5dd7070Spatrick   public:
995e5dd7070Spatrick     explicit OMPMapVars() = default;
996e5dd7070Spatrick     ~OMPMapVars() {
997e5dd7070Spatrick       assert(SavedLocals.empty() && "Did not restored original addresses.");
998e5dd7070Spatrick     };
999e5dd7070Spatrick 
1000e5dd7070Spatrick     /// Sets the address of the variable \p LocalVD to be \p TempAddr in
1001e5dd7070Spatrick     /// function \p CGF.
1002e5dd7070Spatrick     /// \return true if at least one variable was set already, false otherwise.
1003e5dd7070Spatrick     bool setVarAddr(CodeGenFunction &CGF, const VarDecl *LocalVD,
1004e5dd7070Spatrick                     Address TempAddr) {
1005e5dd7070Spatrick       LocalVD = LocalVD->getCanonicalDecl();
1006e5dd7070Spatrick       // Only save it once.
1007e5dd7070Spatrick       if (SavedLocals.count(LocalVD)) return false;
1008e5dd7070Spatrick 
1009e5dd7070Spatrick       // Copy the existing local entry to SavedLocals.
1010e5dd7070Spatrick       auto it = CGF.LocalDeclMap.find(LocalVD);
1011e5dd7070Spatrick       if (it != CGF.LocalDeclMap.end())
1012e5dd7070Spatrick         SavedLocals.try_emplace(LocalVD, it->second);
1013e5dd7070Spatrick       else
1014e5dd7070Spatrick         SavedLocals.try_emplace(LocalVD, Address::invalid());
1015e5dd7070Spatrick 
1016e5dd7070Spatrick       // Generate the private entry.
1017e5dd7070Spatrick       QualType VarTy = LocalVD->getType();
1018e5dd7070Spatrick       if (VarTy->isReferenceType()) {
1019e5dd7070Spatrick         Address Temp = CGF.CreateMemTemp(VarTy);
1020e5dd7070Spatrick         CGF.Builder.CreateStore(TempAddr.getPointer(), Temp);
1021e5dd7070Spatrick         TempAddr = Temp;
1022e5dd7070Spatrick       }
1023e5dd7070Spatrick       SavedTempAddresses.try_emplace(LocalVD, TempAddr);
1024e5dd7070Spatrick 
1025e5dd7070Spatrick       return true;
1026e5dd7070Spatrick     }
1027e5dd7070Spatrick 
1028e5dd7070Spatrick     /// Applies new addresses to the list of the variables.
1029e5dd7070Spatrick     /// \return true if at least one variable is using new address, false
1030e5dd7070Spatrick     /// otherwise.
1031e5dd7070Spatrick     bool apply(CodeGenFunction &CGF) {
1032e5dd7070Spatrick       copyInto(SavedTempAddresses, CGF.LocalDeclMap);
1033e5dd7070Spatrick       SavedTempAddresses.clear();
1034e5dd7070Spatrick       return !SavedLocals.empty();
1035e5dd7070Spatrick     }
1036e5dd7070Spatrick 
1037e5dd7070Spatrick     /// Restores original addresses of the variables.
1038e5dd7070Spatrick     void restore(CodeGenFunction &CGF) {
1039e5dd7070Spatrick       if (!SavedLocals.empty()) {
1040e5dd7070Spatrick         copyInto(SavedLocals, CGF.LocalDeclMap);
1041e5dd7070Spatrick         SavedLocals.clear();
1042e5dd7070Spatrick       }
1043e5dd7070Spatrick     }
1044e5dd7070Spatrick 
1045e5dd7070Spatrick   private:
1046e5dd7070Spatrick     /// Copy all the entries in the source map over the corresponding
1047e5dd7070Spatrick     /// entries in the destination, which must exist.
1048e5dd7070Spatrick     static void copyInto(const DeclMapTy &Src, DeclMapTy &Dest) {
1049e5dd7070Spatrick       for (auto &Pair : Src) {
1050e5dd7070Spatrick         if (!Pair.second.isValid()) {
1051e5dd7070Spatrick           Dest.erase(Pair.first);
1052e5dd7070Spatrick           continue;
1053e5dd7070Spatrick         }
1054e5dd7070Spatrick 
1055e5dd7070Spatrick         auto I = Dest.find(Pair.first);
1056e5dd7070Spatrick         if (I != Dest.end())
1057e5dd7070Spatrick           I->second = Pair.second;
1058e5dd7070Spatrick         else
1059e5dd7070Spatrick           Dest.insert(Pair);
1060e5dd7070Spatrick       }
1061e5dd7070Spatrick     }
1062e5dd7070Spatrick   };
1063e5dd7070Spatrick 
1064e5dd7070Spatrick   /// The scope used to remap some variables as private in the OpenMP loop body
1065e5dd7070Spatrick   /// (or other captured region emitted without outlining), and to restore old
1066e5dd7070Spatrick   /// vars back on exit.
1067e5dd7070Spatrick   class OMPPrivateScope : public RunCleanupsScope {
1068e5dd7070Spatrick     OMPMapVars MappedVars;
1069e5dd7070Spatrick     OMPPrivateScope(const OMPPrivateScope &) = delete;
1070e5dd7070Spatrick     void operator=(const OMPPrivateScope &) = delete;
1071e5dd7070Spatrick 
1072e5dd7070Spatrick   public:
1073e5dd7070Spatrick     /// Enter a new OpenMP private scope.
1074e5dd7070Spatrick     explicit OMPPrivateScope(CodeGenFunction &CGF) : RunCleanupsScope(CGF) {}
1075e5dd7070Spatrick 
1076*12c85518Srobert     /// Registers \p LocalVD variable as a private with \p Addr as the address
1077*12c85518Srobert     /// of the corresponding private variable. \p
1078*12c85518Srobert     /// PrivateGen is the address of the generated private variable.
1079e5dd7070Spatrick     /// \return true if the variable is registered as private, false if it has
1080e5dd7070Spatrick     /// been privatized already.
1081*12c85518Srobert     bool addPrivate(const VarDecl *LocalVD, Address Addr) {
1082e5dd7070Spatrick       assert(PerformCleanup && "adding private to dead scope");
1083*12c85518Srobert       return MappedVars.setVarAddr(CGF, LocalVD, Addr);
1084e5dd7070Spatrick     }
1085e5dd7070Spatrick 
1086e5dd7070Spatrick     /// Privatizes local variables previously registered as private.
1087e5dd7070Spatrick     /// Registration is separate from the actual privatization to allow
1088e5dd7070Spatrick     /// initializers use values of the original variables, not the private one.
1089e5dd7070Spatrick     /// This is important, for example, if the private variable is a class
1090e5dd7070Spatrick     /// variable initialized by a constructor that references other private
1091e5dd7070Spatrick     /// variables. But at initialization original variables must be used, not
1092e5dd7070Spatrick     /// private copies.
1093e5dd7070Spatrick     /// \return true if at least one variable was privatized, false otherwise.
1094e5dd7070Spatrick     bool Privatize() { return MappedVars.apply(CGF); }
1095e5dd7070Spatrick 
1096e5dd7070Spatrick     void ForceCleanup() {
1097e5dd7070Spatrick       RunCleanupsScope::ForceCleanup();
1098*12c85518Srobert       restoreMap();
1099e5dd7070Spatrick     }
1100e5dd7070Spatrick 
1101e5dd7070Spatrick     /// Exit scope - all the mapped variables are restored.
1102e5dd7070Spatrick     ~OMPPrivateScope() {
1103e5dd7070Spatrick       if (PerformCleanup)
1104e5dd7070Spatrick         ForceCleanup();
1105e5dd7070Spatrick     }
1106e5dd7070Spatrick 
1107e5dd7070Spatrick     /// Checks if the global variable is captured in current function.
1108e5dd7070Spatrick     bool isGlobalVarCaptured(const VarDecl *VD) const {
1109e5dd7070Spatrick       VD = VD->getCanonicalDecl();
1110e5dd7070Spatrick       return !VD->isLocalVarDeclOrParm() && CGF.LocalDeclMap.count(VD) > 0;
1111e5dd7070Spatrick     }
1112*12c85518Srobert 
1113*12c85518Srobert     /// Restore all mapped variables w/o clean up. This is usefully when we want
1114*12c85518Srobert     /// to reference the original variables but don't want the clean up because
1115*12c85518Srobert     /// that could emit lifetime end too early, causing backend issue #56913.
1116*12c85518Srobert     void restoreMap() { MappedVars.restore(CGF); }
1117e5dd7070Spatrick   };
1118e5dd7070Spatrick 
1119e5dd7070Spatrick   /// Save/restore original map of previously emitted local vars in case when we
1120e5dd7070Spatrick   /// need to duplicate emission of the same code several times in the same
1121e5dd7070Spatrick   /// function for OpenMP code.
1122e5dd7070Spatrick   class OMPLocalDeclMapRAII {
1123e5dd7070Spatrick     CodeGenFunction &CGF;
1124e5dd7070Spatrick     DeclMapTy SavedMap;
1125e5dd7070Spatrick 
1126e5dd7070Spatrick   public:
1127e5dd7070Spatrick     OMPLocalDeclMapRAII(CodeGenFunction &CGF)
1128e5dd7070Spatrick         : CGF(CGF), SavedMap(CGF.LocalDeclMap) {}
1129e5dd7070Spatrick     ~OMPLocalDeclMapRAII() { SavedMap.swap(CGF.LocalDeclMap); }
1130e5dd7070Spatrick   };
1131e5dd7070Spatrick 
1132e5dd7070Spatrick   /// Takes the old cleanup stack size and emits the cleanup blocks
1133e5dd7070Spatrick   /// that have been added.
1134e5dd7070Spatrick   void
1135e5dd7070Spatrick   PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize,
1136e5dd7070Spatrick                    std::initializer_list<llvm::Value **> ValuesToReload = {});
1137e5dd7070Spatrick 
1138e5dd7070Spatrick   /// Takes the old cleanup stack size and emits the cleanup blocks
1139e5dd7070Spatrick   /// that have been added, then adds all lifetime-extended cleanups from
1140e5dd7070Spatrick   /// the given position to the stack.
1141e5dd7070Spatrick   void
1142e5dd7070Spatrick   PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize,
1143e5dd7070Spatrick                    size_t OldLifetimeExtendedStackSize,
1144e5dd7070Spatrick                    std::initializer_list<llvm::Value **> ValuesToReload = {});
1145e5dd7070Spatrick 
1146e5dd7070Spatrick   void ResolveBranchFixups(llvm::BasicBlock *Target);
1147e5dd7070Spatrick 
1148e5dd7070Spatrick   /// The given basic block lies in the current EH scope, but may be a
1149e5dd7070Spatrick   /// target of a potentially scope-crossing jump; get a stable handle
1150e5dd7070Spatrick   /// to which we can perform this jump later.
1151e5dd7070Spatrick   JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target) {
1152e5dd7070Spatrick     return JumpDest(Target,
1153e5dd7070Spatrick                     EHStack.getInnermostNormalCleanup(),
1154e5dd7070Spatrick                     NextCleanupDestIndex++);
1155e5dd7070Spatrick   }
1156e5dd7070Spatrick 
1157e5dd7070Spatrick   /// The given basic block lies in the current EH scope, but may be a
1158e5dd7070Spatrick   /// target of a potentially scope-crossing jump; get a stable handle
1159e5dd7070Spatrick   /// to which we can perform this jump later.
1160e5dd7070Spatrick   JumpDest getJumpDestInCurrentScope(StringRef Name = StringRef()) {
1161e5dd7070Spatrick     return getJumpDestInCurrentScope(createBasicBlock(Name));
1162e5dd7070Spatrick   }
1163e5dd7070Spatrick 
1164e5dd7070Spatrick   /// EmitBranchThroughCleanup - Emit a branch from the current insert
1165e5dd7070Spatrick   /// block through the normal cleanup handling code (if any) and then
1166e5dd7070Spatrick   /// on to \arg Dest.
1167e5dd7070Spatrick   void EmitBranchThroughCleanup(JumpDest Dest);
1168e5dd7070Spatrick 
1169e5dd7070Spatrick   /// isObviouslyBranchWithoutCleanups - Return true if a branch to the
1170e5dd7070Spatrick   /// specified destination obviously has no cleanups to run.  'false' is always
1171e5dd7070Spatrick   /// a conservatively correct answer for this method.
1172e5dd7070Spatrick   bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const;
1173e5dd7070Spatrick 
1174e5dd7070Spatrick   /// popCatchScope - Pops the catch scope at the top of the EHScope
1175e5dd7070Spatrick   /// stack, emitting any required code (other than the catch handlers
1176e5dd7070Spatrick   /// themselves).
1177e5dd7070Spatrick   void popCatchScope();
1178e5dd7070Spatrick 
1179e5dd7070Spatrick   llvm::BasicBlock *getEHResumeBlock(bool isCleanup);
1180e5dd7070Spatrick   llvm::BasicBlock *getEHDispatchBlock(EHScopeStack::stable_iterator scope);
1181e5dd7070Spatrick   llvm::BasicBlock *
1182e5dd7070Spatrick   getFuncletEHDispatchBlock(EHScopeStack::stable_iterator scope);
1183e5dd7070Spatrick 
1184e5dd7070Spatrick   /// An object to manage conditionally-evaluated expressions.
1185e5dd7070Spatrick   class ConditionalEvaluation {
1186e5dd7070Spatrick     llvm::BasicBlock *StartBB;
1187e5dd7070Spatrick 
1188e5dd7070Spatrick   public:
1189e5dd7070Spatrick     ConditionalEvaluation(CodeGenFunction &CGF)
1190e5dd7070Spatrick       : StartBB(CGF.Builder.GetInsertBlock()) {}
1191e5dd7070Spatrick 
1192e5dd7070Spatrick     void begin(CodeGenFunction &CGF) {
1193e5dd7070Spatrick       assert(CGF.OutermostConditional != this);
1194e5dd7070Spatrick       if (!CGF.OutermostConditional)
1195e5dd7070Spatrick         CGF.OutermostConditional = this;
1196e5dd7070Spatrick     }
1197e5dd7070Spatrick 
1198e5dd7070Spatrick     void end(CodeGenFunction &CGF) {
1199e5dd7070Spatrick       assert(CGF.OutermostConditional != nullptr);
1200e5dd7070Spatrick       if (CGF.OutermostConditional == this)
1201e5dd7070Spatrick         CGF.OutermostConditional = nullptr;
1202e5dd7070Spatrick     }
1203e5dd7070Spatrick 
1204e5dd7070Spatrick     /// Returns a block which will be executed prior to each
1205e5dd7070Spatrick     /// evaluation of the conditional code.
1206e5dd7070Spatrick     llvm::BasicBlock *getStartingBlock() const {
1207e5dd7070Spatrick       return StartBB;
1208e5dd7070Spatrick     }
1209e5dd7070Spatrick   };
1210e5dd7070Spatrick 
1211e5dd7070Spatrick   /// isInConditionalBranch - Return true if we're currently emitting
1212e5dd7070Spatrick   /// one branch or the other of a conditional expression.
1213e5dd7070Spatrick   bool isInConditionalBranch() const { return OutermostConditional != nullptr; }
1214e5dd7070Spatrick 
1215e5dd7070Spatrick   void setBeforeOutermostConditional(llvm::Value *value, Address addr) {
1216e5dd7070Spatrick     assert(isInConditionalBranch());
1217e5dd7070Spatrick     llvm::BasicBlock *block = OutermostConditional->getStartingBlock();
1218e5dd7070Spatrick     auto store = new llvm::StoreInst(value, addr.getPointer(), &block->back());
1219e5dd7070Spatrick     store->setAlignment(addr.getAlignment().getAsAlign());
1220e5dd7070Spatrick   }
1221e5dd7070Spatrick 
1222e5dd7070Spatrick   /// An RAII object to record that we're evaluating a statement
1223e5dd7070Spatrick   /// expression.
1224e5dd7070Spatrick   class StmtExprEvaluation {
1225e5dd7070Spatrick     CodeGenFunction &CGF;
1226e5dd7070Spatrick 
1227e5dd7070Spatrick     /// We have to save the outermost conditional: cleanups in a
1228e5dd7070Spatrick     /// statement expression aren't conditional just because the
1229e5dd7070Spatrick     /// StmtExpr is.
1230e5dd7070Spatrick     ConditionalEvaluation *SavedOutermostConditional;
1231e5dd7070Spatrick 
1232e5dd7070Spatrick   public:
1233e5dd7070Spatrick     StmtExprEvaluation(CodeGenFunction &CGF)
1234e5dd7070Spatrick       : CGF(CGF), SavedOutermostConditional(CGF.OutermostConditional) {
1235e5dd7070Spatrick       CGF.OutermostConditional = nullptr;
1236e5dd7070Spatrick     }
1237e5dd7070Spatrick 
1238e5dd7070Spatrick     ~StmtExprEvaluation() {
1239e5dd7070Spatrick       CGF.OutermostConditional = SavedOutermostConditional;
1240e5dd7070Spatrick       CGF.EnsureInsertPoint();
1241e5dd7070Spatrick     }
1242e5dd7070Spatrick   };
1243e5dd7070Spatrick 
1244e5dd7070Spatrick   /// An object which temporarily prevents a value from being
1245e5dd7070Spatrick   /// destroyed by aggressive peephole optimizations that assume that
1246e5dd7070Spatrick   /// all uses of a value have been realized in the IR.
1247e5dd7070Spatrick   class PeepholeProtection {
1248e5dd7070Spatrick     llvm::Instruction *Inst;
1249e5dd7070Spatrick     friend class CodeGenFunction;
1250e5dd7070Spatrick 
1251e5dd7070Spatrick   public:
1252e5dd7070Spatrick     PeepholeProtection() : Inst(nullptr) {}
1253e5dd7070Spatrick   };
1254e5dd7070Spatrick 
1255e5dd7070Spatrick   /// A non-RAII class containing all the information about a bound
1256e5dd7070Spatrick   /// opaque value.  OpaqueValueMapping, below, is a RAII wrapper for
1257e5dd7070Spatrick   /// this which makes individual mappings very simple; using this
1258e5dd7070Spatrick   /// class directly is useful when you have a variable number of
1259e5dd7070Spatrick   /// opaque values or don't want the RAII functionality for some
1260e5dd7070Spatrick   /// reason.
1261e5dd7070Spatrick   class OpaqueValueMappingData {
1262e5dd7070Spatrick     const OpaqueValueExpr *OpaqueValue;
1263e5dd7070Spatrick     bool BoundLValue;
1264e5dd7070Spatrick     CodeGenFunction::PeepholeProtection Protection;
1265e5dd7070Spatrick 
1266e5dd7070Spatrick     OpaqueValueMappingData(const OpaqueValueExpr *ov,
1267e5dd7070Spatrick                            bool boundLValue)
1268e5dd7070Spatrick       : OpaqueValue(ov), BoundLValue(boundLValue) {}
1269e5dd7070Spatrick   public:
1270e5dd7070Spatrick     OpaqueValueMappingData() : OpaqueValue(nullptr) {}
1271e5dd7070Spatrick 
1272e5dd7070Spatrick     static bool shouldBindAsLValue(const Expr *expr) {
1273e5dd7070Spatrick       // gl-values should be bound as l-values for obvious reasons.
1274e5dd7070Spatrick       // Records should be bound as l-values because IR generation
1275e5dd7070Spatrick       // always keeps them in memory.  Expressions of function type
1276e5dd7070Spatrick       // act exactly like l-values but are formally required to be
1277e5dd7070Spatrick       // r-values in C.
1278e5dd7070Spatrick       return expr->isGLValue() ||
1279e5dd7070Spatrick              expr->getType()->isFunctionType() ||
1280e5dd7070Spatrick              hasAggregateEvaluationKind(expr->getType());
1281e5dd7070Spatrick     }
1282e5dd7070Spatrick 
1283e5dd7070Spatrick     static OpaqueValueMappingData bind(CodeGenFunction &CGF,
1284e5dd7070Spatrick                                        const OpaqueValueExpr *ov,
1285e5dd7070Spatrick                                        const Expr *e) {
1286e5dd7070Spatrick       if (shouldBindAsLValue(ov))
1287e5dd7070Spatrick         return bind(CGF, ov, CGF.EmitLValue(e));
1288e5dd7070Spatrick       return bind(CGF, ov, CGF.EmitAnyExpr(e));
1289e5dd7070Spatrick     }
1290e5dd7070Spatrick 
1291e5dd7070Spatrick     static OpaqueValueMappingData bind(CodeGenFunction &CGF,
1292e5dd7070Spatrick                                        const OpaqueValueExpr *ov,
1293e5dd7070Spatrick                                        const LValue &lv) {
1294e5dd7070Spatrick       assert(shouldBindAsLValue(ov));
1295e5dd7070Spatrick       CGF.OpaqueLValues.insert(std::make_pair(ov, lv));
1296e5dd7070Spatrick       return OpaqueValueMappingData(ov, true);
1297e5dd7070Spatrick     }
1298e5dd7070Spatrick 
1299e5dd7070Spatrick     static OpaqueValueMappingData bind(CodeGenFunction &CGF,
1300e5dd7070Spatrick                                        const OpaqueValueExpr *ov,
1301e5dd7070Spatrick                                        const RValue &rv) {
1302e5dd7070Spatrick       assert(!shouldBindAsLValue(ov));
1303e5dd7070Spatrick       CGF.OpaqueRValues.insert(std::make_pair(ov, rv));
1304e5dd7070Spatrick 
1305e5dd7070Spatrick       OpaqueValueMappingData data(ov, false);
1306e5dd7070Spatrick 
1307e5dd7070Spatrick       // Work around an extremely aggressive peephole optimization in
1308e5dd7070Spatrick       // EmitScalarConversion which assumes that all other uses of a
1309e5dd7070Spatrick       // value are extant.
1310e5dd7070Spatrick       data.Protection = CGF.protectFromPeepholes(rv);
1311e5dd7070Spatrick 
1312e5dd7070Spatrick       return data;
1313e5dd7070Spatrick     }
1314e5dd7070Spatrick 
1315e5dd7070Spatrick     bool isValid() const { return OpaqueValue != nullptr; }
1316e5dd7070Spatrick     void clear() { OpaqueValue = nullptr; }
1317e5dd7070Spatrick 
1318e5dd7070Spatrick     void unbind(CodeGenFunction &CGF) {
1319e5dd7070Spatrick       assert(OpaqueValue && "no data to unbind!");
1320e5dd7070Spatrick 
1321e5dd7070Spatrick       if (BoundLValue) {
1322e5dd7070Spatrick         CGF.OpaqueLValues.erase(OpaqueValue);
1323e5dd7070Spatrick       } else {
1324e5dd7070Spatrick         CGF.OpaqueRValues.erase(OpaqueValue);
1325e5dd7070Spatrick         CGF.unprotectFromPeepholes(Protection);
1326e5dd7070Spatrick       }
1327e5dd7070Spatrick     }
1328e5dd7070Spatrick   };
1329e5dd7070Spatrick 
1330e5dd7070Spatrick   /// An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
1331e5dd7070Spatrick   class OpaqueValueMapping {
1332e5dd7070Spatrick     CodeGenFunction &CGF;
1333e5dd7070Spatrick     OpaqueValueMappingData Data;
1334e5dd7070Spatrick 
1335e5dd7070Spatrick   public:
1336e5dd7070Spatrick     static bool shouldBindAsLValue(const Expr *expr) {
1337e5dd7070Spatrick       return OpaqueValueMappingData::shouldBindAsLValue(expr);
1338e5dd7070Spatrick     }
1339e5dd7070Spatrick 
1340e5dd7070Spatrick     /// Build the opaque value mapping for the given conditional
1341e5dd7070Spatrick     /// operator if it's the GNU ?: extension.  This is a common
1342e5dd7070Spatrick     /// enough pattern that the convenience operator is really
1343e5dd7070Spatrick     /// helpful.
1344e5dd7070Spatrick     ///
1345e5dd7070Spatrick     OpaqueValueMapping(CodeGenFunction &CGF,
1346e5dd7070Spatrick                        const AbstractConditionalOperator *op) : CGF(CGF) {
1347e5dd7070Spatrick       if (isa<ConditionalOperator>(op))
1348e5dd7070Spatrick         // Leave Data empty.
1349e5dd7070Spatrick         return;
1350e5dd7070Spatrick 
1351e5dd7070Spatrick       const BinaryConditionalOperator *e = cast<BinaryConditionalOperator>(op);
1352e5dd7070Spatrick       Data = OpaqueValueMappingData::bind(CGF, e->getOpaqueValue(),
1353e5dd7070Spatrick                                           e->getCommon());
1354e5dd7070Spatrick     }
1355e5dd7070Spatrick 
1356e5dd7070Spatrick     /// Build the opaque value mapping for an OpaqueValueExpr whose source
1357e5dd7070Spatrick     /// expression is set to the expression the OVE represents.
1358e5dd7070Spatrick     OpaqueValueMapping(CodeGenFunction &CGF, const OpaqueValueExpr *OV)
1359e5dd7070Spatrick         : CGF(CGF) {
1360e5dd7070Spatrick       if (OV) {
1361e5dd7070Spatrick         assert(OV->getSourceExpr() && "wrong form of OpaqueValueMapping used "
1362e5dd7070Spatrick                                       "for OVE with no source expression");
1363e5dd7070Spatrick         Data = OpaqueValueMappingData::bind(CGF, OV, OV->getSourceExpr());
1364e5dd7070Spatrick       }
1365e5dd7070Spatrick     }
1366e5dd7070Spatrick 
1367e5dd7070Spatrick     OpaqueValueMapping(CodeGenFunction &CGF,
1368e5dd7070Spatrick                        const OpaqueValueExpr *opaqueValue,
1369e5dd7070Spatrick                        LValue lvalue)
1370e5dd7070Spatrick       : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, lvalue)) {
1371e5dd7070Spatrick     }
1372e5dd7070Spatrick 
1373e5dd7070Spatrick     OpaqueValueMapping(CodeGenFunction &CGF,
1374e5dd7070Spatrick                        const OpaqueValueExpr *opaqueValue,
1375e5dd7070Spatrick                        RValue rvalue)
1376e5dd7070Spatrick       : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, rvalue)) {
1377e5dd7070Spatrick     }
1378e5dd7070Spatrick 
1379e5dd7070Spatrick     void pop() {
1380e5dd7070Spatrick       Data.unbind(CGF);
1381e5dd7070Spatrick       Data.clear();
1382e5dd7070Spatrick     }
1383e5dd7070Spatrick 
1384e5dd7070Spatrick     ~OpaqueValueMapping() {
1385e5dd7070Spatrick       if (Data.isValid()) Data.unbind(CGF);
1386e5dd7070Spatrick     }
1387e5dd7070Spatrick   };
1388e5dd7070Spatrick 
1389e5dd7070Spatrick private:
1390e5dd7070Spatrick   CGDebugInfo *DebugInfo;
1391e5dd7070Spatrick   /// Used to create unique names for artificial VLA size debug info variables.
1392e5dd7070Spatrick   unsigned VLAExprCounter = 0;
1393e5dd7070Spatrick   bool DisableDebugInfo = false;
1394e5dd7070Spatrick 
1395e5dd7070Spatrick   /// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid
1396e5dd7070Spatrick   /// calling llvm.stacksave for multiple VLAs in the same scope.
1397e5dd7070Spatrick   bool DidCallStackSave = false;
1398e5dd7070Spatrick 
1399e5dd7070Spatrick   /// IndirectBranch - The first time an indirect goto is seen we create a block
1400e5dd7070Spatrick   /// with an indirect branch.  Every time we see the address of a label taken,
1401e5dd7070Spatrick   /// we add the label to the indirect goto.  Every subsequent indirect goto is
1402e5dd7070Spatrick   /// codegen'd as a jump to the IndirectBranch's basic block.
1403e5dd7070Spatrick   llvm::IndirectBrInst *IndirectBranch = nullptr;
1404e5dd7070Spatrick 
1405e5dd7070Spatrick   /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
1406e5dd7070Spatrick   /// decls.
1407e5dd7070Spatrick   DeclMapTy LocalDeclMap;
1408e5dd7070Spatrick 
1409e5dd7070Spatrick   // Keep track of the cleanups for callee-destructed parameters pushed to the
1410e5dd7070Spatrick   // cleanup stack so that they can be deactivated later.
1411e5dd7070Spatrick   llvm::DenseMap<const ParmVarDecl *, EHScopeStack::stable_iterator>
1412e5dd7070Spatrick       CalleeDestructedParamCleanups;
1413e5dd7070Spatrick 
1414e5dd7070Spatrick   /// SizeArguments - If a ParmVarDecl had the pass_object_size attribute, this
1415e5dd7070Spatrick   /// will contain a mapping from said ParmVarDecl to its implicit "object_size"
1416e5dd7070Spatrick   /// parameter.
1417e5dd7070Spatrick   llvm::SmallDenseMap<const ParmVarDecl *, const ImplicitParamDecl *, 2>
1418e5dd7070Spatrick       SizeArguments;
1419e5dd7070Spatrick 
1420e5dd7070Spatrick   /// Track escaped local variables with auto storage. Used during SEH
1421e5dd7070Spatrick   /// outlining to produce a call to llvm.localescape.
1422e5dd7070Spatrick   llvm::DenseMap<llvm::AllocaInst *, int> EscapedLocals;
1423e5dd7070Spatrick 
1424e5dd7070Spatrick   /// LabelMap - This keeps track of the LLVM basic block for each C label.
1425e5dd7070Spatrick   llvm::DenseMap<const LabelDecl*, JumpDest> LabelMap;
1426e5dd7070Spatrick 
1427e5dd7070Spatrick   // BreakContinueStack - This keeps track of where break and continue
1428e5dd7070Spatrick   // statements should jump to.
1429e5dd7070Spatrick   struct BreakContinue {
1430e5dd7070Spatrick     BreakContinue(JumpDest Break, JumpDest Continue)
1431e5dd7070Spatrick       : BreakBlock(Break), ContinueBlock(Continue) {}
1432e5dd7070Spatrick 
1433e5dd7070Spatrick     JumpDest BreakBlock;
1434e5dd7070Spatrick     JumpDest ContinueBlock;
1435e5dd7070Spatrick   };
1436e5dd7070Spatrick   SmallVector<BreakContinue, 8> BreakContinueStack;
1437e5dd7070Spatrick 
1438e5dd7070Spatrick   /// Handles cancellation exit points in OpenMP-related constructs.
1439e5dd7070Spatrick   class OpenMPCancelExitStack {
1440e5dd7070Spatrick     /// Tracks cancellation exit point and join point for cancel-related exit
1441e5dd7070Spatrick     /// and normal exit.
1442e5dd7070Spatrick     struct CancelExit {
1443e5dd7070Spatrick       CancelExit() = default;
1444e5dd7070Spatrick       CancelExit(OpenMPDirectiveKind Kind, JumpDest ExitBlock,
1445e5dd7070Spatrick                  JumpDest ContBlock)
1446e5dd7070Spatrick           : Kind(Kind), ExitBlock(ExitBlock), ContBlock(ContBlock) {}
1447e5dd7070Spatrick       OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown;
1448e5dd7070Spatrick       /// true if the exit block has been emitted already by the special
1449e5dd7070Spatrick       /// emitExit() call, false if the default codegen is used.
1450e5dd7070Spatrick       bool HasBeenEmitted = false;
1451e5dd7070Spatrick       JumpDest ExitBlock;
1452e5dd7070Spatrick       JumpDest ContBlock;
1453e5dd7070Spatrick     };
1454e5dd7070Spatrick 
1455e5dd7070Spatrick     SmallVector<CancelExit, 8> Stack;
1456e5dd7070Spatrick 
1457e5dd7070Spatrick   public:
1458e5dd7070Spatrick     OpenMPCancelExitStack() : Stack(1) {}
1459e5dd7070Spatrick     ~OpenMPCancelExitStack() = default;
1460e5dd7070Spatrick     /// Fetches the exit block for the current OpenMP construct.
1461e5dd7070Spatrick     JumpDest getExitBlock() const { return Stack.back().ExitBlock; }
1462e5dd7070Spatrick     /// Emits exit block with special codegen procedure specific for the related
1463e5dd7070Spatrick     /// OpenMP construct + emits code for normal construct cleanup.
1464e5dd7070Spatrick     void emitExit(CodeGenFunction &CGF, OpenMPDirectiveKind Kind,
1465e5dd7070Spatrick                   const llvm::function_ref<void(CodeGenFunction &)> CodeGen) {
1466e5dd7070Spatrick       if (Stack.back().Kind == Kind && getExitBlock().isValid()) {
1467e5dd7070Spatrick         assert(CGF.getOMPCancelDestination(Kind).isValid());
1468e5dd7070Spatrick         assert(CGF.HaveInsertPoint());
1469e5dd7070Spatrick         assert(!Stack.back().HasBeenEmitted);
1470e5dd7070Spatrick         auto IP = CGF.Builder.saveAndClearIP();
1471e5dd7070Spatrick         CGF.EmitBlock(Stack.back().ExitBlock.getBlock());
1472e5dd7070Spatrick         CodeGen(CGF);
1473e5dd7070Spatrick         CGF.EmitBranch(Stack.back().ContBlock.getBlock());
1474e5dd7070Spatrick         CGF.Builder.restoreIP(IP);
1475e5dd7070Spatrick         Stack.back().HasBeenEmitted = true;
1476e5dd7070Spatrick       }
1477e5dd7070Spatrick       CodeGen(CGF);
1478e5dd7070Spatrick     }
1479e5dd7070Spatrick     /// Enter the cancel supporting \a Kind construct.
1480e5dd7070Spatrick     /// \param Kind OpenMP directive that supports cancel constructs.
1481e5dd7070Spatrick     /// \param HasCancel true, if the construct has inner cancel directive,
1482e5dd7070Spatrick     /// false otherwise.
1483e5dd7070Spatrick     void enter(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, bool HasCancel) {
1484e5dd7070Spatrick       Stack.push_back({Kind,
1485e5dd7070Spatrick                        HasCancel ? CGF.getJumpDestInCurrentScope("cancel.exit")
1486e5dd7070Spatrick                                  : JumpDest(),
1487e5dd7070Spatrick                        HasCancel ? CGF.getJumpDestInCurrentScope("cancel.cont")
1488e5dd7070Spatrick                                  : JumpDest()});
1489e5dd7070Spatrick     }
1490e5dd7070Spatrick     /// Emits default exit point for the cancel construct (if the special one
1491e5dd7070Spatrick     /// has not be used) + join point for cancel/normal exits.
1492e5dd7070Spatrick     void exit(CodeGenFunction &CGF) {
1493e5dd7070Spatrick       if (getExitBlock().isValid()) {
1494e5dd7070Spatrick         assert(CGF.getOMPCancelDestination(Stack.back().Kind).isValid());
1495e5dd7070Spatrick         bool HaveIP = CGF.HaveInsertPoint();
1496e5dd7070Spatrick         if (!Stack.back().HasBeenEmitted) {
1497e5dd7070Spatrick           if (HaveIP)
1498e5dd7070Spatrick             CGF.EmitBranchThroughCleanup(Stack.back().ContBlock);
1499e5dd7070Spatrick           CGF.EmitBlock(Stack.back().ExitBlock.getBlock());
1500e5dd7070Spatrick           CGF.EmitBranchThroughCleanup(Stack.back().ContBlock);
1501e5dd7070Spatrick         }
1502e5dd7070Spatrick         CGF.EmitBlock(Stack.back().ContBlock.getBlock());
1503e5dd7070Spatrick         if (!HaveIP) {
1504e5dd7070Spatrick           CGF.Builder.CreateUnreachable();
1505e5dd7070Spatrick           CGF.Builder.ClearInsertionPoint();
1506e5dd7070Spatrick         }
1507e5dd7070Spatrick       }
1508e5dd7070Spatrick       Stack.pop_back();
1509e5dd7070Spatrick     }
1510e5dd7070Spatrick   };
1511e5dd7070Spatrick   OpenMPCancelExitStack OMPCancelStack;
1512e5dd7070Spatrick 
1513a9ac8606Spatrick   /// Lower the Likelihood knowledge about the \p Cond via llvm.expect intrin.
1514a9ac8606Spatrick   llvm::Value *emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond,
1515a9ac8606Spatrick                                                     Stmt::Likelihood LH);
1516a9ac8606Spatrick 
1517e5dd7070Spatrick   CodeGenPGO PGO;
1518e5dd7070Spatrick 
1519e5dd7070Spatrick   /// Calculate branch weights appropriate for PGO data
1520a9ac8606Spatrick   llvm::MDNode *createProfileWeights(uint64_t TrueCount,
1521a9ac8606Spatrick                                      uint64_t FalseCount) const;
1522a9ac8606Spatrick   llvm::MDNode *createProfileWeights(ArrayRef<uint64_t> Weights) const;
1523e5dd7070Spatrick   llvm::MDNode *createProfileWeightsForLoop(const Stmt *Cond,
1524a9ac8606Spatrick                                             uint64_t LoopCount) const;
1525e5dd7070Spatrick 
1526e5dd7070Spatrick public:
1527e5dd7070Spatrick   /// Increment the profiler's counter for the given statement by \p StepV.
1528e5dd7070Spatrick   /// If \p StepV is null, the default increment is 1.
1529e5dd7070Spatrick   void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) {
1530a9ac8606Spatrick     if (CGM.getCodeGenOpts().hasProfileClangInstr() &&
1531*12c85518Srobert         !CurFn->hasFnAttribute(llvm::Attribute::NoProfile) &&
1532*12c85518Srobert         !CurFn->hasFnAttribute(llvm::Attribute::SkipProfile))
1533e5dd7070Spatrick       PGO.emitCounterIncrement(Builder, S, StepV);
1534e5dd7070Spatrick     PGO.setCurrentStmt(S);
1535e5dd7070Spatrick   }
1536e5dd7070Spatrick 
1537e5dd7070Spatrick   /// Get the profiler's count for the given statement.
1538e5dd7070Spatrick   uint64_t getProfileCount(const Stmt *S) {
1539*12c85518Srobert     return PGO.getStmtCount(S).value_or(0);
1540e5dd7070Spatrick   }
1541e5dd7070Spatrick 
1542e5dd7070Spatrick   /// Set the profiler's current count.
1543e5dd7070Spatrick   void setCurrentProfileCount(uint64_t Count) {
1544e5dd7070Spatrick     PGO.setCurrentRegionCount(Count);
1545e5dd7070Spatrick   }
1546e5dd7070Spatrick 
1547e5dd7070Spatrick   /// Get the profiler's current count. This is generally the count for the most
1548e5dd7070Spatrick   /// recently incremented counter.
1549e5dd7070Spatrick   uint64_t getCurrentProfileCount() {
1550e5dd7070Spatrick     return PGO.getCurrentRegionCount();
1551e5dd7070Spatrick   }
1552e5dd7070Spatrick 
1553e5dd7070Spatrick private:
1554e5dd7070Spatrick 
1555e5dd7070Spatrick   /// SwitchInsn - This is nearest current switch instruction. It is null if
1556e5dd7070Spatrick   /// current context is not in a switch.
1557e5dd7070Spatrick   llvm::SwitchInst *SwitchInsn = nullptr;
1558e5dd7070Spatrick   /// The branch weights of SwitchInsn when doing instrumentation based PGO.
1559e5dd7070Spatrick   SmallVector<uint64_t, 16> *SwitchWeights = nullptr;
1560e5dd7070Spatrick 
1561a9ac8606Spatrick   /// The likelihood attributes of the SwitchCase.
1562a9ac8606Spatrick   SmallVector<Stmt::Likelihood, 16> *SwitchLikelihood = nullptr;
1563a9ac8606Spatrick 
1564e5dd7070Spatrick   /// CaseRangeBlock - This block holds if condition check for last case
1565e5dd7070Spatrick   /// statement range in current switch instruction.
1566e5dd7070Spatrick   llvm::BasicBlock *CaseRangeBlock = nullptr;
1567e5dd7070Spatrick 
1568e5dd7070Spatrick   /// OpaqueLValues - Keeps track of the current set of opaque value
1569e5dd7070Spatrick   /// expressions.
1570e5dd7070Spatrick   llvm::DenseMap<const OpaqueValueExpr *, LValue> OpaqueLValues;
1571e5dd7070Spatrick   llvm::DenseMap<const OpaqueValueExpr *, RValue> OpaqueRValues;
1572e5dd7070Spatrick 
1573e5dd7070Spatrick   // VLASizeMap - This keeps track of the associated size for each VLA type.
1574e5dd7070Spatrick   // We track this by the size expression rather than the type itself because
1575e5dd7070Spatrick   // in certain situations, like a const qualifier applied to an VLA typedef,
1576e5dd7070Spatrick   // multiple VLA types can share the same size expression.
1577e5dd7070Spatrick   // FIXME: Maybe this could be a stack of maps that is pushed/popped as we
1578e5dd7070Spatrick   // enter/leave scopes.
1579e5dd7070Spatrick   llvm::DenseMap<const Expr*, llvm::Value*> VLASizeMap;
1580e5dd7070Spatrick 
1581e5dd7070Spatrick   /// A block containing a single 'unreachable' instruction.  Created
1582e5dd7070Spatrick   /// lazily by getUnreachableBlock().
1583e5dd7070Spatrick   llvm::BasicBlock *UnreachableBlock = nullptr;
1584e5dd7070Spatrick 
1585e5dd7070Spatrick   /// Counts of the number return expressions in the function.
1586e5dd7070Spatrick   unsigned NumReturnExprs = 0;
1587e5dd7070Spatrick 
1588e5dd7070Spatrick   /// Count the number of simple (constant) return expressions in the function.
1589e5dd7070Spatrick   unsigned NumSimpleReturnExprs = 0;
1590e5dd7070Spatrick 
1591e5dd7070Spatrick   /// The last regular (non-return) debug location (breakpoint) in the function.
1592e5dd7070Spatrick   SourceLocation LastStopPoint;
1593e5dd7070Spatrick 
1594e5dd7070Spatrick public:
1595e5dd7070Spatrick   /// Source location information about the default argument or member
1596e5dd7070Spatrick   /// initializer expression we're evaluating, if any.
1597e5dd7070Spatrick   CurrentSourceLocExprScope CurSourceLocExprScope;
1598e5dd7070Spatrick   using SourceLocExprScopeGuard =
1599e5dd7070Spatrick       CurrentSourceLocExprScope::SourceLocExprScopeGuard;
1600e5dd7070Spatrick 
1601e5dd7070Spatrick   /// A scope within which we are constructing the fields of an object which
1602e5dd7070Spatrick   /// might use a CXXDefaultInitExpr. This stashes away a 'this' value to use
1603e5dd7070Spatrick   /// if we need to evaluate a CXXDefaultInitExpr within the evaluation.
1604e5dd7070Spatrick   class FieldConstructionScope {
1605e5dd7070Spatrick   public:
1606e5dd7070Spatrick     FieldConstructionScope(CodeGenFunction &CGF, Address This)
1607e5dd7070Spatrick         : CGF(CGF), OldCXXDefaultInitExprThis(CGF.CXXDefaultInitExprThis) {
1608e5dd7070Spatrick       CGF.CXXDefaultInitExprThis = This;
1609e5dd7070Spatrick     }
1610e5dd7070Spatrick     ~FieldConstructionScope() {
1611e5dd7070Spatrick       CGF.CXXDefaultInitExprThis = OldCXXDefaultInitExprThis;
1612e5dd7070Spatrick     }
1613e5dd7070Spatrick 
1614e5dd7070Spatrick   private:
1615e5dd7070Spatrick     CodeGenFunction &CGF;
1616e5dd7070Spatrick     Address OldCXXDefaultInitExprThis;
1617e5dd7070Spatrick   };
1618e5dd7070Spatrick 
1619e5dd7070Spatrick   /// The scope of a CXXDefaultInitExpr. Within this scope, the value of 'this'
1620e5dd7070Spatrick   /// is overridden to be the object under construction.
1621e5dd7070Spatrick   class CXXDefaultInitExprScope  {
1622e5dd7070Spatrick   public:
1623e5dd7070Spatrick     CXXDefaultInitExprScope(CodeGenFunction &CGF, const CXXDefaultInitExpr *E)
1624e5dd7070Spatrick         : CGF(CGF), OldCXXThisValue(CGF.CXXThisValue),
1625e5dd7070Spatrick           OldCXXThisAlignment(CGF.CXXThisAlignment),
1626e5dd7070Spatrick           SourceLocScope(E, CGF.CurSourceLocExprScope) {
1627e5dd7070Spatrick       CGF.CXXThisValue = CGF.CXXDefaultInitExprThis.getPointer();
1628e5dd7070Spatrick       CGF.CXXThisAlignment = CGF.CXXDefaultInitExprThis.getAlignment();
1629e5dd7070Spatrick     }
1630e5dd7070Spatrick     ~CXXDefaultInitExprScope() {
1631e5dd7070Spatrick       CGF.CXXThisValue = OldCXXThisValue;
1632e5dd7070Spatrick       CGF.CXXThisAlignment = OldCXXThisAlignment;
1633e5dd7070Spatrick     }
1634e5dd7070Spatrick 
1635e5dd7070Spatrick   public:
1636e5dd7070Spatrick     CodeGenFunction &CGF;
1637e5dd7070Spatrick     llvm::Value *OldCXXThisValue;
1638e5dd7070Spatrick     CharUnits OldCXXThisAlignment;
1639e5dd7070Spatrick     SourceLocExprScopeGuard SourceLocScope;
1640e5dd7070Spatrick   };
1641e5dd7070Spatrick 
1642e5dd7070Spatrick   struct CXXDefaultArgExprScope : SourceLocExprScopeGuard {
1643e5dd7070Spatrick     CXXDefaultArgExprScope(CodeGenFunction &CGF, const CXXDefaultArgExpr *E)
1644e5dd7070Spatrick         : SourceLocExprScopeGuard(E, CGF.CurSourceLocExprScope) {}
1645e5dd7070Spatrick   };
1646e5dd7070Spatrick 
1647e5dd7070Spatrick   /// The scope of an ArrayInitLoopExpr. Within this scope, the value of the
1648e5dd7070Spatrick   /// current loop index is overridden.
1649e5dd7070Spatrick   class ArrayInitLoopExprScope {
1650e5dd7070Spatrick   public:
1651e5dd7070Spatrick     ArrayInitLoopExprScope(CodeGenFunction &CGF, llvm::Value *Index)
1652e5dd7070Spatrick       : CGF(CGF), OldArrayInitIndex(CGF.ArrayInitIndex) {
1653e5dd7070Spatrick       CGF.ArrayInitIndex = Index;
1654e5dd7070Spatrick     }
1655e5dd7070Spatrick     ~ArrayInitLoopExprScope() {
1656e5dd7070Spatrick       CGF.ArrayInitIndex = OldArrayInitIndex;
1657e5dd7070Spatrick     }
1658e5dd7070Spatrick 
1659e5dd7070Spatrick   private:
1660e5dd7070Spatrick     CodeGenFunction &CGF;
1661e5dd7070Spatrick     llvm::Value *OldArrayInitIndex;
1662e5dd7070Spatrick   };
1663e5dd7070Spatrick 
1664e5dd7070Spatrick   class InlinedInheritingConstructorScope {
1665e5dd7070Spatrick   public:
1666e5dd7070Spatrick     InlinedInheritingConstructorScope(CodeGenFunction &CGF, GlobalDecl GD)
1667e5dd7070Spatrick         : CGF(CGF), OldCurGD(CGF.CurGD), OldCurFuncDecl(CGF.CurFuncDecl),
1668e5dd7070Spatrick           OldCurCodeDecl(CGF.CurCodeDecl),
1669e5dd7070Spatrick           OldCXXABIThisDecl(CGF.CXXABIThisDecl),
1670e5dd7070Spatrick           OldCXXABIThisValue(CGF.CXXABIThisValue),
1671e5dd7070Spatrick           OldCXXThisValue(CGF.CXXThisValue),
1672e5dd7070Spatrick           OldCXXABIThisAlignment(CGF.CXXABIThisAlignment),
1673e5dd7070Spatrick           OldCXXThisAlignment(CGF.CXXThisAlignment),
1674e5dd7070Spatrick           OldReturnValue(CGF.ReturnValue), OldFnRetTy(CGF.FnRetTy),
1675e5dd7070Spatrick           OldCXXInheritedCtorInitExprArgs(
1676e5dd7070Spatrick               std::move(CGF.CXXInheritedCtorInitExprArgs)) {
1677e5dd7070Spatrick       CGF.CurGD = GD;
1678e5dd7070Spatrick       CGF.CurFuncDecl = CGF.CurCodeDecl =
1679e5dd7070Spatrick           cast<CXXConstructorDecl>(GD.getDecl());
1680e5dd7070Spatrick       CGF.CXXABIThisDecl = nullptr;
1681e5dd7070Spatrick       CGF.CXXABIThisValue = nullptr;
1682e5dd7070Spatrick       CGF.CXXThisValue = nullptr;
1683e5dd7070Spatrick       CGF.CXXABIThisAlignment = CharUnits();
1684e5dd7070Spatrick       CGF.CXXThisAlignment = CharUnits();
1685e5dd7070Spatrick       CGF.ReturnValue = Address::invalid();
1686e5dd7070Spatrick       CGF.FnRetTy = QualType();
1687e5dd7070Spatrick       CGF.CXXInheritedCtorInitExprArgs.clear();
1688e5dd7070Spatrick     }
1689e5dd7070Spatrick     ~InlinedInheritingConstructorScope() {
1690e5dd7070Spatrick       CGF.CurGD = OldCurGD;
1691e5dd7070Spatrick       CGF.CurFuncDecl = OldCurFuncDecl;
1692e5dd7070Spatrick       CGF.CurCodeDecl = OldCurCodeDecl;
1693e5dd7070Spatrick       CGF.CXXABIThisDecl = OldCXXABIThisDecl;
1694e5dd7070Spatrick       CGF.CXXABIThisValue = OldCXXABIThisValue;
1695e5dd7070Spatrick       CGF.CXXThisValue = OldCXXThisValue;
1696e5dd7070Spatrick       CGF.CXXABIThisAlignment = OldCXXABIThisAlignment;
1697e5dd7070Spatrick       CGF.CXXThisAlignment = OldCXXThisAlignment;
1698e5dd7070Spatrick       CGF.ReturnValue = OldReturnValue;
1699e5dd7070Spatrick       CGF.FnRetTy = OldFnRetTy;
1700e5dd7070Spatrick       CGF.CXXInheritedCtorInitExprArgs =
1701e5dd7070Spatrick           std::move(OldCXXInheritedCtorInitExprArgs);
1702e5dd7070Spatrick     }
1703e5dd7070Spatrick 
1704e5dd7070Spatrick   private:
1705e5dd7070Spatrick     CodeGenFunction &CGF;
1706e5dd7070Spatrick     GlobalDecl OldCurGD;
1707e5dd7070Spatrick     const Decl *OldCurFuncDecl;
1708e5dd7070Spatrick     const Decl *OldCurCodeDecl;
1709e5dd7070Spatrick     ImplicitParamDecl *OldCXXABIThisDecl;
1710e5dd7070Spatrick     llvm::Value *OldCXXABIThisValue;
1711e5dd7070Spatrick     llvm::Value *OldCXXThisValue;
1712e5dd7070Spatrick     CharUnits OldCXXABIThisAlignment;
1713e5dd7070Spatrick     CharUnits OldCXXThisAlignment;
1714e5dd7070Spatrick     Address OldReturnValue;
1715e5dd7070Spatrick     QualType OldFnRetTy;
1716e5dd7070Spatrick     CallArgList OldCXXInheritedCtorInitExprArgs;
1717e5dd7070Spatrick   };
1718e5dd7070Spatrick 
1719ec727ea7Spatrick   // Helper class for the OpenMP IR Builder. Allows reusability of code used for
1720ec727ea7Spatrick   // region body, and finalization codegen callbacks. This will class will also
1721ec727ea7Spatrick   // contain privatization functions used by the privatization call backs
1722ec727ea7Spatrick   //
1723ec727ea7Spatrick   // TODO: this is temporary class for things that are being moved out of
1724ec727ea7Spatrick   // CGOpenMPRuntime, new versions of current CodeGenFunction methods, or
1725ec727ea7Spatrick   // utility function for use with the OMPBuilder. Once that move to use the
1726ec727ea7Spatrick   // OMPBuilder is done, everything here will either become part of CodeGenFunc.
1727ec727ea7Spatrick   // directly, or a new helper class that will contain functions used by both
1728ec727ea7Spatrick   // this and the OMPBuilder
1729ec727ea7Spatrick 
1730ec727ea7Spatrick   struct OMPBuilderCBHelpers {
1731ec727ea7Spatrick 
1732ec727ea7Spatrick     OMPBuilderCBHelpers() = delete;
1733ec727ea7Spatrick     OMPBuilderCBHelpers(const OMPBuilderCBHelpers &) = delete;
1734ec727ea7Spatrick     OMPBuilderCBHelpers &operator=(const OMPBuilderCBHelpers &) = delete;
1735ec727ea7Spatrick 
1736ec727ea7Spatrick     using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
1737ec727ea7Spatrick 
1738ec727ea7Spatrick     /// Cleanup action for allocate support.
1739ec727ea7Spatrick     class OMPAllocateCleanupTy final : public EHScopeStack::Cleanup {
1740ec727ea7Spatrick 
1741ec727ea7Spatrick     private:
1742ec727ea7Spatrick       llvm::CallInst *RTLFnCI;
1743ec727ea7Spatrick 
1744ec727ea7Spatrick     public:
1745ec727ea7Spatrick       OMPAllocateCleanupTy(llvm::CallInst *RLFnCI) : RTLFnCI(RLFnCI) {
1746ec727ea7Spatrick         RLFnCI->removeFromParent();
1747ec727ea7Spatrick       }
1748ec727ea7Spatrick 
1749ec727ea7Spatrick       void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
1750ec727ea7Spatrick         if (!CGF.HaveInsertPoint())
1751ec727ea7Spatrick           return;
1752ec727ea7Spatrick         CGF.Builder.Insert(RTLFnCI);
1753ec727ea7Spatrick       }
1754ec727ea7Spatrick     };
1755ec727ea7Spatrick 
1756ec727ea7Spatrick     /// Returns address of the threadprivate variable for the current
1757ec727ea7Spatrick     /// thread. This Also create any necessary OMP runtime calls.
1758ec727ea7Spatrick     ///
1759ec727ea7Spatrick     /// \param VD VarDecl for Threadprivate variable.
1760ec727ea7Spatrick     /// \param VDAddr Address of the Vardecl
1761ec727ea7Spatrick     /// \param Loc  The location where the barrier directive was encountered
1762ec727ea7Spatrick     static Address getAddrOfThreadPrivate(CodeGenFunction &CGF,
1763ec727ea7Spatrick                                           const VarDecl *VD, Address VDAddr,
1764ec727ea7Spatrick                                           SourceLocation Loc);
1765ec727ea7Spatrick 
1766ec727ea7Spatrick     /// Gets the OpenMP-specific address of the local variable /p VD.
1767ec727ea7Spatrick     static Address getAddressOfLocalVariable(CodeGenFunction &CGF,
1768ec727ea7Spatrick                                              const VarDecl *VD);
1769ec727ea7Spatrick     /// Get the platform-specific name separator.
1770ec727ea7Spatrick     /// \param Parts different parts of the final name that needs separation
1771ec727ea7Spatrick     /// \param FirstSeparator First separator used between the initial two
1772ec727ea7Spatrick     ///        parts of the name.
1773ec727ea7Spatrick     /// \param Separator separator used between all of the rest consecutinve
1774ec727ea7Spatrick     ///        parts of the name
1775ec727ea7Spatrick     static std::string getNameWithSeparators(ArrayRef<StringRef> Parts,
1776ec727ea7Spatrick                                              StringRef FirstSeparator = ".",
1777ec727ea7Spatrick                                              StringRef Separator = ".");
1778ec727ea7Spatrick     /// Emit the Finalization for an OMP region
1779ec727ea7Spatrick     /// \param CGF	The Codegen function this belongs to
1780ec727ea7Spatrick     /// \param IP	Insertion point for generating the finalization code.
1781ec727ea7Spatrick     static void FinalizeOMPRegion(CodeGenFunction &CGF, InsertPointTy IP) {
1782ec727ea7Spatrick       CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
1783ec727ea7Spatrick       assert(IP.getBlock()->end() != IP.getPoint() &&
1784ec727ea7Spatrick              "OpenMP IR Builder should cause terminated block!");
1785ec727ea7Spatrick 
1786ec727ea7Spatrick       llvm::BasicBlock *IPBB = IP.getBlock();
1787ec727ea7Spatrick       llvm::BasicBlock *DestBB = IPBB->getUniqueSuccessor();
1788ec727ea7Spatrick       assert(DestBB && "Finalization block should have one successor!");
1789ec727ea7Spatrick 
1790ec727ea7Spatrick       // erase and replace with cleanup branch.
1791ec727ea7Spatrick       IPBB->getTerminator()->eraseFromParent();
1792ec727ea7Spatrick       CGF.Builder.SetInsertPoint(IPBB);
1793ec727ea7Spatrick       CodeGenFunction::JumpDest Dest = CGF.getJumpDestInCurrentScope(DestBB);
1794ec727ea7Spatrick       CGF.EmitBranchThroughCleanup(Dest);
1795ec727ea7Spatrick     }
1796ec727ea7Spatrick 
1797ec727ea7Spatrick     /// Emit the body of an OMP region
1798ec727ea7Spatrick     /// \param CGF	          The Codegen function this belongs to
1799ec727ea7Spatrick     /// \param RegionBodyStmt The body statement for the OpenMP region being
1800ec727ea7Spatrick     ///                       generated
1801*12c85518Srobert     /// \param AllocaIP       Where to insert alloca instructions
1802*12c85518Srobert     /// \param CodeGenIP      Where to insert the region code
1803*12c85518Srobert     /// \param RegionName     Name to be used for new blocks
1804*12c85518Srobert     static void EmitOMPInlinedRegionBody(CodeGenFunction &CGF,
1805ec727ea7Spatrick                                          const Stmt *RegionBodyStmt,
1806*12c85518Srobert                                          InsertPointTy AllocaIP,
1807ec727ea7Spatrick                                          InsertPointTy CodeGenIP,
1808*12c85518Srobert                                          Twine RegionName);
1809*12c85518Srobert 
1810*12c85518Srobert     static void EmitCaptureStmt(CodeGenFunction &CGF, InsertPointTy CodeGenIP,
1811*12c85518Srobert                                 llvm::BasicBlock &FiniBB, llvm::Function *Fn,
1812*12c85518Srobert                                 ArrayRef<llvm::Value *> Args) {
1813ec727ea7Spatrick       llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock();
1814ec727ea7Spatrick       if (llvm::Instruction *CodeGenIPBBTI = CodeGenIPBB->getTerminator())
1815ec727ea7Spatrick         CodeGenIPBBTI->eraseFromParent();
1816ec727ea7Spatrick 
1817ec727ea7Spatrick       CGF.Builder.SetInsertPoint(CodeGenIPBB);
1818ec727ea7Spatrick 
1819*12c85518Srobert       if (Fn->doesNotThrow())
1820*12c85518Srobert         CGF.EmitNounwindRuntimeCall(Fn, Args);
1821*12c85518Srobert       else
1822*12c85518Srobert         CGF.EmitRuntimeCall(Fn, Args);
1823ec727ea7Spatrick 
1824ec727ea7Spatrick       if (CGF.Builder.saveIP().isSet())
1825ec727ea7Spatrick         CGF.Builder.CreateBr(&FiniBB);
1826ec727ea7Spatrick     }
1827ec727ea7Spatrick 
1828*12c85518Srobert     /// Emit the body of an OMP region that will be outlined in
1829*12c85518Srobert     /// OpenMPIRBuilder::finalize().
1830*12c85518Srobert     /// \param CGF	          The Codegen function this belongs to
1831*12c85518Srobert     /// \param RegionBodyStmt The body statement for the OpenMP region being
1832*12c85518Srobert     ///                       generated
1833*12c85518Srobert     /// \param AllocaIP       Where to insert alloca instructions
1834*12c85518Srobert     /// \param CodeGenIP      Where to insert the region code
1835*12c85518Srobert     /// \param RegionName     Name to be used for new blocks
1836*12c85518Srobert     static void EmitOMPOutlinedRegionBody(CodeGenFunction &CGF,
1837*12c85518Srobert                                           const Stmt *RegionBodyStmt,
1838*12c85518Srobert                                           InsertPointTy AllocaIP,
1839*12c85518Srobert                                           InsertPointTy CodeGenIP,
1840*12c85518Srobert                                           Twine RegionName);
1841*12c85518Srobert 
1842ec727ea7Spatrick     /// RAII for preserving necessary info during Outlined region body codegen.
1843ec727ea7Spatrick     class OutlinedRegionBodyRAII {
1844ec727ea7Spatrick 
1845ec727ea7Spatrick       llvm::AssertingVH<llvm::Instruction> OldAllocaIP;
1846ec727ea7Spatrick       CodeGenFunction::JumpDest OldReturnBlock;
1847ec727ea7Spatrick       CodeGenFunction &CGF;
1848ec727ea7Spatrick 
1849ec727ea7Spatrick     public:
1850ec727ea7Spatrick       OutlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP,
1851ec727ea7Spatrick                              llvm::BasicBlock &RetBB)
1852ec727ea7Spatrick           : CGF(cgf) {
1853ec727ea7Spatrick         assert(AllocaIP.isSet() &&
1854ec727ea7Spatrick                "Must specify Insertion point for allocas of outlined function");
1855ec727ea7Spatrick         OldAllocaIP = CGF.AllocaInsertPt;
1856ec727ea7Spatrick         CGF.AllocaInsertPt = &*AllocaIP.getPoint();
1857ec727ea7Spatrick 
1858ec727ea7Spatrick         OldReturnBlock = CGF.ReturnBlock;
1859ec727ea7Spatrick         CGF.ReturnBlock = CGF.getJumpDestInCurrentScope(&RetBB);
1860ec727ea7Spatrick       }
1861ec727ea7Spatrick 
1862ec727ea7Spatrick       ~OutlinedRegionBodyRAII() {
1863ec727ea7Spatrick         CGF.AllocaInsertPt = OldAllocaIP;
1864ec727ea7Spatrick         CGF.ReturnBlock = OldReturnBlock;
1865ec727ea7Spatrick       }
1866ec727ea7Spatrick     };
1867ec727ea7Spatrick 
1868ec727ea7Spatrick     /// RAII for preserving necessary info during inlined region body codegen.
1869ec727ea7Spatrick     class InlinedRegionBodyRAII {
1870ec727ea7Spatrick 
1871ec727ea7Spatrick       llvm::AssertingVH<llvm::Instruction> OldAllocaIP;
1872ec727ea7Spatrick       CodeGenFunction &CGF;
1873ec727ea7Spatrick 
1874ec727ea7Spatrick     public:
1875ec727ea7Spatrick       InlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP,
1876ec727ea7Spatrick                             llvm::BasicBlock &FiniBB)
1877ec727ea7Spatrick           : CGF(cgf) {
1878ec727ea7Spatrick         // Alloca insertion block should be in the entry block of the containing
1879ec727ea7Spatrick         // function so it expects an empty AllocaIP in which case will reuse the
1880ec727ea7Spatrick         // old alloca insertion point, or a new AllocaIP in the same block as
1881ec727ea7Spatrick         // the old one
1882ec727ea7Spatrick         assert((!AllocaIP.isSet() ||
1883ec727ea7Spatrick                 CGF.AllocaInsertPt->getParent() == AllocaIP.getBlock()) &&
1884ec727ea7Spatrick                "Insertion point should be in the entry block of containing "
1885ec727ea7Spatrick                "function!");
1886ec727ea7Spatrick         OldAllocaIP = CGF.AllocaInsertPt;
1887ec727ea7Spatrick         if (AllocaIP.isSet())
1888ec727ea7Spatrick           CGF.AllocaInsertPt = &*AllocaIP.getPoint();
1889ec727ea7Spatrick 
1890ec727ea7Spatrick         // TODO: Remove the call, after making sure the counter is not used by
1891ec727ea7Spatrick         //       the EHStack.
1892ec727ea7Spatrick         // Since this is an inlined region, it should not modify the
1893ec727ea7Spatrick         // ReturnBlock, and should reuse the one for the enclosing outlined
1894ec727ea7Spatrick         // region. So, the JumpDest being return by the function is discarded
1895ec727ea7Spatrick         (void)CGF.getJumpDestInCurrentScope(&FiniBB);
1896ec727ea7Spatrick       }
1897ec727ea7Spatrick 
1898ec727ea7Spatrick       ~InlinedRegionBodyRAII() { CGF.AllocaInsertPt = OldAllocaIP; }
1899ec727ea7Spatrick     };
1900ec727ea7Spatrick   };
1901ec727ea7Spatrick 
1902e5dd7070Spatrick private:
1903e5dd7070Spatrick   /// CXXThisDecl - When generating code for a C++ member function,
1904e5dd7070Spatrick   /// this will hold the implicit 'this' declaration.
1905e5dd7070Spatrick   ImplicitParamDecl *CXXABIThisDecl = nullptr;
1906e5dd7070Spatrick   llvm::Value *CXXABIThisValue = nullptr;
1907e5dd7070Spatrick   llvm::Value *CXXThisValue = nullptr;
1908e5dd7070Spatrick   CharUnits CXXABIThisAlignment;
1909e5dd7070Spatrick   CharUnits CXXThisAlignment;
1910e5dd7070Spatrick 
1911e5dd7070Spatrick   /// The value of 'this' to use when evaluating CXXDefaultInitExprs within
1912e5dd7070Spatrick   /// this expression.
1913e5dd7070Spatrick   Address CXXDefaultInitExprThis = Address::invalid();
1914e5dd7070Spatrick 
1915e5dd7070Spatrick   /// The current array initialization index when evaluating an
1916e5dd7070Spatrick   /// ArrayInitIndexExpr within an ArrayInitLoopExpr.
1917e5dd7070Spatrick   llvm::Value *ArrayInitIndex = nullptr;
1918e5dd7070Spatrick 
1919e5dd7070Spatrick   /// The values of function arguments to use when evaluating
1920e5dd7070Spatrick   /// CXXInheritedCtorInitExprs within this context.
1921e5dd7070Spatrick   CallArgList CXXInheritedCtorInitExprArgs;
1922e5dd7070Spatrick 
1923e5dd7070Spatrick   /// CXXStructorImplicitParamDecl - When generating code for a constructor or
1924e5dd7070Spatrick   /// destructor, this will hold the implicit argument (e.g. VTT).
1925e5dd7070Spatrick   ImplicitParamDecl *CXXStructorImplicitParamDecl = nullptr;
1926e5dd7070Spatrick   llvm::Value *CXXStructorImplicitParamValue = nullptr;
1927e5dd7070Spatrick 
1928e5dd7070Spatrick   /// OutermostConditional - Points to the outermost active
1929e5dd7070Spatrick   /// conditional control.  This is used so that we know if a
1930e5dd7070Spatrick   /// temporary should be destroyed conditionally.
1931e5dd7070Spatrick   ConditionalEvaluation *OutermostConditional = nullptr;
1932e5dd7070Spatrick 
1933e5dd7070Spatrick   /// The current lexical scope.
1934e5dd7070Spatrick   LexicalScope *CurLexicalScope = nullptr;
1935e5dd7070Spatrick 
1936e5dd7070Spatrick   /// The current source location that should be used for exception
1937e5dd7070Spatrick   /// handling code.
1938e5dd7070Spatrick   SourceLocation CurEHLocation;
1939e5dd7070Spatrick 
1940e5dd7070Spatrick   /// BlockByrefInfos - For each __block variable, contains
1941e5dd7070Spatrick   /// information about the layout of the variable.
1942e5dd7070Spatrick   llvm::DenseMap<const ValueDecl *, BlockByrefInfo> BlockByrefInfos;
1943e5dd7070Spatrick 
1944e5dd7070Spatrick   /// Used by -fsanitize=nullability-return to determine whether the return
1945e5dd7070Spatrick   /// value can be checked.
1946e5dd7070Spatrick   llvm::Value *RetValNullabilityPrecondition = nullptr;
1947e5dd7070Spatrick 
1948e5dd7070Spatrick   /// Check if -fsanitize=nullability-return instrumentation is required for
1949e5dd7070Spatrick   /// this function.
1950e5dd7070Spatrick   bool requiresReturnValueNullabilityCheck() const {
1951e5dd7070Spatrick     return RetValNullabilityPrecondition;
1952e5dd7070Spatrick   }
1953e5dd7070Spatrick 
1954e5dd7070Spatrick   /// Used to store precise source locations for return statements by the
1955e5dd7070Spatrick   /// runtime return value checks.
1956e5dd7070Spatrick   Address ReturnLocation = Address::invalid();
1957e5dd7070Spatrick 
1958e5dd7070Spatrick   /// Check if the return value of this function requires sanitization.
1959e5dd7070Spatrick   bool requiresReturnValueCheck() const;
1960e5dd7070Spatrick 
1961e5dd7070Spatrick   llvm::BasicBlock *TerminateLandingPad = nullptr;
1962e5dd7070Spatrick   llvm::BasicBlock *TerminateHandler = nullptr;
1963a9ac8606Spatrick   llvm::SmallVector<llvm::BasicBlock *, 2> TrapBBs;
1964e5dd7070Spatrick 
1965e5dd7070Spatrick   /// Terminate funclets keyed by parent funclet pad.
1966e5dd7070Spatrick   llvm::MapVector<llvm::Value *, llvm::BasicBlock *> TerminateFunclets;
1967e5dd7070Spatrick 
1968e5dd7070Spatrick   /// Largest vector width used in ths function. Will be used to create a
1969e5dd7070Spatrick   /// function attribute.
1970e5dd7070Spatrick   unsigned LargestVectorWidth = 0;
1971e5dd7070Spatrick 
1972a9ac8606Spatrick   /// True if we need emit the life-time markers. This is initially set in
1973a9ac8606Spatrick   /// the constructor, but could be overwritten to true if this is a coroutine.
1974a9ac8606Spatrick   bool ShouldEmitLifetimeMarkers;
1975e5dd7070Spatrick 
1976e5dd7070Spatrick   /// Add OpenCL kernel arg metadata and the kernel attribute metadata to
1977e5dd7070Spatrick   /// the function metadata.
1978*12c85518Srobert   void EmitKernelMetadata(const FunctionDecl *FD, llvm::Function *Fn);
1979e5dd7070Spatrick 
1980e5dd7070Spatrick public:
1981e5dd7070Spatrick   CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext=false);
1982e5dd7070Spatrick   ~CodeGenFunction();
1983e5dd7070Spatrick 
1984e5dd7070Spatrick   CodeGenTypes &getTypes() const { return CGM.getTypes(); }
1985e5dd7070Spatrick   ASTContext &getContext() const { return CGM.getContext(); }
1986e5dd7070Spatrick   CGDebugInfo *getDebugInfo() {
1987e5dd7070Spatrick     if (DisableDebugInfo)
1988e5dd7070Spatrick       return nullptr;
1989e5dd7070Spatrick     return DebugInfo;
1990e5dd7070Spatrick   }
1991e5dd7070Spatrick   void disableDebugInfo() { DisableDebugInfo = true; }
1992e5dd7070Spatrick   void enableDebugInfo() { DisableDebugInfo = false; }
1993e5dd7070Spatrick 
1994e5dd7070Spatrick   bool shouldUseFusedARCCalls() {
1995e5dd7070Spatrick     return CGM.getCodeGenOpts().OptimizationLevel == 0;
1996e5dd7070Spatrick   }
1997e5dd7070Spatrick 
1998e5dd7070Spatrick   const LangOptions &getLangOpts() const { return CGM.getLangOpts(); }
1999e5dd7070Spatrick 
2000e5dd7070Spatrick   /// Returns a pointer to the function's exception object and selector slot,
2001e5dd7070Spatrick   /// which is assigned in every landing pad.
2002e5dd7070Spatrick   Address getExceptionSlot();
2003e5dd7070Spatrick   Address getEHSelectorSlot();
2004e5dd7070Spatrick 
2005e5dd7070Spatrick   /// Returns the contents of the function's exception object and selector
2006e5dd7070Spatrick   /// slots.
2007e5dd7070Spatrick   llvm::Value *getExceptionFromSlot();
2008e5dd7070Spatrick   llvm::Value *getSelectorFromSlot();
2009e5dd7070Spatrick 
2010e5dd7070Spatrick   Address getNormalCleanupDestSlot();
2011e5dd7070Spatrick 
2012e5dd7070Spatrick   llvm::BasicBlock *getUnreachableBlock() {
2013e5dd7070Spatrick     if (!UnreachableBlock) {
2014e5dd7070Spatrick       UnreachableBlock = createBasicBlock("unreachable");
2015e5dd7070Spatrick       new llvm::UnreachableInst(getLLVMContext(), UnreachableBlock);
2016e5dd7070Spatrick     }
2017e5dd7070Spatrick     return UnreachableBlock;
2018e5dd7070Spatrick   }
2019e5dd7070Spatrick 
2020e5dd7070Spatrick   llvm::BasicBlock *getInvokeDest() {
2021e5dd7070Spatrick     if (!EHStack.requiresLandingPad()) return nullptr;
2022e5dd7070Spatrick     return getInvokeDestImpl();
2023e5dd7070Spatrick   }
2024e5dd7070Spatrick 
2025*12c85518Srobert   bool currentFunctionUsesSEHTry() const { return !!CurSEHParent; }
2026e5dd7070Spatrick 
2027e5dd7070Spatrick   const TargetInfo &getTarget() const { return Target; }
2028e5dd7070Spatrick   llvm::LLVMContext &getLLVMContext() { return CGM.getLLVMContext(); }
2029e5dd7070Spatrick   const TargetCodeGenInfo &getTargetHooks() const {
2030e5dd7070Spatrick     return CGM.getTargetCodeGenInfo();
2031e5dd7070Spatrick   }
2032e5dd7070Spatrick 
2033e5dd7070Spatrick   //===--------------------------------------------------------------------===//
2034e5dd7070Spatrick   //                                  Cleanups
2035e5dd7070Spatrick   //===--------------------------------------------------------------------===//
2036e5dd7070Spatrick 
2037e5dd7070Spatrick   typedef void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty);
2038e5dd7070Spatrick 
2039e5dd7070Spatrick   void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
2040e5dd7070Spatrick                                         Address arrayEndPointer,
2041e5dd7070Spatrick                                         QualType elementType,
2042e5dd7070Spatrick                                         CharUnits elementAlignment,
2043e5dd7070Spatrick                                         Destroyer *destroyer);
2044e5dd7070Spatrick   void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin,
2045e5dd7070Spatrick                                       llvm::Value *arrayEnd,
2046e5dd7070Spatrick                                       QualType elementType,
2047e5dd7070Spatrick                                       CharUnits elementAlignment,
2048e5dd7070Spatrick                                       Destroyer *destroyer);
2049e5dd7070Spatrick 
2050e5dd7070Spatrick   void pushDestroy(QualType::DestructionKind dtorKind,
2051e5dd7070Spatrick                    Address addr, QualType type);
2052e5dd7070Spatrick   void pushEHDestroy(QualType::DestructionKind dtorKind,
2053e5dd7070Spatrick                      Address addr, QualType type);
2054e5dd7070Spatrick   void pushDestroy(CleanupKind kind, Address addr, QualType type,
2055e5dd7070Spatrick                    Destroyer *destroyer, bool useEHCleanupForArray);
2056e5dd7070Spatrick   void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr,
2057e5dd7070Spatrick                                    QualType type, Destroyer *destroyer,
2058e5dd7070Spatrick                                    bool useEHCleanupForArray);
2059e5dd7070Spatrick   void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete,
2060e5dd7070Spatrick                                    llvm::Value *CompletePtr,
2061e5dd7070Spatrick                                    QualType ElementType);
2062e5dd7070Spatrick   void pushStackRestore(CleanupKind kind, Address SPMem);
2063e5dd7070Spatrick   void emitDestroy(Address addr, QualType type, Destroyer *destroyer,
2064e5dd7070Spatrick                    bool useEHCleanupForArray);
2065e5dd7070Spatrick   llvm::Function *generateDestroyHelper(Address addr, QualType type,
2066e5dd7070Spatrick                                         Destroyer *destroyer,
2067e5dd7070Spatrick                                         bool useEHCleanupForArray,
2068e5dd7070Spatrick                                         const VarDecl *VD);
2069e5dd7070Spatrick   void emitArrayDestroy(llvm::Value *begin, llvm::Value *end,
2070e5dd7070Spatrick                         QualType elementType, CharUnits elementAlign,
2071e5dd7070Spatrick                         Destroyer *destroyer,
2072e5dd7070Spatrick                         bool checkZeroLength, bool useEHCleanup);
2073e5dd7070Spatrick 
2074e5dd7070Spatrick   Destroyer *getDestroyer(QualType::DestructionKind destructionKind);
2075e5dd7070Spatrick 
2076e5dd7070Spatrick   /// Determines whether an EH cleanup is required to destroy a type
2077e5dd7070Spatrick   /// with the given destruction kind.
2078e5dd7070Spatrick   bool needsEHCleanup(QualType::DestructionKind kind) {
2079e5dd7070Spatrick     switch (kind) {
2080e5dd7070Spatrick     case QualType::DK_none:
2081e5dd7070Spatrick       return false;
2082e5dd7070Spatrick     case QualType::DK_cxx_destructor:
2083e5dd7070Spatrick     case QualType::DK_objc_weak_lifetime:
2084e5dd7070Spatrick     case QualType::DK_nontrivial_c_struct:
2085e5dd7070Spatrick       return getLangOpts().Exceptions;
2086e5dd7070Spatrick     case QualType::DK_objc_strong_lifetime:
2087e5dd7070Spatrick       return getLangOpts().Exceptions &&
2088e5dd7070Spatrick              CGM.getCodeGenOpts().ObjCAutoRefCountExceptions;
2089e5dd7070Spatrick     }
2090e5dd7070Spatrick     llvm_unreachable("bad destruction kind");
2091e5dd7070Spatrick   }
2092e5dd7070Spatrick 
2093e5dd7070Spatrick   CleanupKind getCleanupKind(QualType::DestructionKind kind) {
2094e5dd7070Spatrick     return (needsEHCleanup(kind) ? NormalAndEHCleanup : NormalCleanup);
2095e5dd7070Spatrick   }
2096e5dd7070Spatrick 
2097e5dd7070Spatrick   //===--------------------------------------------------------------------===//
2098e5dd7070Spatrick   //                                  Objective-C
2099e5dd7070Spatrick   //===--------------------------------------------------------------------===//
2100e5dd7070Spatrick 
2101e5dd7070Spatrick   void GenerateObjCMethod(const ObjCMethodDecl *OMD);
2102e5dd7070Spatrick 
2103e5dd7070Spatrick   void StartObjCMethod(const ObjCMethodDecl *MD, const ObjCContainerDecl *CD);
2104e5dd7070Spatrick 
2105e5dd7070Spatrick   /// GenerateObjCGetter - Synthesize an Objective-C property getter function.
2106e5dd7070Spatrick   void GenerateObjCGetter(ObjCImplementationDecl *IMP,
2107e5dd7070Spatrick                           const ObjCPropertyImplDecl *PID);
2108e5dd7070Spatrick   void generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
2109e5dd7070Spatrick                               const ObjCPropertyImplDecl *propImpl,
2110e5dd7070Spatrick                               const ObjCMethodDecl *GetterMothodDecl,
2111e5dd7070Spatrick                               llvm::Constant *AtomicHelperFn);
2112e5dd7070Spatrick 
2113e5dd7070Spatrick   void GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
2114e5dd7070Spatrick                                   ObjCMethodDecl *MD, bool ctor);
2115e5dd7070Spatrick 
2116e5dd7070Spatrick   /// GenerateObjCSetter - Synthesize an Objective-C property setter function
2117e5dd7070Spatrick   /// for the given property.
2118e5dd7070Spatrick   void GenerateObjCSetter(ObjCImplementationDecl *IMP,
2119e5dd7070Spatrick                           const ObjCPropertyImplDecl *PID);
2120e5dd7070Spatrick   void generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
2121e5dd7070Spatrick                               const ObjCPropertyImplDecl *propImpl,
2122e5dd7070Spatrick                               llvm::Constant *AtomicHelperFn);
2123e5dd7070Spatrick 
2124e5dd7070Spatrick   //===--------------------------------------------------------------------===//
2125e5dd7070Spatrick   //                                  Block Bits
2126e5dd7070Spatrick   //===--------------------------------------------------------------------===//
2127e5dd7070Spatrick 
2128e5dd7070Spatrick   /// Emit block literal.
2129e5dd7070Spatrick   /// \return an LLVM value which is a pointer to a struct which contains
2130e5dd7070Spatrick   /// information about the block, including the block invoke function, the
2131e5dd7070Spatrick   /// captured variables, etc.
2132e5dd7070Spatrick   llvm::Value *EmitBlockLiteral(const BlockExpr *);
2133e5dd7070Spatrick 
2134e5dd7070Spatrick   llvm::Function *GenerateBlockFunction(GlobalDecl GD,
2135e5dd7070Spatrick                                         const CGBlockInfo &Info,
2136e5dd7070Spatrick                                         const DeclMapTy &ldm,
2137e5dd7070Spatrick                                         bool IsLambdaConversionToBlock,
2138e5dd7070Spatrick                                         bool BuildGlobalBlock);
2139e5dd7070Spatrick 
2140e5dd7070Spatrick   /// Check if \p T is a C++ class that has a destructor that can throw.
2141e5dd7070Spatrick   static bool cxxDestructorCanThrow(QualType T);
2142e5dd7070Spatrick 
2143e5dd7070Spatrick   llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo);
2144e5dd7070Spatrick   llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo);
2145e5dd7070Spatrick   llvm::Constant *GenerateObjCAtomicSetterCopyHelperFunction(
2146e5dd7070Spatrick                                              const ObjCPropertyImplDecl *PID);
2147e5dd7070Spatrick   llvm::Constant *GenerateObjCAtomicGetterCopyHelperFunction(
2148e5dd7070Spatrick                                              const ObjCPropertyImplDecl *PID);
2149e5dd7070Spatrick   llvm::Value *EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty);
2150e5dd7070Spatrick 
2151e5dd7070Spatrick   void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags,
2152e5dd7070Spatrick                          bool CanThrow);
2153e5dd7070Spatrick 
2154e5dd7070Spatrick   class AutoVarEmission;
2155e5dd7070Spatrick 
2156e5dd7070Spatrick   void emitByrefStructureInit(const AutoVarEmission &emission);
2157e5dd7070Spatrick 
2158e5dd7070Spatrick   /// Enter a cleanup to destroy a __block variable.  Note that this
2159e5dd7070Spatrick   /// cleanup should be a no-op if the variable hasn't left the stack
2160e5dd7070Spatrick   /// yet; if a cleanup is required for the variable itself, that needs
2161e5dd7070Spatrick   /// to be done externally.
2162e5dd7070Spatrick   ///
2163e5dd7070Spatrick   /// \param Kind Cleanup kind.
2164e5dd7070Spatrick   ///
2165e5dd7070Spatrick   /// \param Addr When \p LoadBlockVarAddr is false, the address of the __block
2166e5dd7070Spatrick   /// structure that will be passed to _Block_object_dispose. When
2167e5dd7070Spatrick   /// \p LoadBlockVarAddr is true, the address of the field of the block
2168e5dd7070Spatrick   /// structure that holds the address of the __block structure.
2169e5dd7070Spatrick   ///
2170e5dd7070Spatrick   /// \param Flags The flag that will be passed to _Block_object_dispose.
2171e5dd7070Spatrick   ///
2172e5dd7070Spatrick   /// \param LoadBlockVarAddr Indicates whether we need to emit a load from
2173e5dd7070Spatrick   /// \p Addr to get the address of the __block structure.
2174e5dd7070Spatrick   void enterByrefCleanup(CleanupKind Kind, Address Addr, BlockFieldFlags Flags,
2175e5dd7070Spatrick                          bool LoadBlockVarAddr, bool CanThrow);
2176e5dd7070Spatrick 
2177e5dd7070Spatrick   void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum,
2178e5dd7070Spatrick                                 llvm::Value *ptr);
2179e5dd7070Spatrick 
2180e5dd7070Spatrick   Address LoadBlockStruct();
2181e5dd7070Spatrick   Address GetAddrOfBlockDecl(const VarDecl *var);
2182e5dd7070Spatrick 
2183e5dd7070Spatrick   /// BuildBlockByrefAddress - Computes the location of the
2184e5dd7070Spatrick   /// data in a variable which is declared as __block.
2185e5dd7070Spatrick   Address emitBlockByrefAddress(Address baseAddr, const VarDecl *V,
2186e5dd7070Spatrick                                 bool followForward = true);
2187e5dd7070Spatrick   Address emitBlockByrefAddress(Address baseAddr,
2188e5dd7070Spatrick                                 const BlockByrefInfo &info,
2189e5dd7070Spatrick                                 bool followForward,
2190e5dd7070Spatrick                                 const llvm::Twine &name);
2191e5dd7070Spatrick 
2192e5dd7070Spatrick   const BlockByrefInfo &getBlockByrefInfo(const VarDecl *var);
2193e5dd7070Spatrick 
2194e5dd7070Spatrick   QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args);
2195e5dd7070Spatrick 
2196e5dd7070Spatrick   void GenerateCode(GlobalDecl GD, llvm::Function *Fn,
2197e5dd7070Spatrick                     const CGFunctionInfo &FnInfo);
2198e5dd7070Spatrick 
2199e5dd7070Spatrick   /// Annotate the function with an attribute that disables TSan checking at
2200e5dd7070Spatrick   /// runtime.
2201e5dd7070Spatrick   void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn);
2202e5dd7070Spatrick 
2203e5dd7070Spatrick   /// Emit code for the start of a function.
2204e5dd7070Spatrick   /// \param Loc       The location to be associated with the function.
2205e5dd7070Spatrick   /// \param StartLoc  The location of the function body.
2206e5dd7070Spatrick   void StartFunction(GlobalDecl GD,
2207e5dd7070Spatrick                      QualType RetTy,
2208e5dd7070Spatrick                      llvm::Function *Fn,
2209e5dd7070Spatrick                      const CGFunctionInfo &FnInfo,
2210e5dd7070Spatrick                      const FunctionArgList &Args,
2211e5dd7070Spatrick                      SourceLocation Loc = SourceLocation(),
2212e5dd7070Spatrick                      SourceLocation StartLoc = SourceLocation());
2213e5dd7070Spatrick 
2214e5dd7070Spatrick   static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor);
2215e5dd7070Spatrick 
2216e5dd7070Spatrick   void EmitConstructorBody(FunctionArgList &Args);
2217e5dd7070Spatrick   void EmitDestructorBody(FunctionArgList &Args);
2218e5dd7070Spatrick   void emitImplicitAssignmentOperatorBody(FunctionArgList &Args);
2219e5dd7070Spatrick   void EmitFunctionBody(const Stmt *Body);
2220e5dd7070Spatrick   void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S);
2221e5dd7070Spatrick 
2222e5dd7070Spatrick   void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator,
2223e5dd7070Spatrick                                   CallArgList &CallArgs);
2224e5dd7070Spatrick   void EmitLambdaBlockInvokeBody();
2225e5dd7070Spatrick   void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD);
2226e5dd7070Spatrick   void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD);
2227e5dd7070Spatrick   void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV) {
2228e5dd7070Spatrick     EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
2229e5dd7070Spatrick   }
2230e5dd7070Spatrick   void EmitAsanPrologueOrEpilogue(bool Prologue);
2231e5dd7070Spatrick 
2232e5dd7070Spatrick   /// Emit the unified return block, trying to avoid its emission when
2233e5dd7070Spatrick   /// possible.
2234e5dd7070Spatrick   /// \return The debug location of the user written return statement if the
2235*12c85518Srobert   /// return block is avoided.
2236e5dd7070Spatrick   llvm::DebugLoc EmitReturnBlock();
2237e5dd7070Spatrick 
2238e5dd7070Spatrick   /// FinishFunction - Complete IR generation of the current function. It is
2239e5dd7070Spatrick   /// legal to call this function even if there is no current insertion point.
2240e5dd7070Spatrick   void FinishFunction(SourceLocation EndLoc=SourceLocation());
2241e5dd7070Spatrick 
2242e5dd7070Spatrick   void StartThunk(llvm::Function *Fn, GlobalDecl GD,
2243e5dd7070Spatrick                   const CGFunctionInfo &FnInfo, bool IsUnprototyped);
2244e5dd7070Spatrick 
2245e5dd7070Spatrick   void EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
2246e5dd7070Spatrick                                  const ThunkInfo *Thunk, bool IsUnprototyped);
2247e5dd7070Spatrick 
2248e5dd7070Spatrick   void FinishThunk();
2249e5dd7070Spatrick 
2250e5dd7070Spatrick   /// Emit a musttail call for a thunk with a potentially adjusted this pointer.
2251e5dd7070Spatrick   void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr,
2252e5dd7070Spatrick                          llvm::FunctionCallee Callee);
2253e5dd7070Spatrick 
2254e5dd7070Spatrick   /// Generate a thunk for the given method.
2255e5dd7070Spatrick   void generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo,
2256e5dd7070Spatrick                      GlobalDecl GD, const ThunkInfo &Thunk,
2257e5dd7070Spatrick                      bool IsUnprototyped);
2258e5dd7070Spatrick 
2259e5dd7070Spatrick   llvm::Function *GenerateVarArgsThunk(llvm::Function *Fn,
2260e5dd7070Spatrick                                        const CGFunctionInfo &FnInfo,
2261e5dd7070Spatrick                                        GlobalDecl GD, const ThunkInfo &Thunk);
2262e5dd7070Spatrick 
2263e5dd7070Spatrick   void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type,
2264e5dd7070Spatrick                         FunctionArgList &Args);
2265e5dd7070Spatrick 
2266e5dd7070Spatrick   void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init);
2267e5dd7070Spatrick 
2268e5dd7070Spatrick   /// Struct with all information about dynamic [sub]class needed to set vptr.
2269e5dd7070Spatrick   struct VPtr {
2270e5dd7070Spatrick     BaseSubobject Base;
2271e5dd7070Spatrick     const CXXRecordDecl *NearestVBase;
2272e5dd7070Spatrick     CharUnits OffsetFromNearestVBase;
2273e5dd7070Spatrick     const CXXRecordDecl *VTableClass;
2274e5dd7070Spatrick   };
2275e5dd7070Spatrick 
2276e5dd7070Spatrick   /// Initialize the vtable pointer of the given subobject.
2277e5dd7070Spatrick   void InitializeVTablePointer(const VPtr &vptr);
2278e5dd7070Spatrick 
2279e5dd7070Spatrick   typedef llvm::SmallVector<VPtr, 4> VPtrsVector;
2280e5dd7070Spatrick 
2281e5dd7070Spatrick   typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
2282e5dd7070Spatrick   VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass);
2283e5dd7070Spatrick 
2284e5dd7070Spatrick   void getVTablePointers(BaseSubobject Base, const CXXRecordDecl *NearestVBase,
2285e5dd7070Spatrick                          CharUnits OffsetFromNearestVBase,
2286e5dd7070Spatrick                          bool BaseIsNonVirtualPrimaryBase,
2287e5dd7070Spatrick                          const CXXRecordDecl *VTableClass,
2288e5dd7070Spatrick                          VisitedVirtualBasesSetTy &VBases, VPtrsVector &vptrs);
2289e5dd7070Spatrick 
2290e5dd7070Spatrick   void InitializeVTablePointers(const CXXRecordDecl *ClassDecl);
2291e5dd7070Spatrick 
2292e5dd7070Spatrick   /// GetVTablePtr - Return the Value of the vtable pointer member pointed
2293e5dd7070Spatrick   /// to by This.
2294e5dd7070Spatrick   llvm::Value *GetVTablePtr(Address This, llvm::Type *VTableTy,
2295e5dd7070Spatrick                             const CXXRecordDecl *VTableClass);
2296e5dd7070Spatrick 
2297e5dd7070Spatrick   enum CFITypeCheckKind {
2298e5dd7070Spatrick     CFITCK_VCall,
2299e5dd7070Spatrick     CFITCK_NVCall,
2300e5dd7070Spatrick     CFITCK_DerivedCast,
2301e5dd7070Spatrick     CFITCK_UnrelatedCast,
2302e5dd7070Spatrick     CFITCK_ICall,
2303e5dd7070Spatrick     CFITCK_NVMFCall,
2304e5dd7070Spatrick     CFITCK_VMFCall,
2305e5dd7070Spatrick   };
2306e5dd7070Spatrick 
2307e5dd7070Spatrick   /// Derived is the presumed address of an object of type T after a
2308e5dd7070Spatrick   /// cast. If T is a polymorphic class type, emit a check that the virtual
2309e5dd7070Spatrick   /// table for Derived belongs to a class derived from T.
2310*12c85518Srobert   void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull,
2311*12c85518Srobert                                  CFITypeCheckKind TCK, SourceLocation Loc);
2312e5dd7070Spatrick 
2313e5dd7070Spatrick   /// EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
2314e5dd7070Spatrick   /// If vptr CFI is enabled, emit a check that VTable is valid.
2315e5dd7070Spatrick   void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable,
2316e5dd7070Spatrick                                  CFITypeCheckKind TCK, SourceLocation Loc);
2317e5dd7070Spatrick 
2318e5dd7070Spatrick   /// EmitVTablePtrCheck - Emit a check that VTable is a valid virtual table for
2319e5dd7070Spatrick   /// RD using llvm.type.test.
2320e5dd7070Spatrick   void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable,
2321e5dd7070Spatrick                           CFITypeCheckKind TCK, SourceLocation Loc);
2322e5dd7070Spatrick 
2323e5dd7070Spatrick   /// If whole-program virtual table optimization is enabled, emit an assumption
2324e5dd7070Spatrick   /// that VTable is a member of RD's type identifier. Or, if vptr CFI is
2325e5dd7070Spatrick   /// enabled, emit a check that VTable is a member of RD's type identifier.
2326e5dd7070Spatrick   void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD,
2327e5dd7070Spatrick                                     llvm::Value *VTable, SourceLocation Loc);
2328e5dd7070Spatrick 
2329e5dd7070Spatrick   /// Returns whether we should perform a type checked load when loading a
2330e5dd7070Spatrick   /// virtual function for virtual calls to members of RD. This is generally
2331e5dd7070Spatrick   /// true when both vcall CFI and whole-program-vtables are enabled.
2332e5dd7070Spatrick   bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD);
2333e5dd7070Spatrick 
2334e5dd7070Spatrick   /// Emit a type checked load from the given vtable.
2335*12c85518Srobert   llvm::Value *EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD,
2336*12c85518Srobert                                          llvm::Value *VTable,
2337*12c85518Srobert                                          llvm::Type *VTableTy,
2338e5dd7070Spatrick                                          uint64_t VTableByteOffset);
2339e5dd7070Spatrick 
2340e5dd7070Spatrick   /// EnterDtorCleanups - Enter the cleanups necessary to complete the
2341e5dd7070Spatrick   /// given phase of destruction for a destructor.  The end result
2342e5dd7070Spatrick   /// should call destructors on members and base classes in reverse
2343e5dd7070Spatrick   /// order of their construction.
2344e5dd7070Spatrick   void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type);
2345e5dd7070Spatrick 
2346e5dd7070Spatrick   /// ShouldInstrumentFunction - Return true if the current function should be
2347e5dd7070Spatrick   /// instrumented with __cyg_profile_func_* calls
2348e5dd7070Spatrick   bool ShouldInstrumentFunction();
2349e5dd7070Spatrick 
2350*12c85518Srobert   /// ShouldSkipSanitizerInstrumentation - Return true if the current function
2351*12c85518Srobert   /// should not be instrumented with sanitizers.
2352*12c85518Srobert   bool ShouldSkipSanitizerInstrumentation();
2353*12c85518Srobert 
2354e5dd7070Spatrick   /// ShouldXRayInstrument - Return true if the current function should be
2355e5dd7070Spatrick   /// instrumented with XRay nop sleds.
2356e5dd7070Spatrick   bool ShouldXRayInstrumentFunction() const;
2357e5dd7070Spatrick 
2358e5dd7070Spatrick   /// AlwaysEmitXRayCustomEvents - Return true if we must unconditionally emit
2359e5dd7070Spatrick   /// XRay custom event handling calls.
2360e5dd7070Spatrick   bool AlwaysEmitXRayCustomEvents() const;
2361e5dd7070Spatrick 
2362e5dd7070Spatrick   /// AlwaysEmitXRayTypedEvents - Return true if clang must unconditionally emit
2363e5dd7070Spatrick   /// XRay typed event handling calls.
2364e5dd7070Spatrick   bool AlwaysEmitXRayTypedEvents() const;
2365e5dd7070Spatrick 
2366e5dd7070Spatrick   /// Decode an address used in a function prologue, encoded by \c
2367e5dd7070Spatrick   /// EncodeAddrForUseInPrologue.
2368e5dd7070Spatrick   llvm::Value *DecodeAddrUsedInPrologue(llvm::Value *F,
2369e5dd7070Spatrick                                         llvm::Value *EncodedAddr);
2370e5dd7070Spatrick 
2371e5dd7070Spatrick   /// EmitFunctionProlog - Emit the target specific LLVM code to load the
2372e5dd7070Spatrick   /// arguments for the given function. This is also responsible for naming the
2373e5dd7070Spatrick   /// LLVM function arguments.
2374e5dd7070Spatrick   void EmitFunctionProlog(const CGFunctionInfo &FI,
2375e5dd7070Spatrick                           llvm::Function *Fn,
2376e5dd7070Spatrick                           const FunctionArgList &Args);
2377e5dd7070Spatrick 
2378e5dd7070Spatrick   /// EmitFunctionEpilog - Emit the target specific LLVM code to return the
2379e5dd7070Spatrick   /// given temporary.
2380e5dd7070Spatrick   void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc,
2381e5dd7070Spatrick                           SourceLocation EndLoc);
2382e5dd7070Spatrick 
2383e5dd7070Spatrick   /// Emit a test that checks if the return value \p RV is nonnull.
2384e5dd7070Spatrick   void EmitReturnValueCheck(llvm::Value *RV);
2385e5dd7070Spatrick 
2386e5dd7070Spatrick   /// EmitStartEHSpec - Emit the start of the exception spec.
2387e5dd7070Spatrick   void EmitStartEHSpec(const Decl *D);
2388e5dd7070Spatrick 
2389e5dd7070Spatrick   /// EmitEndEHSpec - Emit the end of the exception spec.
2390e5dd7070Spatrick   void EmitEndEHSpec(const Decl *D);
2391e5dd7070Spatrick 
2392e5dd7070Spatrick   /// getTerminateLandingPad - Return a landing pad that just calls terminate.
2393e5dd7070Spatrick   llvm::BasicBlock *getTerminateLandingPad();
2394e5dd7070Spatrick 
2395e5dd7070Spatrick   /// getTerminateLandingPad - Return a cleanup funclet that just calls
2396e5dd7070Spatrick   /// terminate.
2397e5dd7070Spatrick   llvm::BasicBlock *getTerminateFunclet();
2398e5dd7070Spatrick 
2399e5dd7070Spatrick   /// getTerminateHandler - Return a handler (not a landing pad, just
2400e5dd7070Spatrick   /// a catch handler) that just calls terminate.  This is used when
2401e5dd7070Spatrick   /// a terminate scope encloses a try.
2402e5dd7070Spatrick   llvm::BasicBlock *getTerminateHandler();
2403e5dd7070Spatrick 
2404e5dd7070Spatrick   llvm::Type *ConvertTypeForMem(QualType T);
2405e5dd7070Spatrick   llvm::Type *ConvertType(QualType T);
2406e5dd7070Spatrick   llvm::Type *ConvertType(const TypeDecl *T) {
2407e5dd7070Spatrick     return ConvertType(getContext().getTypeDeclType(T));
2408e5dd7070Spatrick   }
2409e5dd7070Spatrick 
2410e5dd7070Spatrick   /// LoadObjCSelf - Load the value of self. This function is only valid while
2411e5dd7070Spatrick   /// generating code for an Objective-C method.
2412e5dd7070Spatrick   llvm::Value *LoadObjCSelf();
2413e5dd7070Spatrick 
2414e5dd7070Spatrick   /// TypeOfSelfObject - Return type of object that this self represents.
2415e5dd7070Spatrick   QualType TypeOfSelfObject();
2416e5dd7070Spatrick 
2417e5dd7070Spatrick   /// getEvaluationKind - Return the TypeEvaluationKind of QualType \c T.
2418e5dd7070Spatrick   static TypeEvaluationKind getEvaluationKind(QualType T);
2419e5dd7070Spatrick 
2420e5dd7070Spatrick   static bool hasScalarEvaluationKind(QualType T) {
2421e5dd7070Spatrick     return getEvaluationKind(T) == TEK_Scalar;
2422e5dd7070Spatrick   }
2423e5dd7070Spatrick 
2424e5dd7070Spatrick   static bool hasAggregateEvaluationKind(QualType T) {
2425e5dd7070Spatrick     return getEvaluationKind(T) == TEK_Aggregate;
2426e5dd7070Spatrick   }
2427e5dd7070Spatrick 
2428e5dd7070Spatrick   /// createBasicBlock - Create an LLVM basic block.
2429e5dd7070Spatrick   llvm::BasicBlock *createBasicBlock(const Twine &name = "",
2430e5dd7070Spatrick                                      llvm::Function *parent = nullptr,
2431e5dd7070Spatrick                                      llvm::BasicBlock *before = nullptr) {
2432e5dd7070Spatrick     return llvm::BasicBlock::Create(getLLVMContext(), name, parent, before);
2433e5dd7070Spatrick   }
2434e5dd7070Spatrick 
2435e5dd7070Spatrick   /// getBasicBlockForLabel - Return the LLVM basicblock that the specified
2436e5dd7070Spatrick   /// label maps to.
2437e5dd7070Spatrick   JumpDest getJumpDestForLabel(const LabelDecl *S);
2438e5dd7070Spatrick 
2439e5dd7070Spatrick   /// SimplifyForwardingBlocks - If the given basic block is only a branch to
2440e5dd7070Spatrick   /// another basic block, simplify it. This assumes that no other code could
2441e5dd7070Spatrick   /// potentially reference the basic block.
2442e5dd7070Spatrick   void SimplifyForwardingBlocks(llvm::BasicBlock *BB);
2443e5dd7070Spatrick 
2444e5dd7070Spatrick   /// EmitBlock - Emit the given block \arg BB and set it as the insert point,
2445e5dd7070Spatrick   /// adding a fall-through branch from the current insert block if
2446e5dd7070Spatrick   /// necessary. It is legal to call this function even if there is no current
2447e5dd7070Spatrick   /// insertion point.
2448e5dd7070Spatrick   ///
2449e5dd7070Spatrick   /// IsFinished - If true, indicates that the caller has finished emitting
2450e5dd7070Spatrick   /// branches to the given block and does not expect to emit code into it. This
2451e5dd7070Spatrick   /// means the block can be ignored if it is unreachable.
2452e5dd7070Spatrick   void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false);
2453e5dd7070Spatrick 
2454e5dd7070Spatrick   /// EmitBlockAfterUses - Emit the given block somewhere hopefully
2455e5dd7070Spatrick   /// near its uses, and leave the insertion point in it.
2456e5dd7070Spatrick   void EmitBlockAfterUses(llvm::BasicBlock *BB);
2457e5dd7070Spatrick 
2458e5dd7070Spatrick   /// EmitBranch - Emit a branch to the specified basic block from the current
2459e5dd7070Spatrick   /// insert block, taking care to avoid creation of branches from dummy
2460e5dd7070Spatrick   /// blocks. It is legal to call this function even if there is no current
2461e5dd7070Spatrick   /// insertion point.
2462e5dd7070Spatrick   ///
2463e5dd7070Spatrick   /// This function clears the current insertion point. The caller should follow
2464e5dd7070Spatrick   /// calls to this function with calls to Emit*Block prior to generation new
2465e5dd7070Spatrick   /// code.
2466e5dd7070Spatrick   void EmitBranch(llvm::BasicBlock *Block);
2467e5dd7070Spatrick 
2468e5dd7070Spatrick   /// HaveInsertPoint - True if an insertion point is defined. If not, this
2469e5dd7070Spatrick   /// indicates that the current code being emitted is unreachable.
2470e5dd7070Spatrick   bool HaveInsertPoint() const {
2471e5dd7070Spatrick     return Builder.GetInsertBlock() != nullptr;
2472e5dd7070Spatrick   }
2473e5dd7070Spatrick 
2474e5dd7070Spatrick   /// EnsureInsertPoint - Ensure that an insertion point is defined so that
2475e5dd7070Spatrick   /// emitted IR has a place to go. Note that by definition, if this function
2476e5dd7070Spatrick   /// creates a block then that block is unreachable; callers may do better to
2477e5dd7070Spatrick   /// detect when no insertion point is defined and simply skip IR generation.
2478e5dd7070Spatrick   void EnsureInsertPoint() {
2479e5dd7070Spatrick     if (!HaveInsertPoint())
2480e5dd7070Spatrick       EmitBlock(createBasicBlock());
2481e5dd7070Spatrick   }
2482e5dd7070Spatrick 
2483e5dd7070Spatrick   /// ErrorUnsupported - Print out an error that codegen doesn't support the
2484e5dd7070Spatrick   /// specified stmt yet.
2485e5dd7070Spatrick   void ErrorUnsupported(const Stmt *S, const char *Type);
2486e5dd7070Spatrick 
2487e5dd7070Spatrick   //===--------------------------------------------------------------------===//
2488e5dd7070Spatrick   //                                  Helpers
2489e5dd7070Spatrick   //===--------------------------------------------------------------------===//
2490e5dd7070Spatrick 
2491e5dd7070Spatrick   LValue MakeAddrLValue(Address Addr, QualType T,
2492e5dd7070Spatrick                         AlignmentSource Source = AlignmentSource::Type) {
2493e5dd7070Spatrick     return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source),
2494e5dd7070Spatrick                             CGM.getTBAAAccessInfo(T));
2495e5dd7070Spatrick   }
2496e5dd7070Spatrick 
2497e5dd7070Spatrick   LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo,
2498e5dd7070Spatrick                         TBAAAccessInfo TBAAInfo) {
2499e5dd7070Spatrick     return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, TBAAInfo);
2500e5dd7070Spatrick   }
2501e5dd7070Spatrick 
2502e5dd7070Spatrick   LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment,
2503e5dd7070Spatrick                         AlignmentSource Source = AlignmentSource::Type) {
2504*12c85518Srobert     Address Addr(V, ConvertTypeForMem(T), Alignment);
2505*12c85518Srobert     return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source),
2506*12c85518Srobert                             CGM.getTBAAAccessInfo(T));
2507e5dd7070Spatrick   }
2508e5dd7070Spatrick 
2509*12c85518Srobert   LValue
2510*12c85518Srobert   MakeAddrLValueWithoutTBAA(Address Addr, QualType T,
2511*12c85518Srobert                             AlignmentSource Source = AlignmentSource::Type) {
2512*12c85518Srobert     return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source),
2513*12c85518Srobert                             TBAAAccessInfo());
2514e5dd7070Spatrick   }
2515e5dd7070Spatrick 
2516e5dd7070Spatrick   LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T);
2517e5dd7070Spatrick   LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T);
2518e5dd7070Spatrick 
2519e5dd7070Spatrick   Address EmitLoadOfReference(LValue RefLVal,
2520e5dd7070Spatrick                               LValueBaseInfo *PointeeBaseInfo = nullptr,
2521e5dd7070Spatrick                               TBAAAccessInfo *PointeeTBAAInfo = nullptr);
2522e5dd7070Spatrick   LValue EmitLoadOfReferenceLValue(LValue RefLVal);
2523e5dd7070Spatrick   LValue EmitLoadOfReferenceLValue(Address RefAddr, QualType RefTy,
2524e5dd7070Spatrick                                    AlignmentSource Source =
2525e5dd7070Spatrick                                        AlignmentSource::Type) {
2526e5dd7070Spatrick     LValue RefLVal = MakeAddrLValue(RefAddr, RefTy, LValueBaseInfo(Source),
2527e5dd7070Spatrick                                     CGM.getTBAAAccessInfo(RefTy));
2528e5dd7070Spatrick     return EmitLoadOfReferenceLValue(RefLVal);
2529e5dd7070Spatrick   }
2530e5dd7070Spatrick 
2531*12c85518Srobert   /// Load a pointer with type \p PtrTy stored at address \p Ptr.
2532*12c85518Srobert   /// Note that \p PtrTy is the type of the loaded pointer, not the addresses
2533*12c85518Srobert   /// it is loaded from.
2534e5dd7070Spatrick   Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy,
2535e5dd7070Spatrick                             LValueBaseInfo *BaseInfo = nullptr,
2536e5dd7070Spatrick                             TBAAAccessInfo *TBAAInfo = nullptr);
2537e5dd7070Spatrick   LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy);
2538e5dd7070Spatrick 
2539e5dd7070Spatrick   /// CreateTempAlloca - This creates an alloca and inserts it into the entry
2540e5dd7070Spatrick   /// block if \p ArraySize is nullptr, otherwise inserts it at the current
2541e5dd7070Spatrick   /// insertion point of the builder. The caller is responsible for setting an
2542e5dd7070Spatrick   /// appropriate alignment on
2543e5dd7070Spatrick   /// the alloca.
2544e5dd7070Spatrick   ///
2545e5dd7070Spatrick   /// \p ArraySize is the number of array elements to be allocated if it
2546e5dd7070Spatrick   ///    is not nullptr.
2547e5dd7070Spatrick   ///
2548e5dd7070Spatrick   /// LangAS::Default is the address space of pointers to local variables and
2549e5dd7070Spatrick   /// temporaries, as exposed in the source language. In certain
2550e5dd7070Spatrick   /// configurations, this is not the same as the alloca address space, and a
2551e5dd7070Spatrick   /// cast is needed to lift the pointer from the alloca AS into
2552e5dd7070Spatrick   /// LangAS::Default. This can happen when the target uses a restricted
2553e5dd7070Spatrick   /// address space for the stack but the source language requires
2554e5dd7070Spatrick   /// LangAS::Default to be a generic address space. The latter condition is
2555e5dd7070Spatrick   /// common for most programming languages; OpenCL is an exception in that
2556e5dd7070Spatrick   /// LangAS::Default is the private address space, which naturally maps
2557e5dd7070Spatrick   /// to the stack.
2558e5dd7070Spatrick   ///
2559e5dd7070Spatrick   /// Because the address of a temporary is often exposed to the program in
2560e5dd7070Spatrick   /// various ways, this function will perform the cast. The original alloca
2561e5dd7070Spatrick   /// instruction is returned through \p Alloca if it is not nullptr.
2562e5dd7070Spatrick   ///
2563e5dd7070Spatrick   /// The cast is not performaed in CreateTempAllocaWithoutCast. This is
2564e5dd7070Spatrick   /// more efficient if the caller knows that the address will not be exposed.
2565e5dd7070Spatrick   llvm::AllocaInst *CreateTempAlloca(llvm::Type *Ty, const Twine &Name = "tmp",
2566e5dd7070Spatrick                                      llvm::Value *ArraySize = nullptr);
2567e5dd7070Spatrick   Address CreateTempAlloca(llvm::Type *Ty, CharUnits align,
2568e5dd7070Spatrick                            const Twine &Name = "tmp",
2569e5dd7070Spatrick                            llvm::Value *ArraySize = nullptr,
2570e5dd7070Spatrick                            Address *Alloca = nullptr);
2571e5dd7070Spatrick   Address CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align,
2572e5dd7070Spatrick                                       const Twine &Name = "tmp",
2573e5dd7070Spatrick                                       llvm::Value *ArraySize = nullptr);
2574e5dd7070Spatrick 
2575e5dd7070Spatrick   /// CreateDefaultAlignedTempAlloca - This creates an alloca with the
2576e5dd7070Spatrick   /// default ABI alignment of the given LLVM type.
2577e5dd7070Spatrick   ///
2578e5dd7070Spatrick   /// IMPORTANT NOTE: This is *not* generally the right alignment for
2579e5dd7070Spatrick   /// any given AST type that happens to have been lowered to the
2580e5dd7070Spatrick   /// given IR type.  This should only ever be used for function-local,
2581e5dd7070Spatrick   /// IR-driven manipulations like saving and restoring a value.  Do
2582e5dd7070Spatrick   /// not hand this address off to arbitrary IRGen routines, and especially
2583e5dd7070Spatrick   /// do not pass it as an argument to a function that might expect a
2584e5dd7070Spatrick   /// properly ABI-aligned value.
2585e5dd7070Spatrick   Address CreateDefaultAlignTempAlloca(llvm::Type *Ty,
2586e5dd7070Spatrick                                        const Twine &Name = "tmp");
2587e5dd7070Spatrick 
2588e5dd7070Spatrick   /// CreateIRTemp - Create a temporary IR object of the given type, with
2589e5dd7070Spatrick   /// appropriate alignment. This routine should only be used when an temporary
2590e5dd7070Spatrick   /// value needs to be stored into an alloca (for example, to avoid explicit
2591e5dd7070Spatrick   /// PHI construction), but the type is the IR type, not the type appropriate
2592e5dd7070Spatrick   /// for storing in memory.
2593e5dd7070Spatrick   ///
2594e5dd7070Spatrick   /// That is, this is exactly equivalent to CreateMemTemp, but calling
2595e5dd7070Spatrick   /// ConvertType instead of ConvertTypeForMem.
2596e5dd7070Spatrick   Address CreateIRTemp(QualType T, const Twine &Name = "tmp");
2597e5dd7070Spatrick 
2598e5dd7070Spatrick   /// CreateMemTemp - Create a temporary memory object of the given type, with
2599e5dd7070Spatrick   /// appropriate alignmen and cast it to the default address space. Returns
2600e5dd7070Spatrick   /// the original alloca instruction by \p Alloca if it is not nullptr.
2601e5dd7070Spatrick   Address CreateMemTemp(QualType T, const Twine &Name = "tmp",
2602e5dd7070Spatrick                         Address *Alloca = nullptr);
2603e5dd7070Spatrick   Address CreateMemTemp(QualType T, CharUnits Align, const Twine &Name = "tmp",
2604e5dd7070Spatrick                         Address *Alloca = nullptr);
2605e5dd7070Spatrick 
2606e5dd7070Spatrick   /// CreateMemTemp - Create a temporary memory object of the given type, with
2607e5dd7070Spatrick   /// appropriate alignmen without casting it to the default address space.
2608e5dd7070Spatrick   Address CreateMemTempWithoutCast(QualType T, const Twine &Name = "tmp");
2609e5dd7070Spatrick   Address CreateMemTempWithoutCast(QualType T, CharUnits Align,
2610e5dd7070Spatrick                                    const Twine &Name = "tmp");
2611e5dd7070Spatrick 
2612e5dd7070Spatrick   /// CreateAggTemp - Create a temporary memory object for the given
2613e5dd7070Spatrick   /// aggregate type.
2614ec727ea7Spatrick   AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp",
2615ec727ea7Spatrick                              Address *Alloca = nullptr) {
2616ec727ea7Spatrick     return AggValueSlot::forAddr(CreateMemTemp(T, Name, Alloca),
2617e5dd7070Spatrick                                  T.getQualifiers(),
2618e5dd7070Spatrick                                  AggValueSlot::IsNotDestructed,
2619e5dd7070Spatrick                                  AggValueSlot::DoesNotNeedGCBarriers,
2620e5dd7070Spatrick                                  AggValueSlot::IsNotAliased,
2621e5dd7070Spatrick                                  AggValueSlot::DoesNotOverlap);
2622e5dd7070Spatrick   }
2623e5dd7070Spatrick 
2624e5dd7070Spatrick   /// Emit a cast to void* in the appropriate address space.
2625e5dd7070Spatrick   llvm::Value *EmitCastToVoidPtr(llvm::Value *value);
2626e5dd7070Spatrick 
2627e5dd7070Spatrick   /// EvaluateExprAsBool - Perform the usual unary conversions on the specified
2628e5dd7070Spatrick   /// expression and compare the result against zero, returning an Int1Ty value.
2629e5dd7070Spatrick   llvm::Value *EvaluateExprAsBool(const Expr *E);
2630e5dd7070Spatrick 
2631e5dd7070Spatrick   /// EmitIgnoredExpr - Emit an expression in a context which ignores the result.
2632e5dd7070Spatrick   void EmitIgnoredExpr(const Expr *E);
2633e5dd7070Spatrick 
2634e5dd7070Spatrick   /// EmitAnyExpr - Emit code to compute the specified expression which can have
2635e5dd7070Spatrick   /// any type.  The result is returned as an RValue struct.  If this is an
2636e5dd7070Spatrick   /// aggregate expression, the aggloc/agglocvolatile arguments indicate where
2637e5dd7070Spatrick   /// the result should be returned.
2638e5dd7070Spatrick   ///
2639e5dd7070Spatrick   /// \param ignoreResult True if the resulting value isn't used.
2640e5dd7070Spatrick   RValue EmitAnyExpr(const Expr *E,
2641e5dd7070Spatrick                      AggValueSlot aggSlot = AggValueSlot::ignored(),
2642e5dd7070Spatrick                      bool ignoreResult = false);
2643e5dd7070Spatrick 
2644e5dd7070Spatrick   // EmitVAListRef - Emit a "reference" to a va_list; this is either the address
2645e5dd7070Spatrick   // or the value of the expression, depending on how va_list is defined.
2646e5dd7070Spatrick   Address EmitVAListRef(const Expr *E);
2647e5dd7070Spatrick 
2648e5dd7070Spatrick   /// Emit a "reference" to a __builtin_ms_va_list; this is
2649e5dd7070Spatrick   /// always the value of the expression, because a __builtin_ms_va_list is a
2650e5dd7070Spatrick   /// pointer to a char.
2651e5dd7070Spatrick   Address EmitMSVAListRef(const Expr *E);
2652e5dd7070Spatrick 
2653e5dd7070Spatrick   /// EmitAnyExprToTemp - Similarly to EmitAnyExpr(), however, the result will
2654e5dd7070Spatrick   /// always be accessible even if no aggregate location is provided.
2655e5dd7070Spatrick   RValue EmitAnyExprToTemp(const Expr *E);
2656e5dd7070Spatrick 
2657e5dd7070Spatrick   /// EmitAnyExprToMem - Emits the code necessary to evaluate an
2658e5dd7070Spatrick   /// arbitrary expression into the given memory location.
2659e5dd7070Spatrick   void EmitAnyExprToMem(const Expr *E, Address Location,
2660e5dd7070Spatrick                         Qualifiers Quals, bool IsInitializer);
2661e5dd7070Spatrick 
2662e5dd7070Spatrick   void EmitAnyExprToExn(const Expr *E, Address Addr);
2663e5dd7070Spatrick 
2664e5dd7070Spatrick   /// EmitExprAsInit - Emits the code necessary to initialize a
2665e5dd7070Spatrick   /// location in memory with the given initializer.
2666e5dd7070Spatrick   void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue,
2667e5dd7070Spatrick                       bool capturedByInit);
2668e5dd7070Spatrick 
2669e5dd7070Spatrick   /// hasVolatileMember - returns true if aggregate type has a volatile
2670e5dd7070Spatrick   /// member.
2671e5dd7070Spatrick   bool hasVolatileMember(QualType T) {
2672e5dd7070Spatrick     if (const RecordType *RT = T->getAs<RecordType>()) {
2673e5dd7070Spatrick       const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
2674e5dd7070Spatrick       return RD->hasVolatileMember();
2675e5dd7070Spatrick     }
2676e5dd7070Spatrick     return false;
2677e5dd7070Spatrick   }
2678e5dd7070Spatrick 
2679e5dd7070Spatrick   /// Determine whether a return value slot may overlap some other object.
2680e5dd7070Spatrick   AggValueSlot::Overlap_t getOverlapForReturnValue() {
2681e5dd7070Spatrick     // FIXME: Assuming no overlap here breaks guaranteed copy elision for base
2682e5dd7070Spatrick     // class subobjects. These cases may need to be revisited depending on the
2683e5dd7070Spatrick     // resolution of the relevant core issue.
2684e5dd7070Spatrick     return AggValueSlot::DoesNotOverlap;
2685e5dd7070Spatrick   }
2686e5dd7070Spatrick 
2687e5dd7070Spatrick   /// Determine whether a field initialization may overlap some other object.
2688e5dd7070Spatrick   AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD);
2689e5dd7070Spatrick 
2690e5dd7070Spatrick   /// Determine whether a base class initialization may overlap some other
2691e5dd7070Spatrick   /// object.
2692e5dd7070Spatrick   AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *RD,
2693e5dd7070Spatrick                                                 const CXXRecordDecl *BaseRD,
2694e5dd7070Spatrick                                                 bool IsVirtual);
2695e5dd7070Spatrick 
2696e5dd7070Spatrick   /// Emit an aggregate assignment.
2697e5dd7070Spatrick   void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy) {
2698e5dd7070Spatrick     bool IsVolatile = hasVolatileMember(EltTy);
2699e5dd7070Spatrick     EmitAggregateCopy(Dest, Src, EltTy, AggValueSlot::MayOverlap, IsVolatile);
2700e5dd7070Spatrick   }
2701e5dd7070Spatrick 
2702e5dd7070Spatrick   void EmitAggregateCopyCtor(LValue Dest, LValue Src,
2703e5dd7070Spatrick                              AggValueSlot::Overlap_t MayOverlap) {
2704e5dd7070Spatrick     EmitAggregateCopy(Dest, Src, Src.getType(), MayOverlap);
2705e5dd7070Spatrick   }
2706e5dd7070Spatrick 
2707e5dd7070Spatrick   /// EmitAggregateCopy - Emit an aggregate copy.
2708e5dd7070Spatrick   ///
2709e5dd7070Spatrick   /// \param isVolatile \c true iff either the source or the destination is
2710e5dd7070Spatrick   ///        volatile.
2711e5dd7070Spatrick   /// \param MayOverlap Whether the tail padding of the destination might be
2712e5dd7070Spatrick   ///        occupied by some other object. More efficient code can often be
2713e5dd7070Spatrick   ///        generated if not.
2714e5dd7070Spatrick   void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy,
2715e5dd7070Spatrick                          AggValueSlot::Overlap_t MayOverlap,
2716e5dd7070Spatrick                          bool isVolatile = false);
2717e5dd7070Spatrick 
2718e5dd7070Spatrick   /// GetAddrOfLocalVar - Return the address of a local variable.
2719e5dd7070Spatrick   Address GetAddrOfLocalVar(const VarDecl *VD) {
2720e5dd7070Spatrick     auto it = LocalDeclMap.find(VD);
2721e5dd7070Spatrick     assert(it != LocalDeclMap.end() &&
2722e5dd7070Spatrick            "Invalid argument to GetAddrOfLocalVar(), no decl!");
2723e5dd7070Spatrick     return it->second;
2724e5dd7070Spatrick   }
2725e5dd7070Spatrick 
2726e5dd7070Spatrick   /// Given an opaque value expression, return its LValue mapping if it exists,
2727e5dd7070Spatrick   /// otherwise create one.
2728e5dd7070Spatrick   LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e);
2729e5dd7070Spatrick 
2730e5dd7070Spatrick   /// Given an opaque value expression, return its RValue mapping if it exists,
2731e5dd7070Spatrick   /// otherwise create one.
2732e5dd7070Spatrick   RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e);
2733e5dd7070Spatrick 
2734e5dd7070Spatrick   /// Get the index of the current ArrayInitLoopExpr, if any.
2735e5dd7070Spatrick   llvm::Value *getArrayInitIndex() { return ArrayInitIndex; }
2736e5dd7070Spatrick 
2737e5dd7070Spatrick   /// getAccessedFieldNo - Given an encoded value and a result number, return
2738e5dd7070Spatrick   /// the input field number being accessed.
2739e5dd7070Spatrick   static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts);
2740e5dd7070Spatrick 
2741e5dd7070Spatrick   llvm::BlockAddress *GetAddrOfLabel(const LabelDecl *L);
2742e5dd7070Spatrick   llvm::BasicBlock *GetIndirectGotoBlock();
2743e5dd7070Spatrick 
2744e5dd7070Spatrick   /// Check if \p E is a C++ "this" pointer wrapped in value-preserving casts.
2745e5dd7070Spatrick   static bool IsWrappedCXXThis(const Expr *E);
2746e5dd7070Spatrick 
2747e5dd7070Spatrick   /// EmitNullInitialization - Generate code to set a value of the given type to
2748e5dd7070Spatrick   /// null, If the type contains data member pointers, they will be initialized
2749e5dd7070Spatrick   /// to -1 in accordance with the Itanium C++ ABI.
2750e5dd7070Spatrick   void EmitNullInitialization(Address DestPtr, QualType Ty);
2751e5dd7070Spatrick 
2752e5dd7070Spatrick   /// Emits a call to an LLVM variable-argument intrinsic, either
2753e5dd7070Spatrick   /// \c llvm.va_start or \c llvm.va_end.
2754e5dd7070Spatrick   /// \param ArgValue A reference to the \c va_list as emitted by either
2755e5dd7070Spatrick   /// \c EmitVAListRef or \c EmitMSVAListRef.
2756e5dd7070Spatrick   /// \param IsStart If \c true, emits a call to \c llvm.va_start; otherwise,
2757e5dd7070Spatrick   /// calls \c llvm.va_end.
2758e5dd7070Spatrick   llvm::Value *EmitVAStartEnd(llvm::Value *ArgValue, bool IsStart);
2759e5dd7070Spatrick 
2760e5dd7070Spatrick   /// Generate code to get an argument from the passed in pointer
2761e5dd7070Spatrick   /// and update it accordingly.
2762e5dd7070Spatrick   /// \param VE The \c VAArgExpr for which to generate code.
2763e5dd7070Spatrick   /// \param VAListAddr Receives a reference to the \c va_list as emitted by
2764e5dd7070Spatrick   /// either \c EmitVAListRef or \c EmitMSVAListRef.
2765e5dd7070Spatrick   /// \returns A pointer to the argument.
2766e5dd7070Spatrick   // FIXME: We should be able to get rid of this method and use the va_arg
2767e5dd7070Spatrick   // instruction in LLVM instead once it works well enough.
2768e5dd7070Spatrick   Address EmitVAArg(VAArgExpr *VE, Address &VAListAddr);
2769e5dd7070Spatrick 
2770e5dd7070Spatrick   /// emitArrayLength - Compute the length of an array, even if it's a
2771e5dd7070Spatrick   /// VLA, and drill down to the base element type.
2772e5dd7070Spatrick   llvm::Value *emitArrayLength(const ArrayType *arrayType,
2773e5dd7070Spatrick                                QualType &baseType,
2774e5dd7070Spatrick                                Address &addr);
2775e5dd7070Spatrick 
2776e5dd7070Spatrick   /// EmitVLASize - Capture all the sizes for the VLA expressions in
2777e5dd7070Spatrick   /// the given variably-modified type and store them in the VLASizeMap.
2778e5dd7070Spatrick   ///
2779e5dd7070Spatrick   /// This function can be called with a null (unreachable) insert point.
2780e5dd7070Spatrick   void EmitVariablyModifiedType(QualType Ty);
2781e5dd7070Spatrick 
2782e5dd7070Spatrick   struct VlaSizePair {
2783e5dd7070Spatrick     llvm::Value *NumElts;
2784e5dd7070Spatrick     QualType Type;
2785e5dd7070Spatrick 
2786e5dd7070Spatrick     VlaSizePair(llvm::Value *NE, QualType T) : NumElts(NE), Type(T) {}
2787e5dd7070Spatrick   };
2788e5dd7070Spatrick 
2789e5dd7070Spatrick   /// Return the number of elements for a single dimension
2790e5dd7070Spatrick   /// for the given array type.
2791e5dd7070Spatrick   VlaSizePair getVLAElements1D(const VariableArrayType *vla);
2792e5dd7070Spatrick   VlaSizePair getVLAElements1D(QualType vla);
2793e5dd7070Spatrick 
2794e5dd7070Spatrick   /// Returns an LLVM value that corresponds to the size,
2795e5dd7070Spatrick   /// in non-variably-sized elements, of a variable length array type,
2796e5dd7070Spatrick   /// plus that largest non-variably-sized element type.  Assumes that
2797e5dd7070Spatrick   /// the type has already been emitted with EmitVariablyModifiedType.
2798e5dd7070Spatrick   VlaSizePair getVLASize(const VariableArrayType *vla);
2799e5dd7070Spatrick   VlaSizePair getVLASize(QualType vla);
2800e5dd7070Spatrick 
2801e5dd7070Spatrick   /// LoadCXXThis - Load the value of 'this'. This function is only valid while
2802e5dd7070Spatrick   /// generating code for an C++ member function.
2803e5dd7070Spatrick   llvm::Value *LoadCXXThis() {
2804e5dd7070Spatrick     assert(CXXThisValue && "no 'this' value for this function");
2805e5dd7070Spatrick     return CXXThisValue;
2806e5dd7070Spatrick   }
2807e5dd7070Spatrick   Address LoadCXXThisAddress();
2808e5dd7070Spatrick 
2809e5dd7070Spatrick   /// LoadCXXVTT - Load the VTT parameter to base constructors/destructors have
2810e5dd7070Spatrick   /// virtual bases.
2811e5dd7070Spatrick   // FIXME: Every place that calls LoadCXXVTT is something
2812e5dd7070Spatrick   // that needs to be abstracted properly.
2813e5dd7070Spatrick   llvm::Value *LoadCXXVTT() {
2814e5dd7070Spatrick     assert(CXXStructorImplicitParamValue && "no VTT value for this function");
2815e5dd7070Spatrick     return CXXStructorImplicitParamValue;
2816e5dd7070Spatrick   }
2817e5dd7070Spatrick 
2818e5dd7070Spatrick   /// GetAddressOfBaseOfCompleteClass - Convert the given pointer to a
2819e5dd7070Spatrick   /// complete class to the given direct base.
2820e5dd7070Spatrick   Address
2821e5dd7070Spatrick   GetAddressOfDirectBaseInCompleteClass(Address Value,
2822e5dd7070Spatrick                                         const CXXRecordDecl *Derived,
2823e5dd7070Spatrick                                         const CXXRecordDecl *Base,
2824e5dd7070Spatrick                                         bool BaseIsVirtual);
2825e5dd7070Spatrick 
2826e5dd7070Spatrick   static bool ShouldNullCheckClassCastValue(const CastExpr *Cast);
2827e5dd7070Spatrick 
2828e5dd7070Spatrick   /// GetAddressOfBaseClass - This function will add the necessary delta to the
2829e5dd7070Spatrick   /// load of 'this' and returns address of the base class.
2830e5dd7070Spatrick   Address GetAddressOfBaseClass(Address Value,
2831e5dd7070Spatrick                                 const CXXRecordDecl *Derived,
2832e5dd7070Spatrick                                 CastExpr::path_const_iterator PathBegin,
2833e5dd7070Spatrick                                 CastExpr::path_const_iterator PathEnd,
2834e5dd7070Spatrick                                 bool NullCheckValue, SourceLocation Loc);
2835e5dd7070Spatrick 
2836e5dd7070Spatrick   Address GetAddressOfDerivedClass(Address Value,
2837e5dd7070Spatrick                                    const CXXRecordDecl *Derived,
2838e5dd7070Spatrick                                    CastExpr::path_const_iterator PathBegin,
2839e5dd7070Spatrick                                    CastExpr::path_const_iterator PathEnd,
2840e5dd7070Spatrick                                    bool NullCheckValue);
2841e5dd7070Spatrick 
2842e5dd7070Spatrick   /// GetVTTParameter - Return the VTT parameter that should be passed to a
2843e5dd7070Spatrick   /// base constructor/destructor with virtual bases.
2844e5dd7070Spatrick   /// FIXME: VTTs are Itanium ABI-specific, so the definition should move
2845e5dd7070Spatrick   /// to ItaniumCXXABI.cpp together with all the references to VTT.
2846e5dd7070Spatrick   llvm::Value *GetVTTParameter(GlobalDecl GD, bool ForVirtualBase,
2847e5dd7070Spatrick                                bool Delegating);
2848e5dd7070Spatrick 
2849e5dd7070Spatrick   void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
2850e5dd7070Spatrick                                       CXXCtorType CtorType,
2851e5dd7070Spatrick                                       const FunctionArgList &Args,
2852e5dd7070Spatrick                                       SourceLocation Loc);
2853e5dd7070Spatrick   // It's important not to confuse this and the previous function. Delegating
2854e5dd7070Spatrick   // constructors are the C++0x feature. The constructor delegate optimization
2855e5dd7070Spatrick   // is used to reduce duplication in the base and complete consturctors where
2856e5dd7070Spatrick   // they are substantially the same.
2857e5dd7070Spatrick   void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor,
2858e5dd7070Spatrick                                         const FunctionArgList &Args);
2859e5dd7070Spatrick 
2860e5dd7070Spatrick   /// Emit a call to an inheriting constructor (that is, one that invokes a
2861e5dd7070Spatrick   /// constructor inherited from a base class) by inlining its definition. This
2862e5dd7070Spatrick   /// is necessary if the ABI does not support forwarding the arguments to the
2863e5dd7070Spatrick   /// base class constructor (because they're variadic or similar).
2864e5dd7070Spatrick   void EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor,
2865e5dd7070Spatrick                                                CXXCtorType CtorType,
2866e5dd7070Spatrick                                                bool ForVirtualBase,
2867e5dd7070Spatrick                                                bool Delegating,
2868e5dd7070Spatrick                                                CallArgList &Args);
2869e5dd7070Spatrick 
2870e5dd7070Spatrick   /// Emit a call to a constructor inherited from a base class, passing the
2871e5dd7070Spatrick   /// current constructor's arguments along unmodified (without even making
2872e5dd7070Spatrick   /// a copy).
2873e5dd7070Spatrick   void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D,
2874e5dd7070Spatrick                                        bool ForVirtualBase, Address This,
2875e5dd7070Spatrick                                        bool InheritedFromVBase,
2876e5dd7070Spatrick                                        const CXXInheritedCtorInitExpr *E);
2877e5dd7070Spatrick 
2878e5dd7070Spatrick   void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
2879e5dd7070Spatrick                               bool ForVirtualBase, bool Delegating,
2880e5dd7070Spatrick                               AggValueSlot ThisAVS, const CXXConstructExpr *E);
2881e5dd7070Spatrick 
2882e5dd7070Spatrick   void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
2883e5dd7070Spatrick                               bool ForVirtualBase, bool Delegating,
2884e5dd7070Spatrick                               Address This, CallArgList &Args,
2885e5dd7070Spatrick                               AggValueSlot::Overlap_t Overlap,
2886e5dd7070Spatrick                               SourceLocation Loc, bool NewPointerIsChecked);
2887e5dd7070Spatrick 
2888*12c85518Srobert   /// Emit assumption load for all bases. Requires to be called only on
2889e5dd7070Spatrick   /// most-derived class and not under construction of the object.
2890e5dd7070Spatrick   void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This);
2891e5dd7070Spatrick 
2892e5dd7070Spatrick   /// Emit assumption that vptr load == global vtable.
2893e5dd7070Spatrick   void EmitVTableAssumptionLoad(const VPtr &vptr, Address This);
2894e5dd7070Spatrick 
2895e5dd7070Spatrick   void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
2896e5dd7070Spatrick                                       Address This, Address Src,
2897e5dd7070Spatrick                                       const CXXConstructExpr *E);
2898e5dd7070Spatrick 
2899e5dd7070Spatrick   void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
2900e5dd7070Spatrick                                   const ArrayType *ArrayTy,
2901e5dd7070Spatrick                                   Address ArrayPtr,
2902e5dd7070Spatrick                                   const CXXConstructExpr *E,
2903e5dd7070Spatrick                                   bool NewPointerIsChecked,
2904e5dd7070Spatrick                                   bool ZeroInitialization = false);
2905e5dd7070Spatrick 
2906e5dd7070Spatrick   void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
2907e5dd7070Spatrick                                   llvm::Value *NumElements,
2908e5dd7070Spatrick                                   Address ArrayPtr,
2909e5dd7070Spatrick                                   const CXXConstructExpr *E,
2910e5dd7070Spatrick                                   bool NewPointerIsChecked,
2911e5dd7070Spatrick                                   bool ZeroInitialization = false);
2912e5dd7070Spatrick 
2913e5dd7070Spatrick   static Destroyer destroyCXXObject;
2914e5dd7070Spatrick 
2915e5dd7070Spatrick   void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type,
2916e5dd7070Spatrick                              bool ForVirtualBase, bool Delegating, Address This,
2917e5dd7070Spatrick                              QualType ThisTy);
2918e5dd7070Spatrick 
2919e5dd7070Spatrick   void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType,
2920e5dd7070Spatrick                                llvm::Type *ElementTy, Address NewPtr,
2921e5dd7070Spatrick                                llvm::Value *NumElements,
2922e5dd7070Spatrick                                llvm::Value *AllocSizeWithoutCookie);
2923e5dd7070Spatrick 
2924e5dd7070Spatrick   void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType,
2925e5dd7070Spatrick                         Address Ptr);
2926e5dd7070Spatrick 
2927a9ac8606Spatrick   void EmitSehCppScopeBegin();
2928a9ac8606Spatrick   void EmitSehCppScopeEnd();
2929a9ac8606Spatrick   void EmitSehTryScopeBegin();
2930a9ac8606Spatrick   void EmitSehTryScopeEnd();
2931a9ac8606Spatrick 
2932a9ac8606Spatrick   llvm::Value *EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr);
2933e5dd7070Spatrick   void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr);
2934e5dd7070Spatrick 
2935e5dd7070Spatrick   llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E);
2936e5dd7070Spatrick   void EmitCXXDeleteExpr(const CXXDeleteExpr *E);
2937e5dd7070Spatrick 
2938e5dd7070Spatrick   void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr,
2939e5dd7070Spatrick                       QualType DeleteTy, llvm::Value *NumElements = nullptr,
2940e5dd7070Spatrick                       CharUnits CookieSize = CharUnits());
2941e5dd7070Spatrick 
2942e5dd7070Spatrick   RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type,
2943e5dd7070Spatrick                                   const CallExpr *TheCallExpr, bool IsDelete);
2944e5dd7070Spatrick 
2945e5dd7070Spatrick   llvm::Value *EmitCXXTypeidExpr(const CXXTypeidExpr *E);
2946e5dd7070Spatrick   llvm::Value *EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE);
2947e5dd7070Spatrick   Address EmitCXXUuidofExpr(const CXXUuidofExpr *E);
2948e5dd7070Spatrick 
2949e5dd7070Spatrick   /// Situations in which we might emit a check for the suitability of a
2950ec727ea7Spatrick   /// pointer or glvalue. Needs to be kept in sync with ubsan_handlers.cpp in
2951ec727ea7Spatrick   /// compiler-rt.
2952e5dd7070Spatrick   enum TypeCheckKind {
2953e5dd7070Spatrick     /// Checking the operand of a load. Must be suitably sized and aligned.
2954e5dd7070Spatrick     TCK_Load,
2955e5dd7070Spatrick     /// Checking the destination of a store. Must be suitably sized and aligned.
2956e5dd7070Spatrick     TCK_Store,
2957e5dd7070Spatrick     /// Checking the bound value in a reference binding. Must be suitably sized
2958e5dd7070Spatrick     /// and aligned, but is not required to refer to an object (until the
2959e5dd7070Spatrick     /// reference is used), per core issue 453.
2960e5dd7070Spatrick     TCK_ReferenceBinding,
2961e5dd7070Spatrick     /// Checking the object expression in a non-static data member access. Must
2962e5dd7070Spatrick     /// be an object within its lifetime.
2963e5dd7070Spatrick     TCK_MemberAccess,
2964e5dd7070Spatrick     /// Checking the 'this' pointer for a call to a non-static member function.
2965e5dd7070Spatrick     /// Must be an object within its lifetime.
2966e5dd7070Spatrick     TCK_MemberCall,
2967e5dd7070Spatrick     /// Checking the 'this' pointer for a constructor call.
2968e5dd7070Spatrick     TCK_ConstructorCall,
2969e5dd7070Spatrick     /// Checking the operand of a static_cast to a derived pointer type. Must be
2970e5dd7070Spatrick     /// null or an object within its lifetime.
2971e5dd7070Spatrick     TCK_DowncastPointer,
2972e5dd7070Spatrick     /// Checking the operand of a static_cast to a derived reference type. Must
2973e5dd7070Spatrick     /// be an object within its lifetime.
2974e5dd7070Spatrick     TCK_DowncastReference,
2975e5dd7070Spatrick     /// Checking the operand of a cast to a base object. Must be suitably sized
2976e5dd7070Spatrick     /// and aligned.
2977e5dd7070Spatrick     TCK_Upcast,
2978e5dd7070Spatrick     /// Checking the operand of a cast to a virtual base object. Must be an
2979e5dd7070Spatrick     /// object within its lifetime.
2980e5dd7070Spatrick     TCK_UpcastToVirtualBase,
2981e5dd7070Spatrick     /// Checking the value assigned to a _Nonnull pointer. Must not be null.
2982e5dd7070Spatrick     TCK_NonnullAssign,
2983e5dd7070Spatrick     /// Checking the operand of a dynamic_cast or a typeid expression.  Must be
2984e5dd7070Spatrick     /// null or an object within its lifetime.
2985e5dd7070Spatrick     TCK_DynamicOperation
2986e5dd7070Spatrick   };
2987e5dd7070Spatrick 
2988e5dd7070Spatrick   /// Determine whether the pointer type check \p TCK permits null pointers.
2989e5dd7070Spatrick   static bool isNullPointerAllowed(TypeCheckKind TCK);
2990e5dd7070Spatrick 
2991e5dd7070Spatrick   /// Determine whether the pointer type check \p TCK requires a vptr check.
2992e5dd7070Spatrick   static bool isVptrCheckRequired(TypeCheckKind TCK, QualType Ty);
2993e5dd7070Spatrick 
2994e5dd7070Spatrick   /// Whether any type-checking sanitizers are enabled. If \c false,
2995e5dd7070Spatrick   /// calls to EmitTypeCheck can be skipped.
2996e5dd7070Spatrick   bool sanitizePerformTypeCheck() const;
2997e5dd7070Spatrick 
2998e5dd7070Spatrick   /// Emit a check that \p V is the address of storage of the
2999e5dd7070Spatrick   /// appropriate size and alignment for an object of type \p Type
3000e5dd7070Spatrick   /// (or if ArraySize is provided, for an array of that bound).
3001e5dd7070Spatrick   void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V,
3002e5dd7070Spatrick                      QualType Type, CharUnits Alignment = CharUnits::Zero(),
3003e5dd7070Spatrick                      SanitizerSet SkippedChecks = SanitizerSet(),
3004e5dd7070Spatrick                      llvm::Value *ArraySize = nullptr);
3005e5dd7070Spatrick 
3006e5dd7070Spatrick   /// Emit a check that \p Base points into an array object, which
3007e5dd7070Spatrick   /// we can access at index \p Index. \p Accessed should be \c false if we
3008e5dd7070Spatrick   /// this expression is used as an lvalue, for instance in "&Arr[Idx]".
3009e5dd7070Spatrick   void EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index,
3010e5dd7070Spatrick                        QualType IndexType, bool Accessed);
3011e5dd7070Spatrick 
3012e5dd7070Spatrick   llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
3013e5dd7070Spatrick                                        bool isInc, bool isPre);
3014e5dd7070Spatrick   ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
3015e5dd7070Spatrick                                          bool isInc, bool isPre);
3016e5dd7070Spatrick 
3017e5dd7070Spatrick   /// Converts Location to a DebugLoc, if debug information is enabled.
3018e5dd7070Spatrick   llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location);
3019e5dd7070Spatrick 
3020e5dd7070Spatrick   /// Get the record field index as represented in debug info.
3021e5dd7070Spatrick   unsigned getDebugInfoFIndex(const RecordDecl *Rec, unsigned FieldIndex);
3022e5dd7070Spatrick 
3023e5dd7070Spatrick 
3024e5dd7070Spatrick   //===--------------------------------------------------------------------===//
3025e5dd7070Spatrick   //                            Declaration Emission
3026e5dd7070Spatrick   //===--------------------------------------------------------------------===//
3027e5dd7070Spatrick 
3028e5dd7070Spatrick   /// EmitDecl - Emit a declaration.
3029e5dd7070Spatrick   ///
3030e5dd7070Spatrick   /// This function can be called with a null (unreachable) insert point.
3031e5dd7070Spatrick   void EmitDecl(const Decl &D);
3032e5dd7070Spatrick 
3033e5dd7070Spatrick   /// EmitVarDecl - Emit a local variable declaration.
3034e5dd7070Spatrick   ///
3035e5dd7070Spatrick   /// This function can be called with a null (unreachable) insert point.
3036e5dd7070Spatrick   void EmitVarDecl(const VarDecl &D);
3037e5dd7070Spatrick 
3038e5dd7070Spatrick   void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue,
3039e5dd7070Spatrick                       bool capturedByInit);
3040e5dd7070Spatrick 
3041e5dd7070Spatrick   typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D,
3042e5dd7070Spatrick                              llvm::Value *Address);
3043e5dd7070Spatrick 
3044e5dd7070Spatrick   /// Determine whether the given initializer is trivial in the sense
3045e5dd7070Spatrick   /// that it requires no code to be generated.
3046e5dd7070Spatrick   bool isTrivialInitializer(const Expr *Init);
3047e5dd7070Spatrick 
3048e5dd7070Spatrick   /// EmitAutoVarDecl - Emit an auto variable declaration.
3049e5dd7070Spatrick   ///
3050e5dd7070Spatrick   /// This function can be called with a null (unreachable) insert point.
3051e5dd7070Spatrick   void EmitAutoVarDecl(const VarDecl &D);
3052e5dd7070Spatrick 
3053e5dd7070Spatrick   class AutoVarEmission {
3054e5dd7070Spatrick     friend class CodeGenFunction;
3055e5dd7070Spatrick 
3056e5dd7070Spatrick     const VarDecl *Variable;
3057e5dd7070Spatrick 
3058e5dd7070Spatrick     /// The address of the alloca for languages with explicit address space
3059e5dd7070Spatrick     /// (e.g. OpenCL) or alloca casted to generic pointer for address space
3060e5dd7070Spatrick     /// agnostic languages (e.g. C++). Invalid if the variable was emitted
3061e5dd7070Spatrick     /// as a global constant.
3062e5dd7070Spatrick     Address Addr;
3063e5dd7070Spatrick 
3064e5dd7070Spatrick     llvm::Value *NRVOFlag;
3065e5dd7070Spatrick 
3066e5dd7070Spatrick     /// True if the variable is a __block variable that is captured by an
3067e5dd7070Spatrick     /// escaping block.
3068e5dd7070Spatrick     bool IsEscapingByRef;
3069e5dd7070Spatrick 
3070e5dd7070Spatrick     /// True if the variable is of aggregate type and has a constant
3071e5dd7070Spatrick     /// initializer.
3072e5dd7070Spatrick     bool IsConstantAggregate;
3073e5dd7070Spatrick 
3074e5dd7070Spatrick     /// Non-null if we should use lifetime annotations.
3075e5dd7070Spatrick     llvm::Value *SizeForLifetimeMarkers;
3076e5dd7070Spatrick 
3077e5dd7070Spatrick     /// Address with original alloca instruction. Invalid if the variable was
3078e5dd7070Spatrick     /// emitted as a global constant.
3079e5dd7070Spatrick     Address AllocaAddr;
3080e5dd7070Spatrick 
3081e5dd7070Spatrick     struct Invalid {};
3082e5dd7070Spatrick     AutoVarEmission(Invalid)
3083e5dd7070Spatrick         : Variable(nullptr), Addr(Address::invalid()),
3084e5dd7070Spatrick           AllocaAddr(Address::invalid()) {}
3085e5dd7070Spatrick 
3086e5dd7070Spatrick     AutoVarEmission(const VarDecl &variable)
3087e5dd7070Spatrick         : Variable(&variable), Addr(Address::invalid()), NRVOFlag(nullptr),
3088e5dd7070Spatrick           IsEscapingByRef(false), IsConstantAggregate(false),
3089e5dd7070Spatrick           SizeForLifetimeMarkers(nullptr), AllocaAddr(Address::invalid()) {}
3090e5dd7070Spatrick 
3091e5dd7070Spatrick     bool wasEmittedAsGlobal() const { return !Addr.isValid(); }
3092e5dd7070Spatrick 
3093e5dd7070Spatrick   public:
3094e5dd7070Spatrick     static AutoVarEmission invalid() { return AutoVarEmission(Invalid()); }
3095e5dd7070Spatrick 
3096e5dd7070Spatrick     bool useLifetimeMarkers() const {
3097e5dd7070Spatrick       return SizeForLifetimeMarkers != nullptr;
3098e5dd7070Spatrick     }
3099e5dd7070Spatrick     llvm::Value *getSizeForLifetimeMarkers() const {
3100e5dd7070Spatrick       assert(useLifetimeMarkers());
3101e5dd7070Spatrick       return SizeForLifetimeMarkers;
3102e5dd7070Spatrick     }
3103e5dd7070Spatrick 
3104e5dd7070Spatrick     /// Returns the raw, allocated address, which is not necessarily
3105e5dd7070Spatrick     /// the address of the object itself. It is casted to default
3106e5dd7070Spatrick     /// address space for address space agnostic languages.
3107e5dd7070Spatrick     Address getAllocatedAddress() const {
3108e5dd7070Spatrick       return Addr;
3109e5dd7070Spatrick     }
3110e5dd7070Spatrick 
3111e5dd7070Spatrick     /// Returns the address for the original alloca instruction.
3112e5dd7070Spatrick     Address getOriginalAllocatedAddress() const { return AllocaAddr; }
3113e5dd7070Spatrick 
3114e5dd7070Spatrick     /// Returns the address of the object within this declaration.
3115e5dd7070Spatrick     /// Note that this does not chase the forwarding pointer for
3116e5dd7070Spatrick     /// __block decls.
3117e5dd7070Spatrick     Address getObjectAddress(CodeGenFunction &CGF) const {
3118e5dd7070Spatrick       if (!IsEscapingByRef) return Addr;
3119e5dd7070Spatrick 
3120e5dd7070Spatrick       return CGF.emitBlockByrefAddress(Addr, Variable, /*forward*/ false);
3121e5dd7070Spatrick     }
3122e5dd7070Spatrick   };
3123e5dd7070Spatrick   AutoVarEmission EmitAutoVarAlloca(const VarDecl &var);
3124e5dd7070Spatrick   void EmitAutoVarInit(const AutoVarEmission &emission);
3125e5dd7070Spatrick   void EmitAutoVarCleanups(const AutoVarEmission &emission);
3126e5dd7070Spatrick   void emitAutoVarTypeCleanup(const AutoVarEmission &emission,
3127e5dd7070Spatrick                               QualType::DestructionKind dtorKind);
3128e5dd7070Spatrick 
3129e5dd7070Spatrick   /// Emits the alloca and debug information for the size expressions for each
3130e5dd7070Spatrick   /// dimension of an array. It registers the association of its (1-dimensional)
3131e5dd7070Spatrick   /// QualTypes and size expression's debug node, so that CGDebugInfo can
3132e5dd7070Spatrick   /// reference this node when creating the DISubrange object to describe the
3133e5dd7070Spatrick   /// array types.
3134e5dd7070Spatrick   void EmitAndRegisterVariableArrayDimensions(CGDebugInfo *DI,
3135e5dd7070Spatrick                                               const VarDecl &D,
3136e5dd7070Spatrick                                               bool EmitDebugInfo);
3137e5dd7070Spatrick 
3138e5dd7070Spatrick   void EmitStaticVarDecl(const VarDecl &D,
3139e5dd7070Spatrick                          llvm::GlobalValue::LinkageTypes Linkage);
3140e5dd7070Spatrick 
3141e5dd7070Spatrick   class ParamValue {
3142e5dd7070Spatrick     llvm::Value *Value;
3143*12c85518Srobert     llvm::Type *ElementType;
3144e5dd7070Spatrick     unsigned Alignment;
3145*12c85518Srobert     ParamValue(llvm::Value *V, llvm::Type *T, unsigned A)
3146*12c85518Srobert         : Value(V), ElementType(T), Alignment(A) {}
3147e5dd7070Spatrick   public:
3148e5dd7070Spatrick     static ParamValue forDirect(llvm::Value *value) {
3149*12c85518Srobert       return ParamValue(value, nullptr, 0);
3150e5dd7070Spatrick     }
3151e5dd7070Spatrick     static ParamValue forIndirect(Address addr) {
3152e5dd7070Spatrick       assert(!addr.getAlignment().isZero());
3153*12c85518Srobert       return ParamValue(addr.getPointer(), addr.getElementType(),
3154*12c85518Srobert                         addr.getAlignment().getQuantity());
3155e5dd7070Spatrick     }
3156e5dd7070Spatrick 
3157e5dd7070Spatrick     bool isIndirect() const { return Alignment != 0; }
3158e5dd7070Spatrick     llvm::Value *getAnyValue() const { return Value; }
3159e5dd7070Spatrick 
3160e5dd7070Spatrick     llvm::Value *getDirectValue() const {
3161e5dd7070Spatrick       assert(!isIndirect());
3162e5dd7070Spatrick       return Value;
3163e5dd7070Spatrick     }
3164e5dd7070Spatrick 
3165e5dd7070Spatrick     Address getIndirectAddress() const {
3166e5dd7070Spatrick       assert(isIndirect());
3167*12c85518Srobert       return Address(Value, ElementType, CharUnits::fromQuantity(Alignment));
3168e5dd7070Spatrick     }
3169e5dd7070Spatrick   };
3170e5dd7070Spatrick 
3171e5dd7070Spatrick   /// EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
3172e5dd7070Spatrick   void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo);
3173e5dd7070Spatrick 
3174e5dd7070Spatrick   /// protectFromPeepholes - Protect a value that we're intending to
3175e5dd7070Spatrick   /// store to the side, but which will probably be used later, from
3176e5dd7070Spatrick   /// aggressive peepholing optimizations that might delete it.
3177e5dd7070Spatrick   ///
3178e5dd7070Spatrick   /// Pass the result to unprotectFromPeepholes to declare that
3179e5dd7070Spatrick   /// protection is no longer required.
3180e5dd7070Spatrick   ///
3181e5dd7070Spatrick   /// There's no particular reason why this shouldn't apply to
3182e5dd7070Spatrick   /// l-values, it's just that no existing peepholes work on pointers.
3183e5dd7070Spatrick   PeepholeProtection protectFromPeepholes(RValue rvalue);
3184e5dd7070Spatrick   void unprotectFromPeepholes(PeepholeProtection protection);
3185e5dd7070Spatrick 
3186ec727ea7Spatrick   void emitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType Ty,
3187e5dd7070Spatrick                                     SourceLocation Loc,
3188e5dd7070Spatrick                                     SourceLocation AssumptionLoc,
3189e5dd7070Spatrick                                     llvm::Value *Alignment,
3190e5dd7070Spatrick                                     llvm::Value *OffsetValue,
3191e5dd7070Spatrick                                     llvm::Value *TheCheck,
3192e5dd7070Spatrick                                     llvm::Instruction *Assumption);
3193e5dd7070Spatrick 
3194ec727ea7Spatrick   void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty,
3195e5dd7070Spatrick                                SourceLocation Loc, SourceLocation AssumptionLoc,
3196e5dd7070Spatrick                                llvm::Value *Alignment,
3197e5dd7070Spatrick                                llvm::Value *OffsetValue = nullptr);
3198e5dd7070Spatrick 
3199ec727ea7Spatrick   void emitAlignmentAssumption(llvm::Value *PtrValue, const Expr *E,
3200ec727ea7Spatrick                                SourceLocation AssumptionLoc,
3201ec727ea7Spatrick                                llvm::Value *Alignment,
3202e5dd7070Spatrick                                llvm::Value *OffsetValue = nullptr);
3203e5dd7070Spatrick 
3204e5dd7070Spatrick   //===--------------------------------------------------------------------===//
3205e5dd7070Spatrick   //                             Statement Emission
3206e5dd7070Spatrick   //===--------------------------------------------------------------------===//
3207e5dd7070Spatrick 
3208e5dd7070Spatrick   /// EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
3209e5dd7070Spatrick   void EmitStopPoint(const Stmt *S);
3210e5dd7070Spatrick 
3211e5dd7070Spatrick   /// EmitStmt - Emit the code for the statement \arg S. It is legal to call
3212e5dd7070Spatrick   /// this function even if there is no current insertion point.
3213e5dd7070Spatrick   ///
3214e5dd7070Spatrick   /// This function may clear the current insertion point; callers should use
3215e5dd7070Spatrick   /// EnsureInsertPoint if they wish to subsequently generate code without first
3216e5dd7070Spatrick   /// calling EmitBlock, EmitBranch, or EmitStmt.
3217*12c85518Srobert   void EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs = std::nullopt);
3218e5dd7070Spatrick 
3219e5dd7070Spatrick   /// EmitSimpleStmt - Try to emit a "simple" statement which does not
3220e5dd7070Spatrick   /// necessarily require an insertion point or debug information; typically
3221e5dd7070Spatrick   /// because the statement amounts to a jump or a container of other
3222e5dd7070Spatrick   /// statements.
3223e5dd7070Spatrick   ///
3224e5dd7070Spatrick   /// \return True if the statement was handled.
3225a9ac8606Spatrick   bool EmitSimpleStmt(const Stmt *S, ArrayRef<const Attr *> Attrs);
3226e5dd7070Spatrick 
3227e5dd7070Spatrick   Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false,
3228e5dd7070Spatrick                            AggValueSlot AVS = AggValueSlot::ignored());
3229e5dd7070Spatrick   Address EmitCompoundStmtWithoutScope(const CompoundStmt &S,
3230e5dd7070Spatrick                                        bool GetLast = false,
3231e5dd7070Spatrick                                        AggValueSlot AVS =
3232e5dd7070Spatrick                                                 AggValueSlot::ignored());
3233e5dd7070Spatrick 
3234e5dd7070Spatrick   /// EmitLabel - Emit the block for the given label. It is legal to call this
3235e5dd7070Spatrick   /// function even if there is no current insertion point.
3236e5dd7070Spatrick   void EmitLabel(const LabelDecl *D); // helper for EmitLabelStmt.
3237e5dd7070Spatrick 
3238e5dd7070Spatrick   void EmitLabelStmt(const LabelStmt &S);
3239e5dd7070Spatrick   void EmitAttributedStmt(const AttributedStmt &S);
3240e5dd7070Spatrick   void EmitGotoStmt(const GotoStmt &S);
3241e5dd7070Spatrick   void EmitIndirectGotoStmt(const IndirectGotoStmt &S);
3242e5dd7070Spatrick   void EmitIfStmt(const IfStmt &S);
3243e5dd7070Spatrick 
3244e5dd7070Spatrick   void EmitWhileStmt(const WhileStmt &S,
3245*12c85518Srobert                      ArrayRef<const Attr *> Attrs = std::nullopt);
3246*12c85518Srobert   void EmitDoStmt(const DoStmt &S, ArrayRef<const Attr *> Attrs = std::nullopt);
3247e5dd7070Spatrick   void EmitForStmt(const ForStmt &S,
3248*12c85518Srobert                    ArrayRef<const Attr *> Attrs = std::nullopt);
3249e5dd7070Spatrick   void EmitReturnStmt(const ReturnStmt &S);
3250e5dd7070Spatrick   void EmitDeclStmt(const DeclStmt &S);
3251e5dd7070Spatrick   void EmitBreakStmt(const BreakStmt &S);
3252e5dd7070Spatrick   void EmitContinueStmt(const ContinueStmt &S);
3253e5dd7070Spatrick   void EmitSwitchStmt(const SwitchStmt &S);
3254a9ac8606Spatrick   void EmitDefaultStmt(const DefaultStmt &S, ArrayRef<const Attr *> Attrs);
3255a9ac8606Spatrick   void EmitCaseStmt(const CaseStmt &S, ArrayRef<const Attr *> Attrs);
3256a9ac8606Spatrick   void EmitCaseStmtRange(const CaseStmt &S, ArrayRef<const Attr *> Attrs);
3257e5dd7070Spatrick   void EmitAsmStmt(const AsmStmt &S);
3258e5dd7070Spatrick 
3259e5dd7070Spatrick   void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S);
3260e5dd7070Spatrick   void EmitObjCAtTryStmt(const ObjCAtTryStmt &S);
3261e5dd7070Spatrick   void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S);
3262e5dd7070Spatrick   void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S);
3263e5dd7070Spatrick   void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S);
3264e5dd7070Spatrick 
3265e5dd7070Spatrick   void EmitCoroutineBody(const CoroutineBodyStmt &S);
3266e5dd7070Spatrick   void EmitCoreturnStmt(const CoreturnStmt &S);
3267e5dd7070Spatrick   RValue EmitCoawaitExpr(const CoawaitExpr &E,
3268e5dd7070Spatrick                          AggValueSlot aggSlot = AggValueSlot::ignored(),
3269e5dd7070Spatrick                          bool ignoreResult = false);
3270e5dd7070Spatrick   LValue EmitCoawaitLValue(const CoawaitExpr *E);
3271e5dd7070Spatrick   RValue EmitCoyieldExpr(const CoyieldExpr &E,
3272e5dd7070Spatrick                          AggValueSlot aggSlot = AggValueSlot::ignored(),
3273e5dd7070Spatrick                          bool ignoreResult = false);
3274e5dd7070Spatrick   LValue EmitCoyieldLValue(const CoyieldExpr *E);
3275e5dd7070Spatrick   RValue EmitCoroutineIntrinsic(const CallExpr *E, unsigned int IID);
3276e5dd7070Spatrick 
3277e5dd7070Spatrick   void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
3278e5dd7070Spatrick   void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
3279e5dd7070Spatrick 
3280e5dd7070Spatrick   void EmitCXXTryStmt(const CXXTryStmt &S);
3281e5dd7070Spatrick   void EmitSEHTryStmt(const SEHTryStmt &S);
3282e5dd7070Spatrick   void EmitSEHLeaveStmt(const SEHLeaveStmt &S);
3283e5dd7070Spatrick   void EnterSEHTryStmt(const SEHTryStmt &S);
3284e5dd7070Spatrick   void ExitSEHTryStmt(const SEHTryStmt &S);
3285a9ac8606Spatrick   void VolatilizeTryBlocks(llvm::BasicBlock *BB,
3286a9ac8606Spatrick                            llvm::SmallPtrSet<llvm::BasicBlock *, 10> &V);
3287e5dd7070Spatrick 
3288e5dd7070Spatrick   void pushSEHCleanup(CleanupKind kind,
3289e5dd7070Spatrick                       llvm::Function *FinallyFunc);
3290e5dd7070Spatrick   void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter,
3291e5dd7070Spatrick                               const Stmt *OutlinedStmt);
3292e5dd7070Spatrick 
3293e5dd7070Spatrick   llvm::Function *GenerateSEHFilterFunction(CodeGenFunction &ParentCGF,
3294e5dd7070Spatrick                                             const SEHExceptStmt &Except);
3295e5dd7070Spatrick 
3296e5dd7070Spatrick   llvm::Function *GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF,
3297e5dd7070Spatrick                                              const SEHFinallyStmt &Finally);
3298e5dd7070Spatrick 
3299e5dd7070Spatrick   void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF,
3300e5dd7070Spatrick                                 llvm::Value *ParentFP,
3301e5dd7070Spatrick                                 llvm::Value *EntryEBP);
3302e5dd7070Spatrick   llvm::Value *EmitSEHExceptionCode();
3303e5dd7070Spatrick   llvm::Value *EmitSEHExceptionInfo();
3304e5dd7070Spatrick   llvm::Value *EmitSEHAbnormalTermination();
3305e5dd7070Spatrick 
3306e5dd7070Spatrick   /// Emit simple code for OpenMP directives in Simd-only mode.
3307e5dd7070Spatrick   void EmitSimpleOMPExecutableDirective(const OMPExecutableDirective &D);
3308e5dd7070Spatrick 
3309e5dd7070Spatrick   /// Scan the outlined statement for captures from the parent function. For
3310e5dd7070Spatrick   /// each capture, mark the capture as escaped and emit a call to
3311e5dd7070Spatrick   /// llvm.localrecover. Insert the localrecover result into the LocalDeclMap.
3312e5dd7070Spatrick   void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt,
3313e5dd7070Spatrick                           bool IsFilter);
3314e5dd7070Spatrick 
3315e5dd7070Spatrick   /// Recovers the address of a local in a parent function. ParentVar is the
3316e5dd7070Spatrick   /// address of the variable used in the immediate parent function. It can
3317e5dd7070Spatrick   /// either be an alloca or a call to llvm.localrecover if there are nested
3318e5dd7070Spatrick   /// outlined functions. ParentFP is the frame pointer of the outermost parent
3319e5dd7070Spatrick   /// frame.
3320e5dd7070Spatrick   Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,
3321e5dd7070Spatrick                                     Address ParentVar,
3322e5dd7070Spatrick                                     llvm::Value *ParentFP);
3323e5dd7070Spatrick 
3324e5dd7070Spatrick   void EmitCXXForRangeStmt(const CXXForRangeStmt &S,
3325*12c85518Srobert                            ArrayRef<const Attr *> Attrs = std::nullopt);
3326e5dd7070Spatrick 
3327e5dd7070Spatrick   /// Controls insertion of cancellation exit blocks in worksharing constructs.
3328e5dd7070Spatrick   class OMPCancelStackRAII {
3329e5dd7070Spatrick     CodeGenFunction &CGF;
3330e5dd7070Spatrick 
3331e5dd7070Spatrick   public:
3332e5dd7070Spatrick     OMPCancelStackRAII(CodeGenFunction &CGF, OpenMPDirectiveKind Kind,
3333e5dd7070Spatrick                        bool HasCancel)
3334e5dd7070Spatrick         : CGF(CGF) {
3335e5dd7070Spatrick       CGF.OMPCancelStack.enter(CGF, Kind, HasCancel);
3336e5dd7070Spatrick     }
3337e5dd7070Spatrick     ~OMPCancelStackRAII() { CGF.OMPCancelStack.exit(CGF); }
3338e5dd7070Spatrick   };
3339e5dd7070Spatrick 
3340e5dd7070Spatrick   /// Returns calculated size of the specified type.
3341e5dd7070Spatrick   llvm::Value *getTypeSize(QualType Ty);
3342e5dd7070Spatrick   LValue InitCapturedStruct(const CapturedStmt &S);
3343e5dd7070Spatrick   llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K);
3344e5dd7070Spatrick   llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S);
3345e5dd7070Spatrick   Address GenerateCapturedStmtArgument(const CapturedStmt &S);
3346ec727ea7Spatrick   llvm::Function *GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
3347ec727ea7Spatrick                                                      SourceLocation Loc);
3348e5dd7070Spatrick   void GenerateOpenMPCapturedVars(const CapturedStmt &S,
3349e5dd7070Spatrick                                   SmallVectorImpl<llvm::Value *> &CapturedVars);
3350e5dd7070Spatrick   void emitOMPSimpleStore(LValue LVal, RValue RVal, QualType RValTy,
3351e5dd7070Spatrick                           SourceLocation Loc);
3352e5dd7070Spatrick   /// Perform element by element copying of arrays with type \a
3353e5dd7070Spatrick   /// OriginalType from \a SrcAddr to \a DestAddr using copying procedure
3354e5dd7070Spatrick   /// generated by \a CopyGen.
3355e5dd7070Spatrick   ///
3356e5dd7070Spatrick   /// \param DestAddr Address of the destination array.
3357e5dd7070Spatrick   /// \param SrcAddr Address of the source array.
3358e5dd7070Spatrick   /// \param OriginalType Type of destination and source arrays.
3359e5dd7070Spatrick   /// \param CopyGen Copying procedure that copies value of single array element
3360e5dd7070Spatrick   /// to another single array element.
3361e5dd7070Spatrick   void EmitOMPAggregateAssign(
3362e5dd7070Spatrick       Address DestAddr, Address SrcAddr, QualType OriginalType,
3363e5dd7070Spatrick       const llvm::function_ref<void(Address, Address)> CopyGen);
3364e5dd7070Spatrick   /// Emit proper copying of data from one variable to another.
3365e5dd7070Spatrick   ///
3366e5dd7070Spatrick   /// \param OriginalType Original type of the copied variables.
3367e5dd7070Spatrick   /// \param DestAddr Destination address.
3368e5dd7070Spatrick   /// \param SrcAddr Source address.
3369e5dd7070Spatrick   /// \param DestVD Destination variable used in \a CopyExpr (for arrays, has
3370e5dd7070Spatrick   /// type of the base array element).
3371e5dd7070Spatrick   /// \param SrcVD Source variable used in \a CopyExpr (for arrays, has type of
3372e5dd7070Spatrick   /// the base array element).
3373e5dd7070Spatrick   /// \param Copy Actual copygin expression for copying data from \a SrcVD to \a
3374e5dd7070Spatrick   /// DestVD.
3375e5dd7070Spatrick   void EmitOMPCopy(QualType OriginalType,
3376e5dd7070Spatrick                    Address DestAddr, Address SrcAddr,
3377e5dd7070Spatrick                    const VarDecl *DestVD, const VarDecl *SrcVD,
3378e5dd7070Spatrick                    const Expr *Copy);
3379e5dd7070Spatrick   /// Emit atomic update code for constructs: \a X = \a X \a BO \a E or
3380e5dd7070Spatrick   /// \a X = \a E \a BO \a E.
3381e5dd7070Spatrick   ///
3382e5dd7070Spatrick   /// \param X Value to be updated.
3383e5dd7070Spatrick   /// \param E Update value.
3384e5dd7070Spatrick   /// \param BO Binary operation for update operation.
3385e5dd7070Spatrick   /// \param IsXLHSInRHSPart true if \a X is LHS in RHS part of the update
3386e5dd7070Spatrick   /// expression, false otherwise.
3387e5dd7070Spatrick   /// \param AO Atomic ordering of the generated atomic instructions.
3388e5dd7070Spatrick   /// \param CommonGen Code generator for complex expressions that cannot be
3389e5dd7070Spatrick   /// expressed through atomicrmw instruction.
3390e5dd7070Spatrick   /// \returns <true, OldAtomicValue> if simple 'atomicrmw' instruction was
3391e5dd7070Spatrick   /// generated, <false, RValue::get(nullptr)> otherwise.
3392e5dd7070Spatrick   std::pair<bool, RValue> EmitOMPAtomicSimpleUpdateExpr(
3393e5dd7070Spatrick       LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart,
3394e5dd7070Spatrick       llvm::AtomicOrdering AO, SourceLocation Loc,
3395e5dd7070Spatrick       const llvm::function_ref<RValue(RValue)> CommonGen);
3396e5dd7070Spatrick   bool EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
3397e5dd7070Spatrick                                  OMPPrivateScope &PrivateScope);
3398e5dd7070Spatrick   void EmitOMPPrivateClause(const OMPExecutableDirective &D,
3399e5dd7070Spatrick                             OMPPrivateScope &PrivateScope);
3400e5dd7070Spatrick   void EmitOMPUseDevicePtrClause(
3401ec727ea7Spatrick       const OMPUseDevicePtrClause &C, OMPPrivateScope &PrivateScope,
3402ec727ea7Spatrick       const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap);
3403ec727ea7Spatrick   void EmitOMPUseDeviceAddrClause(
3404ec727ea7Spatrick       const OMPUseDeviceAddrClause &C, OMPPrivateScope &PrivateScope,
3405e5dd7070Spatrick       const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap);
3406e5dd7070Spatrick   /// Emit code for copyin clause in \a D directive. The next code is
3407e5dd7070Spatrick   /// generated at the start of outlined functions for directives:
3408e5dd7070Spatrick   /// \code
3409e5dd7070Spatrick   /// threadprivate_var1 = master_threadprivate_var1;
3410e5dd7070Spatrick   /// operator=(threadprivate_var2, master_threadprivate_var2);
3411e5dd7070Spatrick   /// ...
3412e5dd7070Spatrick   /// __kmpc_barrier(&loc, global_tid);
3413e5dd7070Spatrick   /// \endcode
3414e5dd7070Spatrick   ///
3415e5dd7070Spatrick   /// \param D OpenMP directive possibly with 'copyin' clause(s).
3416e5dd7070Spatrick   /// \returns true if at least one copyin variable is found, false otherwise.
3417e5dd7070Spatrick   bool EmitOMPCopyinClause(const OMPExecutableDirective &D);
3418e5dd7070Spatrick   /// Emit initial code for lastprivate variables. If some variable is
3419e5dd7070Spatrick   /// not also firstprivate, then the default initialization is used. Otherwise
3420e5dd7070Spatrick   /// initialization of this variable is performed by EmitOMPFirstprivateClause
3421e5dd7070Spatrick   /// method.
3422e5dd7070Spatrick   ///
3423e5dd7070Spatrick   /// \param D Directive that may have 'lastprivate' directives.
3424e5dd7070Spatrick   /// \param PrivateScope Private scope for capturing lastprivate variables for
3425e5dd7070Spatrick   /// proper codegen in internal captured statement.
3426e5dd7070Spatrick   ///
3427e5dd7070Spatrick   /// \returns true if there is at least one lastprivate variable, false
3428e5dd7070Spatrick   /// otherwise.
3429e5dd7070Spatrick   bool EmitOMPLastprivateClauseInit(const OMPExecutableDirective &D,
3430e5dd7070Spatrick                                     OMPPrivateScope &PrivateScope);
3431e5dd7070Spatrick   /// Emit final copying of lastprivate values to original variables at
3432e5dd7070Spatrick   /// the end of the worksharing or simd directive.
3433e5dd7070Spatrick   ///
3434e5dd7070Spatrick   /// \param D Directive that has at least one 'lastprivate' directives.
3435e5dd7070Spatrick   /// \param IsLastIterCond Boolean condition that must be set to 'i1 true' if
3436e5dd7070Spatrick   /// it is the last iteration of the loop code in associated directive, or to
3437e5dd7070Spatrick   /// 'i1 false' otherwise. If this item is nullptr, no final check is required.
3438e5dd7070Spatrick   void EmitOMPLastprivateClauseFinal(const OMPExecutableDirective &D,
3439e5dd7070Spatrick                                      bool NoFinals,
3440e5dd7070Spatrick                                      llvm::Value *IsLastIterCond = nullptr);
3441e5dd7070Spatrick   /// Emit initial code for linear clauses.
3442e5dd7070Spatrick   void EmitOMPLinearClause(const OMPLoopDirective &D,
3443e5dd7070Spatrick                            CodeGenFunction::OMPPrivateScope &PrivateScope);
3444e5dd7070Spatrick   /// Emit final code for linear clauses.
3445e5dd7070Spatrick   /// \param CondGen Optional conditional code for final part of codegen for
3446e5dd7070Spatrick   /// linear clause.
3447e5dd7070Spatrick   void EmitOMPLinearClauseFinal(
3448e5dd7070Spatrick       const OMPLoopDirective &D,
3449e5dd7070Spatrick       const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen);
3450e5dd7070Spatrick   /// Emit initial code for reduction variables. Creates reduction copies
3451e5dd7070Spatrick   /// and initializes them with the values according to OpenMP standard.
3452e5dd7070Spatrick   ///
3453e5dd7070Spatrick   /// \param D Directive (possibly) with the 'reduction' clause.
3454e5dd7070Spatrick   /// \param PrivateScope Private scope for capturing reduction variables for
3455e5dd7070Spatrick   /// proper codegen in internal captured statement.
3456e5dd7070Spatrick   ///
3457e5dd7070Spatrick   void EmitOMPReductionClauseInit(const OMPExecutableDirective &D,
3458ec727ea7Spatrick                                   OMPPrivateScope &PrivateScope,
3459ec727ea7Spatrick                                   bool ForInscan = false);
3460e5dd7070Spatrick   /// Emit final update of reduction values to original variables at
3461e5dd7070Spatrick   /// the end of the directive.
3462e5dd7070Spatrick   ///
3463e5dd7070Spatrick   /// \param D Directive that has at least one 'reduction' directives.
3464e5dd7070Spatrick   /// \param ReductionKind The kind of reduction to perform.
3465e5dd7070Spatrick   void EmitOMPReductionClauseFinal(const OMPExecutableDirective &D,
3466e5dd7070Spatrick                                    const OpenMPDirectiveKind ReductionKind);
3467e5dd7070Spatrick   /// Emit initial code for linear variables. Creates private copies
3468e5dd7070Spatrick   /// and initializes them with the values according to OpenMP standard.
3469e5dd7070Spatrick   ///
3470e5dd7070Spatrick   /// \param D Directive (possibly) with the 'linear' clause.
3471e5dd7070Spatrick   /// \return true if at least one linear variable is found that should be
3472e5dd7070Spatrick   /// initialized with the value of the original variable, false otherwise.
3473e5dd7070Spatrick   bool EmitOMPLinearClauseInit(const OMPLoopDirective &D);
3474e5dd7070Spatrick 
3475e5dd7070Spatrick   typedef const llvm::function_ref<void(CodeGenFunction & /*CGF*/,
3476e5dd7070Spatrick                                         llvm::Function * /*OutlinedFn*/,
3477e5dd7070Spatrick                                         const OMPTaskDataTy & /*Data*/)>
3478e5dd7070Spatrick       TaskGenTy;
3479e5dd7070Spatrick   void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S,
3480e5dd7070Spatrick                                  const OpenMPDirectiveKind CapturedRegion,
3481e5dd7070Spatrick                                  const RegionCodeGenTy &BodyGen,
3482e5dd7070Spatrick                                  const TaskGenTy &TaskGen, OMPTaskDataTy &Data);
3483e5dd7070Spatrick   struct OMPTargetDataInfo {
3484e5dd7070Spatrick     Address BasePointersArray = Address::invalid();
3485e5dd7070Spatrick     Address PointersArray = Address::invalid();
3486e5dd7070Spatrick     Address SizesArray = Address::invalid();
3487a9ac8606Spatrick     Address MappersArray = Address::invalid();
3488e5dd7070Spatrick     unsigned NumberOfTargetItems = 0;
3489e5dd7070Spatrick     explicit OMPTargetDataInfo() = default;
3490e5dd7070Spatrick     OMPTargetDataInfo(Address BasePointersArray, Address PointersArray,
3491a9ac8606Spatrick                       Address SizesArray, Address MappersArray,
3492a9ac8606Spatrick                       unsigned NumberOfTargetItems)
3493e5dd7070Spatrick         : BasePointersArray(BasePointersArray), PointersArray(PointersArray),
3494a9ac8606Spatrick           SizesArray(SizesArray), MappersArray(MappersArray),
3495a9ac8606Spatrick           NumberOfTargetItems(NumberOfTargetItems) {}
3496e5dd7070Spatrick   };
3497e5dd7070Spatrick   void EmitOMPTargetTaskBasedDirective(const OMPExecutableDirective &S,
3498e5dd7070Spatrick                                        const RegionCodeGenTy &BodyGen,
3499e5dd7070Spatrick                                        OMPTargetDataInfo &InputInfo);
3500*12c85518Srobert   void processInReduction(const OMPExecutableDirective &S,
3501*12c85518Srobert                           OMPTaskDataTy &Data,
3502*12c85518Srobert                           CodeGenFunction &CGF,
3503*12c85518Srobert                           const CapturedStmt *CS,
3504*12c85518Srobert                           OMPPrivateScope &Scope);
3505*12c85518Srobert   void EmitOMPMetaDirective(const OMPMetaDirective &S);
3506e5dd7070Spatrick   void EmitOMPParallelDirective(const OMPParallelDirective &S);
3507e5dd7070Spatrick   void EmitOMPSimdDirective(const OMPSimdDirective &S);
3508a9ac8606Spatrick   void EmitOMPTileDirective(const OMPTileDirective &S);
3509a9ac8606Spatrick   void EmitOMPUnrollDirective(const OMPUnrollDirective &S);
3510e5dd7070Spatrick   void EmitOMPForDirective(const OMPForDirective &S);
3511e5dd7070Spatrick   void EmitOMPForSimdDirective(const OMPForSimdDirective &S);
3512e5dd7070Spatrick   void EmitOMPSectionsDirective(const OMPSectionsDirective &S);
3513e5dd7070Spatrick   void EmitOMPSectionDirective(const OMPSectionDirective &S);
3514e5dd7070Spatrick   void EmitOMPSingleDirective(const OMPSingleDirective &S);
3515e5dd7070Spatrick   void EmitOMPMasterDirective(const OMPMasterDirective &S);
3516a9ac8606Spatrick   void EmitOMPMaskedDirective(const OMPMaskedDirective &S);
3517e5dd7070Spatrick   void EmitOMPCriticalDirective(const OMPCriticalDirective &S);
3518e5dd7070Spatrick   void EmitOMPParallelForDirective(const OMPParallelForDirective &S);
3519e5dd7070Spatrick   void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S);
3520e5dd7070Spatrick   void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S);
3521e5dd7070Spatrick   void EmitOMPParallelMasterDirective(const OMPParallelMasterDirective &S);
3522e5dd7070Spatrick   void EmitOMPTaskDirective(const OMPTaskDirective &S);
3523e5dd7070Spatrick   void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S);
3524*12c85518Srobert   void EmitOMPErrorDirective(const OMPErrorDirective &S);
3525e5dd7070Spatrick   void EmitOMPBarrierDirective(const OMPBarrierDirective &S);
3526e5dd7070Spatrick   void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S);
3527e5dd7070Spatrick   void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S);
3528e5dd7070Spatrick   void EmitOMPFlushDirective(const OMPFlushDirective &S);
3529ec727ea7Spatrick   void EmitOMPDepobjDirective(const OMPDepobjDirective &S);
3530ec727ea7Spatrick   void EmitOMPScanDirective(const OMPScanDirective &S);
3531e5dd7070Spatrick   void EmitOMPOrderedDirective(const OMPOrderedDirective &S);
3532e5dd7070Spatrick   void EmitOMPAtomicDirective(const OMPAtomicDirective &S);
3533e5dd7070Spatrick   void EmitOMPTargetDirective(const OMPTargetDirective &S);
3534e5dd7070Spatrick   void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S);
3535e5dd7070Spatrick   void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S);
3536e5dd7070Spatrick   void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S);
3537e5dd7070Spatrick   void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S);
3538e5dd7070Spatrick   void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S);
3539e5dd7070Spatrick   void
3540e5dd7070Spatrick   EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S);
3541e5dd7070Spatrick   void EmitOMPTeamsDirective(const OMPTeamsDirective &S);
3542e5dd7070Spatrick   void
3543e5dd7070Spatrick   EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S);
3544e5dd7070Spatrick   void EmitOMPCancelDirective(const OMPCancelDirective &S);
3545e5dd7070Spatrick   void EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S);
3546e5dd7070Spatrick   void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S);
3547e5dd7070Spatrick   void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S);
3548e5dd7070Spatrick   void EmitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &S);
3549e5dd7070Spatrick   void
3550e5dd7070Spatrick   EmitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective &S);
3551e5dd7070Spatrick   void EmitOMPParallelMasterTaskLoopDirective(
3552e5dd7070Spatrick       const OMPParallelMasterTaskLoopDirective &S);
3553e5dd7070Spatrick   void EmitOMPParallelMasterTaskLoopSimdDirective(
3554e5dd7070Spatrick       const OMPParallelMasterTaskLoopSimdDirective &S);
3555e5dd7070Spatrick   void EmitOMPDistributeDirective(const OMPDistributeDirective &S);
3556e5dd7070Spatrick   void EmitOMPDistributeParallelForDirective(
3557e5dd7070Spatrick       const OMPDistributeParallelForDirective &S);
3558e5dd7070Spatrick   void EmitOMPDistributeParallelForSimdDirective(
3559e5dd7070Spatrick       const OMPDistributeParallelForSimdDirective &S);
3560e5dd7070Spatrick   void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S);
3561e5dd7070Spatrick   void EmitOMPTargetParallelForSimdDirective(
3562e5dd7070Spatrick       const OMPTargetParallelForSimdDirective &S);
3563e5dd7070Spatrick   void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S);
3564e5dd7070Spatrick   void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S);
3565e5dd7070Spatrick   void
3566e5dd7070Spatrick   EmitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &S);
3567e5dd7070Spatrick   void EmitOMPTeamsDistributeParallelForSimdDirective(
3568e5dd7070Spatrick       const OMPTeamsDistributeParallelForSimdDirective &S);
3569e5dd7070Spatrick   void EmitOMPTeamsDistributeParallelForDirective(
3570e5dd7070Spatrick       const OMPTeamsDistributeParallelForDirective &S);
3571e5dd7070Spatrick   void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S);
3572e5dd7070Spatrick   void EmitOMPTargetTeamsDistributeDirective(
3573e5dd7070Spatrick       const OMPTargetTeamsDistributeDirective &S);
3574e5dd7070Spatrick   void EmitOMPTargetTeamsDistributeParallelForDirective(
3575e5dd7070Spatrick       const OMPTargetTeamsDistributeParallelForDirective &S);
3576e5dd7070Spatrick   void EmitOMPTargetTeamsDistributeParallelForSimdDirective(
3577e5dd7070Spatrick       const OMPTargetTeamsDistributeParallelForSimdDirective &S);
3578e5dd7070Spatrick   void EmitOMPTargetTeamsDistributeSimdDirective(
3579e5dd7070Spatrick       const OMPTargetTeamsDistributeSimdDirective &S);
3580*12c85518Srobert   void EmitOMPGenericLoopDirective(const OMPGenericLoopDirective &S);
3581*12c85518Srobert   void EmitOMPInteropDirective(const OMPInteropDirective &S);
3582e5dd7070Spatrick 
3583e5dd7070Spatrick   /// Emit device code for the target directive.
3584e5dd7070Spatrick   static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
3585e5dd7070Spatrick                                           StringRef ParentName,
3586e5dd7070Spatrick                                           const OMPTargetDirective &S);
3587e5dd7070Spatrick   static void
3588e5dd7070Spatrick   EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName,
3589e5dd7070Spatrick                                       const OMPTargetParallelDirective &S);
3590e5dd7070Spatrick   /// Emit device code for the target parallel for directive.
3591e5dd7070Spatrick   static void EmitOMPTargetParallelForDeviceFunction(
3592e5dd7070Spatrick       CodeGenModule &CGM, StringRef ParentName,
3593e5dd7070Spatrick       const OMPTargetParallelForDirective &S);
3594e5dd7070Spatrick   /// Emit device code for the target parallel for simd directive.
3595e5dd7070Spatrick   static void EmitOMPTargetParallelForSimdDeviceFunction(
3596e5dd7070Spatrick       CodeGenModule &CGM, StringRef ParentName,
3597e5dd7070Spatrick       const OMPTargetParallelForSimdDirective &S);
3598e5dd7070Spatrick   /// Emit device code for the target teams directive.
3599e5dd7070Spatrick   static void
3600e5dd7070Spatrick   EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName,
3601e5dd7070Spatrick                                    const OMPTargetTeamsDirective &S);
3602e5dd7070Spatrick   /// Emit device code for the target teams distribute directive.
3603e5dd7070Spatrick   static void EmitOMPTargetTeamsDistributeDeviceFunction(
3604e5dd7070Spatrick       CodeGenModule &CGM, StringRef ParentName,
3605e5dd7070Spatrick       const OMPTargetTeamsDistributeDirective &S);
3606e5dd7070Spatrick   /// Emit device code for the target teams distribute simd directive.
3607e5dd7070Spatrick   static void EmitOMPTargetTeamsDistributeSimdDeviceFunction(
3608e5dd7070Spatrick       CodeGenModule &CGM, StringRef ParentName,
3609e5dd7070Spatrick       const OMPTargetTeamsDistributeSimdDirective &S);
3610e5dd7070Spatrick   /// Emit device code for the target simd directive.
3611e5dd7070Spatrick   static void EmitOMPTargetSimdDeviceFunction(CodeGenModule &CGM,
3612e5dd7070Spatrick                                               StringRef ParentName,
3613e5dd7070Spatrick                                               const OMPTargetSimdDirective &S);
3614e5dd7070Spatrick   /// Emit device code for the target teams distribute parallel for simd
3615e5dd7070Spatrick   /// directive.
3616e5dd7070Spatrick   static void EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(
3617e5dd7070Spatrick       CodeGenModule &CGM, StringRef ParentName,
3618e5dd7070Spatrick       const OMPTargetTeamsDistributeParallelForSimdDirective &S);
3619e5dd7070Spatrick 
3620e5dd7070Spatrick   static void EmitOMPTargetTeamsDistributeParallelForDeviceFunction(
3621e5dd7070Spatrick       CodeGenModule &CGM, StringRef ParentName,
3622e5dd7070Spatrick       const OMPTargetTeamsDistributeParallelForDirective &S);
3623a9ac8606Spatrick 
3624a9ac8606Spatrick   /// Emit the Stmt \p S and return its topmost canonical loop, if any.
3625a9ac8606Spatrick   /// TODO: The \p Depth paramter is not yet implemented and must be 1. In the
3626a9ac8606Spatrick   /// future it is meant to be the number of loops expected in the loop nests
3627a9ac8606Spatrick   /// (usually specified by the "collapse" clause) that are collapsed to a
3628a9ac8606Spatrick   /// single loop by this function.
3629a9ac8606Spatrick   llvm::CanonicalLoopInfo *EmitOMPCollapsedCanonicalLoopNest(const Stmt *S,
3630a9ac8606Spatrick                                                              int Depth);
3631a9ac8606Spatrick 
3632a9ac8606Spatrick   /// Emit an OMPCanonicalLoop using the OpenMPIRBuilder.
3633a9ac8606Spatrick   void EmitOMPCanonicalLoop(const OMPCanonicalLoop *S);
3634a9ac8606Spatrick 
3635e5dd7070Spatrick   /// Emit inner loop of the worksharing/simd construct.
3636e5dd7070Spatrick   ///
3637e5dd7070Spatrick   /// \param S Directive, for which the inner loop must be emitted.
3638e5dd7070Spatrick   /// \param RequiresCleanup true, if directive has some associated private
3639e5dd7070Spatrick   /// variables.
3640e5dd7070Spatrick   /// \param LoopCond Bollean condition for loop continuation.
3641e5dd7070Spatrick   /// \param IncExpr Increment expression for loop control variable.
3642e5dd7070Spatrick   /// \param BodyGen Generator for the inner body of the inner loop.
3643e5dd7070Spatrick   /// \param PostIncGen Genrator for post-increment code (required for ordered
3644e5dd7070Spatrick   /// loop directvies).
3645e5dd7070Spatrick   void EmitOMPInnerLoop(
3646ec727ea7Spatrick       const OMPExecutableDirective &S, bool RequiresCleanup,
3647ec727ea7Spatrick       const Expr *LoopCond, const Expr *IncExpr,
3648e5dd7070Spatrick       const llvm::function_ref<void(CodeGenFunction &)> BodyGen,
3649e5dd7070Spatrick       const llvm::function_ref<void(CodeGenFunction &)> PostIncGen);
3650e5dd7070Spatrick 
3651e5dd7070Spatrick   JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind);
3652e5dd7070Spatrick   /// Emit initial code for loop counters of loop-based directives.
3653e5dd7070Spatrick   void EmitOMPPrivateLoopCounters(const OMPLoopDirective &S,
3654e5dd7070Spatrick                                   OMPPrivateScope &LoopScope);
3655e5dd7070Spatrick 
3656e5dd7070Spatrick   /// Helper for the OpenMP loop directives.
3657e5dd7070Spatrick   void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit);
3658e5dd7070Spatrick 
3659e5dd7070Spatrick   /// Emit code for the worksharing loop-based directive.
3660e5dd7070Spatrick   /// \return true, if this construct has any lastprivate clause, false -
3661e5dd7070Spatrick   /// otherwise.
3662e5dd7070Spatrick   bool EmitOMPWorksharingLoop(const OMPLoopDirective &S, Expr *EUB,
3663e5dd7070Spatrick                               const CodeGenLoopBoundsTy &CodeGenLoopBounds,
3664e5dd7070Spatrick                               const CodeGenDispatchBoundsTy &CGDispatchBounds);
3665e5dd7070Spatrick 
3666e5dd7070Spatrick   /// Emit code for the distribute loop-based directive.
3667e5dd7070Spatrick   void EmitOMPDistributeLoop(const OMPLoopDirective &S,
3668e5dd7070Spatrick                              const CodeGenLoopTy &CodeGenLoop, Expr *IncExpr);
3669e5dd7070Spatrick 
3670e5dd7070Spatrick   /// Helpers for the OpenMP loop directives.
3671a9ac8606Spatrick   void EmitOMPSimdInit(const OMPLoopDirective &D);
3672e5dd7070Spatrick   void EmitOMPSimdFinal(
3673e5dd7070Spatrick       const OMPLoopDirective &D,
3674e5dd7070Spatrick       const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen);
3675e5dd7070Spatrick 
3676e5dd7070Spatrick   /// Emits the lvalue for the expression with possibly captured variable.
3677e5dd7070Spatrick   LValue EmitOMPSharedLValue(const Expr *E);
3678e5dd7070Spatrick 
3679e5dd7070Spatrick private:
3680e5dd7070Spatrick   /// Helpers for blocks.
3681e5dd7070Spatrick   llvm::Value *EmitBlockLiteral(const CGBlockInfo &Info);
3682e5dd7070Spatrick 
3683e5dd7070Spatrick   /// struct with the values to be passed to the OpenMP loop-related functions
3684e5dd7070Spatrick   struct OMPLoopArguments {
3685e5dd7070Spatrick     /// loop lower bound
3686e5dd7070Spatrick     Address LB = Address::invalid();
3687e5dd7070Spatrick     /// loop upper bound
3688e5dd7070Spatrick     Address UB = Address::invalid();
3689e5dd7070Spatrick     /// loop stride
3690e5dd7070Spatrick     Address ST = Address::invalid();
3691e5dd7070Spatrick     /// isLastIteration argument for runtime functions
3692e5dd7070Spatrick     Address IL = Address::invalid();
3693e5dd7070Spatrick     /// Chunk value generated by sema
3694e5dd7070Spatrick     llvm::Value *Chunk = nullptr;
3695e5dd7070Spatrick     /// EnsureUpperBound
3696e5dd7070Spatrick     Expr *EUB = nullptr;
3697e5dd7070Spatrick     /// IncrementExpression
3698e5dd7070Spatrick     Expr *IncExpr = nullptr;
3699e5dd7070Spatrick     /// Loop initialization
3700e5dd7070Spatrick     Expr *Init = nullptr;
3701e5dd7070Spatrick     /// Loop exit condition
3702e5dd7070Spatrick     Expr *Cond = nullptr;
3703e5dd7070Spatrick     /// Update of LB after a whole chunk has been executed
3704e5dd7070Spatrick     Expr *NextLB = nullptr;
3705e5dd7070Spatrick     /// Update of UB after a whole chunk has been executed
3706e5dd7070Spatrick     Expr *NextUB = nullptr;
3707e5dd7070Spatrick     OMPLoopArguments() = default;
3708e5dd7070Spatrick     OMPLoopArguments(Address LB, Address UB, Address ST, Address IL,
3709e5dd7070Spatrick                      llvm::Value *Chunk = nullptr, Expr *EUB = nullptr,
3710e5dd7070Spatrick                      Expr *IncExpr = nullptr, Expr *Init = nullptr,
3711e5dd7070Spatrick                      Expr *Cond = nullptr, Expr *NextLB = nullptr,
3712e5dd7070Spatrick                      Expr *NextUB = nullptr)
3713e5dd7070Spatrick         : LB(LB), UB(UB), ST(ST), IL(IL), Chunk(Chunk), EUB(EUB),
3714e5dd7070Spatrick           IncExpr(IncExpr), Init(Init), Cond(Cond), NextLB(NextLB),
3715e5dd7070Spatrick           NextUB(NextUB) {}
3716e5dd7070Spatrick   };
3717e5dd7070Spatrick   void EmitOMPOuterLoop(bool DynamicOrOrdered, bool IsMonotonic,
3718e5dd7070Spatrick                         const OMPLoopDirective &S, OMPPrivateScope &LoopScope,
3719e5dd7070Spatrick                         const OMPLoopArguments &LoopArgs,
3720e5dd7070Spatrick                         const CodeGenLoopTy &CodeGenLoop,
3721e5dd7070Spatrick                         const CodeGenOrderedTy &CodeGenOrdered);
3722e5dd7070Spatrick   void EmitOMPForOuterLoop(const OpenMPScheduleTy &ScheduleKind,
3723e5dd7070Spatrick                            bool IsMonotonic, const OMPLoopDirective &S,
3724e5dd7070Spatrick                            OMPPrivateScope &LoopScope, bool Ordered,
3725e5dd7070Spatrick                            const OMPLoopArguments &LoopArgs,
3726e5dd7070Spatrick                            const CodeGenDispatchBoundsTy &CGDispatchBounds);
3727e5dd7070Spatrick   void EmitOMPDistributeOuterLoop(OpenMPDistScheduleClauseKind ScheduleKind,
3728e5dd7070Spatrick                                   const OMPLoopDirective &S,
3729e5dd7070Spatrick                                   OMPPrivateScope &LoopScope,
3730e5dd7070Spatrick                                   const OMPLoopArguments &LoopArgs,
3731e5dd7070Spatrick                                   const CodeGenLoopTy &CodeGenLoopContent);
3732e5dd7070Spatrick   /// Emit code for sections directive.
3733e5dd7070Spatrick   void EmitSections(const OMPExecutableDirective &S);
3734e5dd7070Spatrick 
3735e5dd7070Spatrick public:
3736e5dd7070Spatrick 
3737e5dd7070Spatrick   //===--------------------------------------------------------------------===//
3738e5dd7070Spatrick   //                         LValue Expression Emission
3739e5dd7070Spatrick   //===--------------------------------------------------------------------===//
3740e5dd7070Spatrick 
3741a9ac8606Spatrick   /// Create a check that a scalar RValue is non-null.
3742a9ac8606Spatrick   llvm::Value *EmitNonNullRValueCheck(RValue RV, QualType T);
3743a9ac8606Spatrick 
3744e5dd7070Spatrick   /// GetUndefRValue - Get an appropriate 'undef' rvalue for the given type.
3745e5dd7070Spatrick   RValue GetUndefRValue(QualType Ty);
3746e5dd7070Spatrick 
3747e5dd7070Spatrick   /// EmitUnsupportedRValue - Emit a dummy r-value using the type of E
3748e5dd7070Spatrick   /// and issue an ErrorUnsupported style diagnostic (using the
3749e5dd7070Spatrick   /// provided Name).
3750e5dd7070Spatrick   RValue EmitUnsupportedRValue(const Expr *E,
3751e5dd7070Spatrick                                const char *Name);
3752e5dd7070Spatrick 
3753e5dd7070Spatrick   /// EmitUnsupportedLValue - Emit a dummy l-value using the type of E and issue
3754e5dd7070Spatrick   /// an ErrorUnsupported style diagnostic (using the provided Name).
3755e5dd7070Spatrick   LValue EmitUnsupportedLValue(const Expr *E,
3756e5dd7070Spatrick                                const char *Name);
3757e5dd7070Spatrick 
3758e5dd7070Spatrick   /// EmitLValue - Emit code to compute a designator that specifies the location
3759e5dd7070Spatrick   /// of the expression.
3760e5dd7070Spatrick   ///
3761e5dd7070Spatrick   /// This can return one of two things: a simple address or a bitfield
3762e5dd7070Spatrick   /// reference.  In either case, the LLVM Value* in the LValue structure is
3763e5dd7070Spatrick   /// guaranteed to be an LLVM pointer type.
3764e5dd7070Spatrick   ///
3765e5dd7070Spatrick   /// If this returns a bitfield reference, nothing about the pointee type of
3766e5dd7070Spatrick   /// the LLVM value is known: For example, it may not be a pointer to an
3767e5dd7070Spatrick   /// integer.
3768e5dd7070Spatrick   ///
3769e5dd7070Spatrick   /// If this returns a normal address, and if the lvalue's C type is fixed
3770e5dd7070Spatrick   /// size, this method guarantees that the returned pointer type will point to
3771e5dd7070Spatrick   /// an LLVM type of the same size of the lvalue's type.  If the lvalue has a
3772e5dd7070Spatrick   /// variable length type, this is not possible.
3773e5dd7070Spatrick   ///
3774e5dd7070Spatrick   LValue EmitLValue(const Expr *E);
3775e5dd7070Spatrick 
3776e5dd7070Spatrick   /// Same as EmitLValue but additionally we generate checking code to
3777e5dd7070Spatrick   /// guard against undefined behavior.  This is only suitable when we know
3778e5dd7070Spatrick   /// that the address will be used to access the object.
3779e5dd7070Spatrick   LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK);
3780e5dd7070Spatrick 
3781e5dd7070Spatrick   RValue convertTempToRValue(Address addr, QualType type,
3782e5dd7070Spatrick                              SourceLocation Loc);
3783e5dd7070Spatrick 
3784e5dd7070Spatrick   void EmitAtomicInit(Expr *E, LValue lvalue);
3785e5dd7070Spatrick 
3786e5dd7070Spatrick   bool LValueIsSuitableForInlineAtomic(LValue Src);
3787e5dd7070Spatrick 
3788e5dd7070Spatrick   RValue EmitAtomicLoad(LValue LV, SourceLocation SL,
3789e5dd7070Spatrick                         AggValueSlot Slot = AggValueSlot::ignored());
3790e5dd7070Spatrick 
3791e5dd7070Spatrick   RValue EmitAtomicLoad(LValue lvalue, SourceLocation loc,
3792e5dd7070Spatrick                         llvm::AtomicOrdering AO, bool IsVolatile = false,
3793e5dd7070Spatrick                         AggValueSlot slot = AggValueSlot::ignored());
3794e5dd7070Spatrick 
3795e5dd7070Spatrick   void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit);
3796e5dd7070Spatrick 
3797e5dd7070Spatrick   void EmitAtomicStore(RValue rvalue, LValue lvalue, llvm::AtomicOrdering AO,
3798e5dd7070Spatrick                        bool IsVolatile, bool isInit);
3799e5dd7070Spatrick 
3800e5dd7070Spatrick   std::pair<RValue, llvm::Value *> EmitAtomicCompareExchange(
3801e5dd7070Spatrick       LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc,
3802e5dd7070Spatrick       llvm::AtomicOrdering Success =
3803e5dd7070Spatrick           llvm::AtomicOrdering::SequentiallyConsistent,
3804e5dd7070Spatrick       llvm::AtomicOrdering Failure =
3805e5dd7070Spatrick           llvm::AtomicOrdering::SequentiallyConsistent,
3806e5dd7070Spatrick       bool IsWeak = false, AggValueSlot Slot = AggValueSlot::ignored());
3807e5dd7070Spatrick 
3808e5dd7070Spatrick   void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO,
3809e5dd7070Spatrick                         const llvm::function_ref<RValue(RValue)> &UpdateOp,
3810e5dd7070Spatrick                         bool IsVolatile);
3811e5dd7070Spatrick 
3812e5dd7070Spatrick   /// EmitToMemory - Change a scalar value from its value
3813e5dd7070Spatrick   /// representation to its in-memory representation.
3814e5dd7070Spatrick   llvm::Value *EmitToMemory(llvm::Value *Value, QualType Ty);
3815e5dd7070Spatrick 
3816e5dd7070Spatrick   /// EmitFromMemory - Change a scalar value from its memory
3817e5dd7070Spatrick   /// representation to its value representation.
3818e5dd7070Spatrick   llvm::Value *EmitFromMemory(llvm::Value *Value, QualType Ty);
3819e5dd7070Spatrick 
3820e5dd7070Spatrick   /// Check if the scalar \p Value is within the valid range for the given
3821e5dd7070Spatrick   /// type \p Ty.
3822e5dd7070Spatrick   ///
3823e5dd7070Spatrick   /// Returns true if a check is needed (even if the range is unknown).
3824e5dd7070Spatrick   bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
3825e5dd7070Spatrick                             SourceLocation Loc);
3826e5dd7070Spatrick 
3827e5dd7070Spatrick   /// EmitLoadOfScalar - Load a scalar value from an address, taking
3828e5dd7070Spatrick   /// care to appropriately convert from the memory representation to
3829e5dd7070Spatrick   /// the LLVM value representation.
3830e5dd7070Spatrick   llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty,
3831e5dd7070Spatrick                                 SourceLocation Loc,
3832e5dd7070Spatrick                                 AlignmentSource Source = AlignmentSource::Type,
3833e5dd7070Spatrick                                 bool isNontemporal = false) {
3834e5dd7070Spatrick     return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, LValueBaseInfo(Source),
3835e5dd7070Spatrick                             CGM.getTBAAAccessInfo(Ty), isNontemporal);
3836e5dd7070Spatrick   }
3837e5dd7070Spatrick 
3838e5dd7070Spatrick   llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty,
3839e5dd7070Spatrick                                 SourceLocation Loc, LValueBaseInfo BaseInfo,
3840e5dd7070Spatrick                                 TBAAAccessInfo TBAAInfo,
3841e5dd7070Spatrick                                 bool isNontemporal = false);
3842e5dd7070Spatrick 
3843e5dd7070Spatrick   /// EmitLoadOfScalar - Load a scalar value from an address, taking
3844e5dd7070Spatrick   /// care to appropriately convert from the memory representation to
3845e5dd7070Spatrick   /// the LLVM value representation.  The l-value must be a simple
3846e5dd7070Spatrick   /// l-value.
3847e5dd7070Spatrick   llvm::Value *EmitLoadOfScalar(LValue lvalue, SourceLocation Loc);
3848e5dd7070Spatrick 
3849e5dd7070Spatrick   /// EmitStoreOfScalar - Store a scalar value to an address, taking
3850e5dd7070Spatrick   /// care to appropriately convert from the memory representation to
3851e5dd7070Spatrick   /// the LLVM value representation.
3852e5dd7070Spatrick   void EmitStoreOfScalar(llvm::Value *Value, Address Addr,
3853e5dd7070Spatrick                          bool Volatile, QualType Ty,
3854e5dd7070Spatrick                          AlignmentSource Source = AlignmentSource::Type,
3855e5dd7070Spatrick                          bool isInit = false, bool isNontemporal = false) {
3856e5dd7070Spatrick     EmitStoreOfScalar(Value, Addr, Volatile, Ty, LValueBaseInfo(Source),
3857e5dd7070Spatrick                       CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal);
3858e5dd7070Spatrick   }
3859e5dd7070Spatrick 
3860e5dd7070Spatrick   void EmitStoreOfScalar(llvm::Value *Value, Address Addr,
3861e5dd7070Spatrick                          bool Volatile, QualType Ty,
3862e5dd7070Spatrick                          LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo,
3863e5dd7070Spatrick                          bool isInit = false, bool isNontemporal = false);
3864e5dd7070Spatrick 
3865e5dd7070Spatrick   /// EmitStoreOfScalar - Store a scalar value to an address, taking
3866e5dd7070Spatrick   /// care to appropriately convert from the memory representation to
3867e5dd7070Spatrick   /// the LLVM value representation.  The l-value must be a simple
3868e5dd7070Spatrick   /// l-value.  The isInit flag indicates whether this is an initialization.
3869e5dd7070Spatrick   /// If so, atomic qualifiers are ignored and the store is always non-atomic.
3870e5dd7070Spatrick   void EmitStoreOfScalar(llvm::Value *value, LValue lvalue, bool isInit=false);
3871e5dd7070Spatrick 
3872e5dd7070Spatrick   /// EmitLoadOfLValue - Given an expression that represents a value lvalue,
3873e5dd7070Spatrick   /// this method emits the address of the lvalue, then loads the result as an
3874e5dd7070Spatrick   /// rvalue, returning the rvalue.
3875e5dd7070Spatrick   RValue EmitLoadOfLValue(LValue V, SourceLocation Loc);
3876e5dd7070Spatrick   RValue EmitLoadOfExtVectorElementLValue(LValue V);
3877e5dd7070Spatrick   RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc);
3878e5dd7070Spatrick   RValue EmitLoadOfGlobalRegLValue(LValue LV);
3879e5dd7070Spatrick 
3880e5dd7070Spatrick   /// EmitStoreThroughLValue - Store the specified rvalue into the specified
3881e5dd7070Spatrick   /// lvalue, where both are guaranteed to the have the same type, and that type
3882e5dd7070Spatrick   /// is 'Ty'.
3883e5dd7070Spatrick   void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit = false);
3884e5dd7070Spatrick   void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst);
3885e5dd7070Spatrick   void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst);
3886e5dd7070Spatrick 
3887e5dd7070Spatrick   /// EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints
3888e5dd7070Spatrick   /// as EmitStoreThroughLValue.
3889e5dd7070Spatrick   ///
3890e5dd7070Spatrick   /// \param Result [out] - If non-null, this will be set to a Value* for the
3891e5dd7070Spatrick   /// bit-field contents after the store, appropriate for use as the result of
3892e5dd7070Spatrick   /// an assignment to the bit-field.
3893e5dd7070Spatrick   void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
3894e5dd7070Spatrick                                       llvm::Value **Result=nullptr);
3895e5dd7070Spatrick 
3896e5dd7070Spatrick   /// Emit an l-value for an assignment (simple or compound) of complex type.
3897e5dd7070Spatrick   LValue EmitComplexAssignmentLValue(const BinaryOperator *E);
3898e5dd7070Spatrick   LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E);
3899e5dd7070Spatrick   LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E,
3900e5dd7070Spatrick                                              llvm::Value *&Result);
3901e5dd7070Spatrick 
3902e5dd7070Spatrick   // Note: only available for agg return types
3903e5dd7070Spatrick   LValue EmitBinaryOperatorLValue(const BinaryOperator *E);
3904e5dd7070Spatrick   LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E);
3905e5dd7070Spatrick   // Note: only available for agg return types
3906e5dd7070Spatrick   LValue EmitCallExprLValue(const CallExpr *E);
3907e5dd7070Spatrick   // Note: only available for agg return types
3908e5dd7070Spatrick   LValue EmitVAArgExprLValue(const VAArgExpr *E);
3909e5dd7070Spatrick   LValue EmitDeclRefLValue(const DeclRefExpr *E);
3910e5dd7070Spatrick   LValue EmitStringLiteralLValue(const StringLiteral *E);
3911e5dd7070Spatrick   LValue EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E);
3912e5dd7070Spatrick   LValue EmitPredefinedLValue(const PredefinedExpr *E);
3913e5dd7070Spatrick   LValue EmitUnaryOpLValue(const UnaryOperator *E);
3914e5dd7070Spatrick   LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
3915e5dd7070Spatrick                                 bool Accessed = false);
3916ec727ea7Spatrick   LValue EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E);
3917e5dd7070Spatrick   LValue EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
3918e5dd7070Spatrick                                  bool IsLowerBound = true);
3919e5dd7070Spatrick   LValue EmitExtVectorElementExpr(const ExtVectorElementExpr *E);
3920e5dd7070Spatrick   LValue EmitMemberExpr(const MemberExpr *E);
3921e5dd7070Spatrick   LValue EmitObjCIsaExpr(const ObjCIsaExpr *E);
3922e5dd7070Spatrick   LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E);
3923e5dd7070Spatrick   LValue EmitInitListLValue(const InitListExpr *E);
3924*12c85518Srobert   void EmitIgnoredConditionalOperator(const AbstractConditionalOperator *E);
3925e5dd7070Spatrick   LValue EmitConditionalOperatorLValue(const AbstractConditionalOperator *E);
3926e5dd7070Spatrick   LValue EmitCastLValue(const CastExpr *E);
3927e5dd7070Spatrick   LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
3928e5dd7070Spatrick   LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e);
3929e5dd7070Spatrick 
3930e5dd7070Spatrick   Address EmitExtVectorElementLValue(LValue V);
3931e5dd7070Spatrick 
3932e5dd7070Spatrick   RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc);
3933e5dd7070Spatrick 
3934e5dd7070Spatrick   Address EmitArrayToPointerDecay(const Expr *Array,
3935e5dd7070Spatrick                                   LValueBaseInfo *BaseInfo = nullptr,
3936e5dd7070Spatrick                                   TBAAAccessInfo *TBAAInfo = nullptr);
3937e5dd7070Spatrick 
3938e5dd7070Spatrick   class ConstantEmission {
3939e5dd7070Spatrick     llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference;
3940e5dd7070Spatrick     ConstantEmission(llvm::Constant *C, bool isReference)
3941e5dd7070Spatrick       : ValueAndIsReference(C, isReference) {}
3942e5dd7070Spatrick   public:
3943e5dd7070Spatrick     ConstantEmission() {}
3944e5dd7070Spatrick     static ConstantEmission forReference(llvm::Constant *C) {
3945e5dd7070Spatrick       return ConstantEmission(C, true);
3946e5dd7070Spatrick     }
3947e5dd7070Spatrick     static ConstantEmission forValue(llvm::Constant *C) {
3948e5dd7070Spatrick       return ConstantEmission(C, false);
3949e5dd7070Spatrick     }
3950e5dd7070Spatrick 
3951e5dd7070Spatrick     explicit operator bool() const {
3952e5dd7070Spatrick       return ValueAndIsReference.getOpaqueValue() != nullptr;
3953e5dd7070Spatrick     }
3954e5dd7070Spatrick 
3955e5dd7070Spatrick     bool isReference() const { return ValueAndIsReference.getInt(); }
3956e5dd7070Spatrick     LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const {
3957e5dd7070Spatrick       assert(isReference());
3958e5dd7070Spatrick       return CGF.MakeNaturalAlignAddrLValue(ValueAndIsReference.getPointer(),
3959e5dd7070Spatrick                                             refExpr->getType());
3960e5dd7070Spatrick     }
3961e5dd7070Spatrick 
3962e5dd7070Spatrick     llvm::Constant *getValue() const {
3963e5dd7070Spatrick       assert(!isReference());
3964e5dd7070Spatrick       return ValueAndIsReference.getPointer();
3965e5dd7070Spatrick     }
3966e5dd7070Spatrick   };
3967e5dd7070Spatrick 
3968e5dd7070Spatrick   ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr);
3969e5dd7070Spatrick   ConstantEmission tryEmitAsConstant(const MemberExpr *ME);
3970e5dd7070Spatrick   llvm::Value *emitScalarConstant(const ConstantEmission &Constant, Expr *E);
3971e5dd7070Spatrick 
3972e5dd7070Spatrick   RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e,
3973e5dd7070Spatrick                                 AggValueSlot slot = AggValueSlot::ignored());
3974e5dd7070Spatrick   LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e);
3975e5dd7070Spatrick 
3976e5dd7070Spatrick   llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
3977e5dd7070Spatrick                               const ObjCIvarDecl *Ivar);
3978*12c85518Srobert   llvm::Value *EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface,
3979*12c85518Srobert                                            const ObjCIvarDecl *Ivar);
3980e5dd7070Spatrick   LValue EmitLValueForField(LValue Base, const FieldDecl* Field);
3981e5dd7070Spatrick   LValue EmitLValueForLambdaField(const FieldDecl *Field);
3982e5dd7070Spatrick 
3983e5dd7070Spatrick   /// EmitLValueForFieldInitialization - Like EmitLValueForField, except that
3984e5dd7070Spatrick   /// if the Field is a reference, this will return the address of the reference
3985e5dd7070Spatrick   /// and not the address of the value stored in the reference.
3986e5dd7070Spatrick   LValue EmitLValueForFieldInitialization(LValue Base,
3987e5dd7070Spatrick                                           const FieldDecl* Field);
3988e5dd7070Spatrick 
3989e5dd7070Spatrick   LValue EmitLValueForIvar(QualType ObjectTy,
3990e5dd7070Spatrick                            llvm::Value* Base, const ObjCIvarDecl *Ivar,
3991e5dd7070Spatrick                            unsigned CVRQualifiers);
3992e5dd7070Spatrick 
3993e5dd7070Spatrick   LValue EmitCXXConstructLValue(const CXXConstructExpr *E);
3994e5dd7070Spatrick   LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E);
3995e5dd7070Spatrick   LValue EmitCXXTypeidLValue(const CXXTypeidExpr *E);
3996e5dd7070Spatrick   LValue EmitCXXUuidofLValue(const CXXUuidofExpr *E);
3997e5dd7070Spatrick 
3998e5dd7070Spatrick   LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E);
3999e5dd7070Spatrick   LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E);
4000e5dd7070Spatrick   LValue EmitStmtExprLValue(const StmtExpr *E);
4001e5dd7070Spatrick   LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E);
4002e5dd7070Spatrick   LValue EmitObjCSelectorLValue(const ObjCSelectorExpr *E);
4003e5dd7070Spatrick   void   EmitDeclRefExprDbgValue(const DeclRefExpr *E, const APValue &Init);
4004e5dd7070Spatrick 
4005e5dd7070Spatrick   //===--------------------------------------------------------------------===//
4006e5dd7070Spatrick   //                         Scalar Expression Emission
4007e5dd7070Spatrick   //===--------------------------------------------------------------------===//
4008e5dd7070Spatrick 
4009e5dd7070Spatrick   /// EmitCall - Generate a call of the given function, expecting the given
4010e5dd7070Spatrick   /// result type, and using the given argument list which specifies both the
4011e5dd7070Spatrick   /// LLVM arguments and the types they were derived from.
4012e5dd7070Spatrick   RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee,
4013e5dd7070Spatrick                   ReturnValueSlot ReturnValue, const CallArgList &Args,
4014a9ac8606Spatrick                   llvm::CallBase **callOrInvoke, bool IsMustTail,
4015a9ac8606Spatrick                   SourceLocation Loc);
4016e5dd7070Spatrick   RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee,
4017e5dd7070Spatrick                   ReturnValueSlot ReturnValue, const CallArgList &Args,
4018a9ac8606Spatrick                   llvm::CallBase **callOrInvoke = nullptr,
4019a9ac8606Spatrick                   bool IsMustTail = false) {
4020e5dd7070Spatrick     return EmitCall(CallInfo, Callee, ReturnValue, Args, callOrInvoke,
4021a9ac8606Spatrick                     IsMustTail, SourceLocation());
4022e5dd7070Spatrick   }
4023e5dd7070Spatrick   RValue EmitCall(QualType FnType, const CGCallee &Callee, const CallExpr *E,
4024e5dd7070Spatrick                   ReturnValueSlot ReturnValue, llvm::Value *Chain = nullptr);
4025e5dd7070Spatrick   RValue EmitCallExpr(const CallExpr *E,
4026e5dd7070Spatrick                       ReturnValueSlot ReturnValue = ReturnValueSlot());
4027e5dd7070Spatrick   RValue EmitSimpleCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue);
4028e5dd7070Spatrick   CGCallee EmitCallee(const Expr *E);
4029e5dd7070Spatrick 
4030e5dd7070Spatrick   void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl);
4031e5dd7070Spatrick   void checkTargetFeatures(SourceLocation Loc, const FunctionDecl *TargetDecl);
4032e5dd7070Spatrick 
4033e5dd7070Spatrick   llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee,
4034e5dd7070Spatrick                                   const Twine &name = "");
4035e5dd7070Spatrick   llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee,
4036e5dd7070Spatrick                                   ArrayRef<llvm::Value *> args,
4037e5dd7070Spatrick                                   const Twine &name = "");
4038e5dd7070Spatrick   llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
4039e5dd7070Spatrick                                           const Twine &name = "");
4040e5dd7070Spatrick   llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
4041e5dd7070Spatrick                                           ArrayRef<llvm::Value *> args,
4042e5dd7070Spatrick                                           const Twine &name = "");
4043e5dd7070Spatrick 
4044e5dd7070Spatrick   SmallVector<llvm::OperandBundleDef, 1>
4045e5dd7070Spatrick   getBundlesForFunclet(llvm::Value *Callee);
4046e5dd7070Spatrick 
4047e5dd7070Spatrick   llvm::CallBase *EmitCallOrInvoke(llvm::FunctionCallee Callee,
4048e5dd7070Spatrick                                    ArrayRef<llvm::Value *> Args,
4049e5dd7070Spatrick                                    const Twine &Name = "");
4050e5dd7070Spatrick   llvm::CallBase *EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
4051e5dd7070Spatrick                                           ArrayRef<llvm::Value *> args,
4052e5dd7070Spatrick                                           const Twine &name = "");
4053e5dd7070Spatrick   llvm::CallBase *EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
4054e5dd7070Spatrick                                           const Twine &name = "");
4055e5dd7070Spatrick   void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee,
4056e5dd7070Spatrick                                        ArrayRef<llvm::Value *> args);
4057e5dd7070Spatrick 
4058e5dd7070Spatrick   CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
4059e5dd7070Spatrick                                      NestedNameSpecifier *Qual,
4060e5dd7070Spatrick                                      llvm::Type *Ty);
4061e5dd7070Spatrick 
4062e5dd7070Spatrick   CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD,
4063e5dd7070Spatrick                                                CXXDtorType Type,
4064e5dd7070Spatrick                                                const CXXRecordDecl *RD);
4065e5dd7070Spatrick 
4066e5dd7070Spatrick   // Return the copy constructor name with the prefix "__copy_constructor_"
4067e5dd7070Spatrick   // removed.
4068e5dd7070Spatrick   static std::string getNonTrivialCopyConstructorStr(QualType QT,
4069e5dd7070Spatrick                                                      CharUnits Alignment,
4070e5dd7070Spatrick                                                      bool IsVolatile,
4071e5dd7070Spatrick                                                      ASTContext &Ctx);
4072e5dd7070Spatrick 
4073e5dd7070Spatrick   // Return the destructor name with the prefix "__destructor_" removed.
4074e5dd7070Spatrick   static std::string getNonTrivialDestructorStr(QualType QT,
4075e5dd7070Spatrick                                                 CharUnits Alignment,
4076e5dd7070Spatrick                                                 bool IsVolatile,
4077e5dd7070Spatrick                                                 ASTContext &Ctx);
4078e5dd7070Spatrick 
4079e5dd7070Spatrick   // These functions emit calls to the special functions of non-trivial C
4080e5dd7070Spatrick   // structs.
4081e5dd7070Spatrick   void defaultInitNonTrivialCStructVar(LValue Dst);
4082e5dd7070Spatrick   void callCStructDefaultConstructor(LValue Dst);
4083e5dd7070Spatrick   void callCStructDestructor(LValue Dst);
4084e5dd7070Spatrick   void callCStructCopyConstructor(LValue Dst, LValue Src);
4085e5dd7070Spatrick   void callCStructMoveConstructor(LValue Dst, LValue Src);
4086e5dd7070Spatrick   void callCStructCopyAssignmentOperator(LValue Dst, LValue Src);
4087e5dd7070Spatrick   void callCStructMoveAssignmentOperator(LValue Dst, LValue Src);
4088e5dd7070Spatrick 
4089e5dd7070Spatrick   RValue
4090e5dd7070Spatrick   EmitCXXMemberOrOperatorCall(const CXXMethodDecl *Method,
4091e5dd7070Spatrick                               const CGCallee &Callee,
4092e5dd7070Spatrick                               ReturnValueSlot ReturnValue, llvm::Value *This,
4093e5dd7070Spatrick                               llvm::Value *ImplicitParam,
4094e5dd7070Spatrick                               QualType ImplicitParamTy, const CallExpr *E,
4095e5dd7070Spatrick                               CallArgList *RtlArgs);
4096e5dd7070Spatrick   RValue EmitCXXDestructorCall(GlobalDecl Dtor, const CGCallee &Callee,
4097e5dd7070Spatrick                                llvm::Value *This, QualType ThisTy,
4098e5dd7070Spatrick                                llvm::Value *ImplicitParam,
4099e5dd7070Spatrick                                QualType ImplicitParamTy, const CallExpr *E);
4100e5dd7070Spatrick   RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E,
4101e5dd7070Spatrick                                ReturnValueSlot ReturnValue);
4102e5dd7070Spatrick   RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE,
4103e5dd7070Spatrick                                                const CXXMethodDecl *MD,
4104e5dd7070Spatrick                                                ReturnValueSlot ReturnValue,
4105e5dd7070Spatrick                                                bool HasQualifier,
4106e5dd7070Spatrick                                                NestedNameSpecifier *Qualifier,
4107e5dd7070Spatrick                                                bool IsArrow, const Expr *Base);
4108e5dd7070Spatrick   // Compute the object pointer.
4109e5dd7070Spatrick   Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base,
4110e5dd7070Spatrick                                           llvm::Value *memberPtr,
4111e5dd7070Spatrick                                           const MemberPointerType *memberPtrType,
4112e5dd7070Spatrick                                           LValueBaseInfo *BaseInfo = nullptr,
4113e5dd7070Spatrick                                           TBAAAccessInfo *TBAAInfo = nullptr);
4114e5dd7070Spatrick   RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
4115e5dd7070Spatrick                                       ReturnValueSlot ReturnValue);
4116e5dd7070Spatrick 
4117e5dd7070Spatrick   RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
4118e5dd7070Spatrick                                        const CXXMethodDecl *MD,
4119e5dd7070Spatrick                                        ReturnValueSlot ReturnValue);
4120e5dd7070Spatrick   RValue EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
4121e5dd7070Spatrick 
4122e5dd7070Spatrick   RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E,
4123e5dd7070Spatrick                                 ReturnValueSlot ReturnValue);
4124e5dd7070Spatrick 
4125*12c85518Srobert   RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E);
4126*12c85518Srobert   RValue EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E);
4127*12c85518Srobert   RValue EmitOpenMPDevicePrintfCallExpr(const CallExpr *E);
4128e5dd7070Spatrick 
4129e5dd7070Spatrick   RValue EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
4130e5dd7070Spatrick                          const CallExpr *E, ReturnValueSlot ReturnValue);
4131e5dd7070Spatrick 
4132e5dd7070Spatrick   RValue emitRotate(const CallExpr *E, bool IsRotateRight);
4133e5dd7070Spatrick 
4134e5dd7070Spatrick   /// Emit IR for __builtin_os_log_format.
4135e5dd7070Spatrick   RValue emitBuiltinOSLogFormat(const CallExpr &E);
4136e5dd7070Spatrick 
4137e5dd7070Spatrick   /// Emit IR for __builtin_is_aligned.
4138e5dd7070Spatrick   RValue EmitBuiltinIsAligned(const CallExpr *E);
4139e5dd7070Spatrick   /// Emit IR for __builtin_align_up/__builtin_align_down.
4140e5dd7070Spatrick   RValue EmitBuiltinAlignTo(const CallExpr *E, bool AlignUp);
4141e5dd7070Spatrick 
4142e5dd7070Spatrick   llvm::Function *generateBuiltinOSLogHelperFunction(
4143e5dd7070Spatrick       const analyze_os_log::OSLogBufferLayout &Layout,
4144e5dd7070Spatrick       CharUnits BufferAlignment);
4145e5dd7070Spatrick 
4146e5dd7070Spatrick   RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue);
4147e5dd7070Spatrick 
4148e5dd7070Spatrick   /// EmitTargetBuiltinExpr - Emit the given builtin call. Returns 0 if the call
4149e5dd7070Spatrick   /// is unhandled by the current target.
4150e5dd7070Spatrick   llvm::Value *EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4151e5dd7070Spatrick                                      ReturnValueSlot ReturnValue);
4152e5dd7070Spatrick 
4153e5dd7070Spatrick   llvm::Value *EmitAArch64CompareBuiltinExpr(llvm::Value *Op, llvm::Type *Ty,
4154e5dd7070Spatrick                                              const llvm::CmpInst::Predicate Fp,
4155e5dd7070Spatrick                                              const llvm::CmpInst::Predicate Ip,
4156e5dd7070Spatrick                                              const llvm::Twine &Name = "");
4157e5dd7070Spatrick   llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4158e5dd7070Spatrick                                   ReturnValueSlot ReturnValue,
4159e5dd7070Spatrick                                   llvm::Triple::ArchType Arch);
4160e5dd7070Spatrick   llvm::Value *EmitARMMVEBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4161e5dd7070Spatrick                                      ReturnValueSlot ReturnValue,
4162e5dd7070Spatrick                                      llvm::Triple::ArchType Arch);
4163ec727ea7Spatrick   llvm::Value *EmitARMCDEBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4164ec727ea7Spatrick                                      ReturnValueSlot ReturnValue,
4165ec727ea7Spatrick                                      llvm::Triple::ArchType Arch);
4166ec727ea7Spatrick   llvm::Value *EmitCMSEClearRecord(llvm::Value *V, llvm::IntegerType *ITy,
4167ec727ea7Spatrick                                    QualType RTy);
4168ec727ea7Spatrick   llvm::Value *EmitCMSEClearRecord(llvm::Value *V, llvm::ArrayType *ATy,
4169ec727ea7Spatrick                                    QualType RTy);
4170e5dd7070Spatrick 
4171e5dd7070Spatrick   llvm::Value *EmitCommonNeonBuiltinExpr(unsigned BuiltinID,
4172e5dd7070Spatrick                                          unsigned LLVMIntrinsic,
4173e5dd7070Spatrick                                          unsigned AltLLVMIntrinsic,
4174e5dd7070Spatrick                                          const char *NameHint,
4175e5dd7070Spatrick                                          unsigned Modifier,
4176e5dd7070Spatrick                                          const CallExpr *E,
4177e5dd7070Spatrick                                          SmallVectorImpl<llvm::Value *> &Ops,
4178e5dd7070Spatrick                                          Address PtrOp0, Address PtrOp1,
4179e5dd7070Spatrick                                          llvm::Triple::ArchType Arch);
4180e5dd7070Spatrick 
4181e5dd7070Spatrick   llvm::Function *LookupNeonLLVMIntrinsic(unsigned IntrinsicID,
4182e5dd7070Spatrick                                           unsigned Modifier, llvm::Type *ArgTy,
4183e5dd7070Spatrick                                           const CallExpr *E);
4184e5dd7070Spatrick   llvm::Value *EmitNeonCall(llvm::Function *F,
4185e5dd7070Spatrick                             SmallVectorImpl<llvm::Value*> &O,
4186e5dd7070Spatrick                             const char *name,
4187e5dd7070Spatrick                             unsigned shift = 0, bool rightshift = false);
4188ec727ea7Spatrick   llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx,
4189ec727ea7Spatrick                              const llvm::ElementCount &Count);
4190e5dd7070Spatrick   llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx);
4191e5dd7070Spatrick   llvm::Value *EmitNeonShiftVector(llvm::Value *V, llvm::Type *Ty,
4192e5dd7070Spatrick                                    bool negateForRightShift);
4193e5dd7070Spatrick   llvm::Value *EmitNeonRShiftImm(llvm::Value *Vec, llvm::Value *Amt,
4194e5dd7070Spatrick                                  llvm::Type *Ty, bool usgn, const char *name);
4195e5dd7070Spatrick   llvm::Value *vectorWrapScalar16(llvm::Value *Op);
4196ec727ea7Spatrick   /// SVEBuiltinMemEltTy - Returns the memory element type for this memory
4197ec727ea7Spatrick   /// access builtin.  Only required if it can't be inferred from the base
4198ec727ea7Spatrick   /// pointer operand.
4199*12c85518Srobert   llvm::Type *SVEBuiltinMemEltTy(const SVETypeFlags &TypeFlags);
4200ec727ea7Spatrick 
4201*12c85518Srobert   SmallVector<llvm::Type *, 2>
4202*12c85518Srobert   getSVEOverloadTypes(const SVETypeFlags &TypeFlags, llvm::Type *ReturnType,
4203*12c85518Srobert                       ArrayRef<llvm::Value *> Ops);
4204*12c85518Srobert   llvm::Type *getEltType(const SVETypeFlags &TypeFlags);
4205*12c85518Srobert   llvm::ScalableVectorType *getSVEType(const SVETypeFlags &TypeFlags);
4206*12c85518Srobert   llvm::ScalableVectorType *getSVEPredType(const SVETypeFlags &TypeFlags);
4207*12c85518Srobert   llvm::Value *EmitSVETupleSetOrGet(const SVETypeFlags &TypeFlags,
4208ec727ea7Spatrick                                     llvm::Type *ReturnType,
4209ec727ea7Spatrick                                     ArrayRef<llvm::Value *> Ops);
4210*12c85518Srobert   llvm::Value *EmitSVETupleCreate(const SVETypeFlags &TypeFlags,
4211*12c85518Srobert                                   llvm::Type *ReturnType,
4212*12c85518Srobert                                   ArrayRef<llvm::Value *> Ops);
4213*12c85518Srobert   llvm::Value *EmitSVEAllTruePred(const SVETypeFlags &TypeFlags);
4214ec727ea7Spatrick   llvm::Value *EmitSVEDupX(llvm::Value *Scalar);
4215ec727ea7Spatrick   llvm::Value *EmitSVEDupX(llvm::Value *Scalar, llvm::Type *Ty);
4216ec727ea7Spatrick   llvm::Value *EmitSVEReinterpret(llvm::Value *Val, llvm::Type *Ty);
4217*12c85518Srobert   llvm::Value *EmitSVEPMull(const SVETypeFlags &TypeFlags,
4218ec727ea7Spatrick                             llvm::SmallVectorImpl<llvm::Value *> &Ops,
4219ec727ea7Spatrick                             unsigned BuiltinID);
4220*12c85518Srobert   llvm::Value *EmitSVEMovl(const SVETypeFlags &TypeFlags,
4221ec727ea7Spatrick                            llvm::ArrayRef<llvm::Value *> Ops,
4222ec727ea7Spatrick                            unsigned BuiltinID);
4223ec727ea7Spatrick   llvm::Value *EmitSVEPredicateCast(llvm::Value *Pred,
4224ec727ea7Spatrick                                     llvm::ScalableVectorType *VTy);
4225*12c85518Srobert   llvm::Value *EmitSVEGatherLoad(const SVETypeFlags &TypeFlags,
4226ec727ea7Spatrick                                  llvm::SmallVectorImpl<llvm::Value *> &Ops,
4227ec727ea7Spatrick                                  unsigned IntID);
4228*12c85518Srobert   llvm::Value *EmitSVEScatterStore(const SVETypeFlags &TypeFlags,
4229ec727ea7Spatrick                                    llvm::SmallVectorImpl<llvm::Value *> &Ops,
4230ec727ea7Spatrick                                    unsigned IntID);
4231ec727ea7Spatrick   llvm::Value *EmitSVEMaskedLoad(const CallExpr *, llvm::Type *ReturnTy,
4232ec727ea7Spatrick                                  SmallVectorImpl<llvm::Value *> &Ops,
4233ec727ea7Spatrick                                  unsigned BuiltinID, bool IsZExtReturn);
4234ec727ea7Spatrick   llvm::Value *EmitSVEMaskedStore(const CallExpr *,
4235ec727ea7Spatrick                                   SmallVectorImpl<llvm::Value *> &Ops,
4236ec727ea7Spatrick                                   unsigned BuiltinID);
4237*12c85518Srobert   llvm::Value *EmitSVEPrefetchLoad(const SVETypeFlags &TypeFlags,
4238ec727ea7Spatrick                                    SmallVectorImpl<llvm::Value *> &Ops,
4239ec727ea7Spatrick                                    unsigned BuiltinID);
4240*12c85518Srobert   llvm::Value *EmitSVEGatherPrefetch(const SVETypeFlags &TypeFlags,
4241ec727ea7Spatrick                                      SmallVectorImpl<llvm::Value *> &Ops,
4242ec727ea7Spatrick                                      unsigned IntID);
4243*12c85518Srobert   llvm::Value *EmitSVEStructLoad(const SVETypeFlags &TypeFlags,
4244*12c85518Srobert                                  SmallVectorImpl<llvm::Value *> &Ops,
4245*12c85518Srobert                                  unsigned IntID);
4246*12c85518Srobert   llvm::Value *EmitSVEStructStore(const SVETypeFlags &TypeFlags,
4247ec727ea7Spatrick                                   SmallVectorImpl<llvm::Value *> &Ops,
4248ec727ea7Spatrick                                   unsigned IntID);
4249ec727ea7Spatrick   llvm::Value *EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4250ec727ea7Spatrick 
4251e5dd7070Spatrick   llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4252e5dd7070Spatrick                                       llvm::Triple::ArchType Arch);
4253e5dd7070Spatrick   llvm::Value *EmitBPFBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4254e5dd7070Spatrick 
4255e5dd7070Spatrick   llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops);
4256e5dd7070Spatrick   llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4257e5dd7070Spatrick   llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4258e5dd7070Spatrick   llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4259e5dd7070Spatrick   llvm::Value *EmitSystemZBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4260e5dd7070Spatrick   llvm::Value *EmitNVPTXBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4261e5dd7070Spatrick   llvm::Value *EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
4262e5dd7070Spatrick                                           const CallExpr *E);
4263e5dd7070Spatrick   llvm::Value *EmitHexagonBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4264a9ac8606Spatrick   llvm::Value *EmitRISCVBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4265a9ac8606Spatrick                                     ReturnValueSlot ReturnValue);
4266*12c85518Srobert   llvm::Value *EmitLoongArchBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4267*12c85518Srobert   void ProcessOrderScopeAMDGCN(llvm::Value *Order, llvm::Value *Scope,
4268ec727ea7Spatrick                                llvm::AtomicOrdering &AO,
4269ec727ea7Spatrick                                llvm::SyncScope::ID &SSID);
4270e5dd7070Spatrick 
4271e5dd7070Spatrick   enum class MSVCIntrin;
4272e5dd7070Spatrick   llvm::Value *EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E);
4273e5dd7070Spatrick 
4274a9ac8606Spatrick   llvm::Value *EmitBuiltinAvailable(const VersionTuple &Version);
4275e5dd7070Spatrick 
4276e5dd7070Spatrick   llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
4277e5dd7070Spatrick   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
4278e5dd7070Spatrick   llvm::Value *EmitObjCBoxedExpr(const ObjCBoxedExpr *E);
4279e5dd7070Spatrick   llvm::Value *EmitObjCArrayLiteral(const ObjCArrayLiteral *E);
4280e5dd7070Spatrick   llvm::Value *EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E);
4281e5dd7070Spatrick   llvm::Value *EmitObjCCollectionLiteral(const Expr *E,
4282e5dd7070Spatrick                                 const ObjCMethodDecl *MethodWithObjects);
4283e5dd7070Spatrick   llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
4284e5dd7070Spatrick   RValue EmitObjCMessageExpr(const ObjCMessageExpr *E,
4285e5dd7070Spatrick                              ReturnValueSlot Return = ReturnValueSlot());
4286e5dd7070Spatrick 
4287e5dd7070Spatrick   /// Retrieves the default cleanup kind for an ARC cleanup.
4288e5dd7070Spatrick   /// Except under -fobjc-arc-eh, ARC cleanups are normal-only.
4289e5dd7070Spatrick   CleanupKind getARCCleanupKind() {
4290e5dd7070Spatrick     return CGM.getCodeGenOpts().ObjCAutoRefCountExceptions
4291e5dd7070Spatrick              ? NormalAndEHCleanup : NormalCleanup;
4292e5dd7070Spatrick   }
4293e5dd7070Spatrick 
4294e5dd7070Spatrick   // ARC primitives.
4295e5dd7070Spatrick   void EmitARCInitWeak(Address addr, llvm::Value *value);
4296e5dd7070Spatrick   void EmitARCDestroyWeak(Address addr);
4297e5dd7070Spatrick   llvm::Value *EmitARCLoadWeak(Address addr);
4298e5dd7070Spatrick   llvm::Value *EmitARCLoadWeakRetained(Address addr);
4299e5dd7070Spatrick   llvm::Value *EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored);
4300e5dd7070Spatrick   void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr);
4301e5dd7070Spatrick   void emitARCMoveAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr);
4302e5dd7070Spatrick   void EmitARCCopyWeak(Address dst, Address src);
4303e5dd7070Spatrick   void EmitARCMoveWeak(Address dst, Address src);
4304e5dd7070Spatrick   llvm::Value *EmitARCRetainAutorelease(QualType type, llvm::Value *value);
4305e5dd7070Spatrick   llvm::Value *EmitARCRetainAutoreleaseNonBlock(llvm::Value *value);
4306e5dd7070Spatrick   llvm::Value *EmitARCStoreStrong(LValue lvalue, llvm::Value *value,
4307e5dd7070Spatrick                                   bool resultIgnored);
4308e5dd7070Spatrick   llvm::Value *EmitARCStoreStrongCall(Address addr, llvm::Value *value,
4309e5dd7070Spatrick                                       bool resultIgnored);
4310e5dd7070Spatrick   llvm::Value *EmitARCRetain(QualType type, llvm::Value *value);
4311e5dd7070Spatrick   llvm::Value *EmitARCRetainNonBlock(llvm::Value *value);
4312e5dd7070Spatrick   llvm::Value *EmitARCRetainBlock(llvm::Value *value, bool mandatory);
4313e5dd7070Spatrick   void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise);
4314e5dd7070Spatrick   void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise);
4315e5dd7070Spatrick   llvm::Value *EmitARCAutorelease(llvm::Value *value);
4316e5dd7070Spatrick   llvm::Value *EmitARCAutoreleaseReturnValue(llvm::Value *value);
4317e5dd7070Spatrick   llvm::Value *EmitARCRetainAutoreleaseReturnValue(llvm::Value *value);
4318e5dd7070Spatrick   llvm::Value *EmitARCRetainAutoreleasedReturnValue(llvm::Value *value);
4319e5dd7070Spatrick   llvm::Value *EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value);
4320e5dd7070Spatrick 
4321e5dd7070Spatrick   llvm::Value *EmitObjCAutorelease(llvm::Value *value, llvm::Type *returnType);
4322e5dd7070Spatrick   llvm::Value *EmitObjCRetainNonBlock(llvm::Value *value,
4323e5dd7070Spatrick                                       llvm::Type *returnType);
4324e5dd7070Spatrick   void EmitObjCRelease(llvm::Value *value, ARCPreciseLifetime_t precise);
4325e5dd7070Spatrick 
4326e5dd7070Spatrick   std::pair<LValue,llvm::Value*>
4327e5dd7070Spatrick   EmitARCStoreAutoreleasing(const BinaryOperator *e);
4328e5dd7070Spatrick   std::pair<LValue,llvm::Value*>
4329e5dd7070Spatrick   EmitARCStoreStrong(const BinaryOperator *e, bool ignored);
4330e5dd7070Spatrick   std::pair<LValue,llvm::Value*>
4331e5dd7070Spatrick   EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored);
4332e5dd7070Spatrick 
4333e5dd7070Spatrick   llvm::Value *EmitObjCAlloc(llvm::Value *value,
4334e5dd7070Spatrick                              llvm::Type *returnType);
4335e5dd7070Spatrick   llvm::Value *EmitObjCAllocWithZone(llvm::Value *value,
4336e5dd7070Spatrick                                      llvm::Type *returnType);
4337e5dd7070Spatrick   llvm::Value *EmitObjCAllocInit(llvm::Value *value, llvm::Type *resultType);
4338e5dd7070Spatrick 
4339e5dd7070Spatrick   llvm::Value *EmitObjCThrowOperand(const Expr *expr);
4340e5dd7070Spatrick   llvm::Value *EmitObjCConsumeObject(QualType T, llvm::Value *Ptr);
4341e5dd7070Spatrick   llvm::Value *EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr);
4342e5dd7070Spatrick 
4343e5dd7070Spatrick   llvm::Value *EmitARCExtendBlockObject(const Expr *expr);
4344e5dd7070Spatrick   llvm::Value *EmitARCReclaimReturnedObject(const Expr *e,
4345e5dd7070Spatrick                                             bool allowUnsafeClaim);
4346e5dd7070Spatrick   llvm::Value *EmitARCRetainScalarExpr(const Expr *expr);
4347e5dd7070Spatrick   llvm::Value *EmitARCRetainAutoreleaseScalarExpr(const Expr *expr);
4348e5dd7070Spatrick   llvm::Value *EmitARCUnsafeUnretainedScalarExpr(const Expr *expr);
4349e5dd7070Spatrick 
4350e5dd7070Spatrick   void EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values);
4351e5dd7070Spatrick 
4352a9ac8606Spatrick   void EmitARCNoopIntrinsicUse(ArrayRef<llvm::Value *> values);
4353a9ac8606Spatrick 
4354e5dd7070Spatrick   static Destroyer destroyARCStrongImprecise;
4355e5dd7070Spatrick   static Destroyer destroyARCStrongPrecise;
4356e5dd7070Spatrick   static Destroyer destroyARCWeak;
4357e5dd7070Spatrick   static Destroyer emitARCIntrinsicUse;
4358e5dd7070Spatrick   static Destroyer destroyNonTrivialCStruct;
4359e5dd7070Spatrick 
4360e5dd7070Spatrick   void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr);
4361e5dd7070Spatrick   llvm::Value *EmitObjCAutoreleasePoolPush();
4362e5dd7070Spatrick   llvm::Value *EmitObjCMRRAutoreleasePoolPush();
4363e5dd7070Spatrick   void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr);
4364e5dd7070Spatrick   void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr);
4365e5dd7070Spatrick 
4366e5dd7070Spatrick   /// Emits a reference binding to the passed in expression.
4367e5dd7070Spatrick   RValue EmitReferenceBindingToExpr(const Expr *E);
4368e5dd7070Spatrick 
4369e5dd7070Spatrick   //===--------------------------------------------------------------------===//
4370e5dd7070Spatrick   //                           Expression Emission
4371e5dd7070Spatrick   //===--------------------------------------------------------------------===//
4372e5dd7070Spatrick 
4373e5dd7070Spatrick   // Expressions are broken into three classes: scalar, complex, aggregate.
4374e5dd7070Spatrick 
4375e5dd7070Spatrick   /// EmitScalarExpr - Emit the computation of the specified expression of LLVM
4376e5dd7070Spatrick   /// scalar type, returning the result.
4377e5dd7070Spatrick   llvm::Value *EmitScalarExpr(const Expr *E , bool IgnoreResultAssign = false);
4378e5dd7070Spatrick 
4379e5dd7070Spatrick   /// Emit a conversion from the specified type to the specified destination
4380e5dd7070Spatrick   /// type, both of which are LLVM scalar types.
4381e5dd7070Spatrick   llvm::Value *EmitScalarConversion(llvm::Value *Src, QualType SrcTy,
4382e5dd7070Spatrick                                     QualType DstTy, SourceLocation Loc);
4383e5dd7070Spatrick 
4384e5dd7070Spatrick   /// Emit a conversion from the specified complex type to the specified
4385e5dd7070Spatrick   /// destination type, where the destination type is an LLVM scalar type.
4386e5dd7070Spatrick   llvm::Value *EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy,
4387e5dd7070Spatrick                                              QualType DstTy,
4388e5dd7070Spatrick                                              SourceLocation Loc);
4389e5dd7070Spatrick 
4390e5dd7070Spatrick   /// EmitAggExpr - Emit the computation of the specified expression
4391e5dd7070Spatrick   /// of aggregate type.  The result is computed into the given slot,
4392e5dd7070Spatrick   /// which may be null to indicate that the value is not needed.
4393e5dd7070Spatrick   void EmitAggExpr(const Expr *E, AggValueSlot AS);
4394e5dd7070Spatrick 
4395e5dd7070Spatrick   /// EmitAggExprToLValue - Emit the computation of the specified expression of
4396e5dd7070Spatrick   /// aggregate type into a temporary LValue.
4397e5dd7070Spatrick   LValue EmitAggExprToLValue(const Expr *E);
4398e5dd7070Spatrick 
4399ec727ea7Spatrick   /// Build all the stores needed to initialize an aggregate at Dest with the
4400ec727ea7Spatrick   /// value Val.
4401ec727ea7Spatrick   void EmitAggregateStore(llvm::Value *Val, Address Dest, bool DestIsVolatile);
4402ec727ea7Spatrick 
4403e5dd7070Spatrick   /// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
4404e5dd7070Spatrick   /// make sure it survives garbage collection until this point.
4405e5dd7070Spatrick   void EmitExtendGCLifetime(llvm::Value *object);
4406e5dd7070Spatrick 
4407e5dd7070Spatrick   /// EmitComplexExpr - Emit the computation of the specified expression of
4408e5dd7070Spatrick   /// complex type, returning the result.
4409e5dd7070Spatrick   ComplexPairTy EmitComplexExpr(const Expr *E,
4410e5dd7070Spatrick                                 bool IgnoreReal = false,
4411e5dd7070Spatrick                                 bool IgnoreImag = false);
4412e5dd7070Spatrick 
4413e5dd7070Spatrick   /// EmitComplexExprIntoLValue - Emit the given expression of complex
4414e5dd7070Spatrick   /// type and place its result into the specified l-value.
4415e5dd7070Spatrick   void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit);
4416e5dd7070Spatrick 
4417e5dd7070Spatrick   /// EmitStoreOfComplex - Store a complex number into the specified l-value.
4418e5dd7070Spatrick   void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit);
4419e5dd7070Spatrick 
4420e5dd7070Spatrick   /// EmitLoadOfComplex - Load a complex number from the specified l-value.
4421e5dd7070Spatrick   ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc);
4422e5dd7070Spatrick 
4423*12c85518Srobert   ComplexPairTy EmitPromotedComplexExpr(const Expr *E, QualType PromotionType);
4424*12c85518Srobert   llvm::Value *EmitPromotedScalarExpr(const Expr *E, QualType PromotionType);
4425*12c85518Srobert   ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType);
4426*12c85518Srobert   ComplexPairTy EmitUnPromotedValue(ComplexPairTy result, QualType PromotionType);
4427*12c85518Srobert 
4428e5dd7070Spatrick   Address emitAddrOfRealComponent(Address complex, QualType complexType);
4429e5dd7070Spatrick   Address emitAddrOfImagComponent(Address complex, QualType complexType);
4430e5dd7070Spatrick 
4431e5dd7070Spatrick   /// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the
4432e5dd7070Spatrick   /// global variable that has already been created for it.  If the initializer
4433e5dd7070Spatrick   /// has a different type than GV does, this may free GV and return a different
4434e5dd7070Spatrick   /// one.  Otherwise it just returns GV.
4435e5dd7070Spatrick   llvm::GlobalVariable *
4436e5dd7070Spatrick   AddInitializerToStaticVarDecl(const VarDecl &D,
4437e5dd7070Spatrick                                 llvm::GlobalVariable *GV);
4438e5dd7070Spatrick 
4439e5dd7070Spatrick   // Emit an @llvm.invariant.start call for the given memory region.
4440e5dd7070Spatrick   void EmitInvariantStart(llvm::Constant *Addr, CharUnits Size);
4441e5dd7070Spatrick 
4442e5dd7070Spatrick   /// EmitCXXGlobalVarDeclInit - Create the initializer for a C++
4443e5dd7070Spatrick   /// variable with global storage.
4444*12c85518Srobert   void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV,
4445e5dd7070Spatrick                                 bool PerformInit);
4446e5dd7070Spatrick 
4447e5dd7070Spatrick   llvm::Function *createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor,
4448e5dd7070Spatrick                                    llvm::Constant *Addr);
4449e5dd7070Spatrick 
4450a9ac8606Spatrick   llvm::Function *createTLSAtExitStub(const VarDecl &VD,
4451a9ac8606Spatrick                                       llvm::FunctionCallee Dtor,
4452a9ac8606Spatrick                                       llvm::Constant *Addr,
4453a9ac8606Spatrick                                       llvm::FunctionCallee &AtExit);
4454a9ac8606Spatrick 
4455e5dd7070Spatrick   /// Call atexit() with a function that passes the given argument to
4456e5dd7070Spatrick   /// the given function.
4457e5dd7070Spatrick   void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn,
4458e5dd7070Spatrick                                     llvm::Constant *addr);
4459e5dd7070Spatrick 
4460e5dd7070Spatrick   /// Call atexit() with function dtorStub.
4461e5dd7070Spatrick   void registerGlobalDtorWithAtExit(llvm::Constant *dtorStub);
4462e5dd7070Spatrick 
4463ec727ea7Spatrick   /// Call unatexit() with function dtorStub.
4464a9ac8606Spatrick   llvm::Value *unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub);
4465ec727ea7Spatrick 
4466e5dd7070Spatrick   /// Emit code in this function to perform a guarded variable
4467e5dd7070Spatrick   /// initialization.  Guarded initializations are used when it's not
4468e5dd7070Spatrick   /// possible to prove that an initialization will be done exactly
4469e5dd7070Spatrick   /// once, e.g. with a static local variable or a static data member
4470e5dd7070Spatrick   /// of a class template.
4471e5dd7070Spatrick   void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr,
4472e5dd7070Spatrick                           bool PerformInit);
4473e5dd7070Spatrick 
4474e5dd7070Spatrick   enum class GuardKind { VariableGuard, TlsGuard };
4475e5dd7070Spatrick 
4476e5dd7070Spatrick   /// Emit a branch to select whether or not to perform guarded initialization.
4477e5dd7070Spatrick   void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit,
4478e5dd7070Spatrick                                 llvm::BasicBlock *InitBlock,
4479e5dd7070Spatrick                                 llvm::BasicBlock *NoInitBlock,
4480e5dd7070Spatrick                                 GuardKind Kind, const VarDecl *D);
4481e5dd7070Spatrick 
4482e5dd7070Spatrick   /// GenerateCXXGlobalInitFunc - Generates code for initializing global
4483e5dd7070Spatrick   /// variables.
4484e5dd7070Spatrick   void
4485e5dd7070Spatrick   GenerateCXXGlobalInitFunc(llvm::Function *Fn,
4486e5dd7070Spatrick                             ArrayRef<llvm::Function *> CXXThreadLocals,
4487e5dd7070Spatrick                             ConstantAddress Guard = ConstantAddress::invalid());
4488e5dd7070Spatrick 
4489ec727ea7Spatrick   /// GenerateCXXGlobalCleanUpFunc - Generates code for cleaning up global
4490e5dd7070Spatrick   /// variables.
4491ec727ea7Spatrick   void GenerateCXXGlobalCleanUpFunc(
4492e5dd7070Spatrick       llvm::Function *Fn,
4493a9ac8606Spatrick       ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
4494a9ac8606Spatrick                           llvm::Constant *>>
4495a9ac8606Spatrick           DtorsOrStermFinalizers);
4496e5dd7070Spatrick 
4497e5dd7070Spatrick   void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
4498e5dd7070Spatrick                                         const VarDecl *D,
4499e5dd7070Spatrick                                         llvm::GlobalVariable *Addr,
4500e5dd7070Spatrick                                         bool PerformInit);
4501e5dd7070Spatrick 
4502e5dd7070Spatrick   void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest);
4503e5dd7070Spatrick 
4504e5dd7070Spatrick   void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp);
4505e5dd7070Spatrick 
4506e5dd7070Spatrick   void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint = true);
4507e5dd7070Spatrick 
4508e5dd7070Spatrick   RValue EmitAtomicExpr(AtomicExpr *E);
4509e5dd7070Spatrick 
4510e5dd7070Spatrick   //===--------------------------------------------------------------------===//
4511e5dd7070Spatrick   //                         Annotations Emission
4512e5dd7070Spatrick   //===--------------------------------------------------------------------===//
4513e5dd7070Spatrick 
4514e5dd7070Spatrick   /// Emit an annotation call (intrinsic).
4515e5dd7070Spatrick   llvm::Value *EmitAnnotationCall(llvm::Function *AnnotationFn,
4516e5dd7070Spatrick                                   llvm::Value *AnnotatedVal,
4517e5dd7070Spatrick                                   StringRef AnnotationStr,
4518a9ac8606Spatrick                                   SourceLocation Location,
4519a9ac8606Spatrick                                   const AnnotateAttr *Attr);
4520e5dd7070Spatrick 
4521e5dd7070Spatrick   /// Emit local annotations for the local variable V, declared by D.
4522e5dd7070Spatrick   void EmitVarAnnotations(const VarDecl *D, llvm::Value *V);
4523e5dd7070Spatrick 
4524e5dd7070Spatrick   /// Emit field annotations for the given field & value. Returns the
4525e5dd7070Spatrick   /// annotation result.
4526e5dd7070Spatrick   Address EmitFieldAnnotations(const FieldDecl *D, Address V);
4527e5dd7070Spatrick 
4528e5dd7070Spatrick   //===--------------------------------------------------------------------===//
4529e5dd7070Spatrick   //                             Internal Helpers
4530e5dd7070Spatrick   //===--------------------------------------------------------------------===//
4531e5dd7070Spatrick 
4532e5dd7070Spatrick   /// ContainsLabel - Return true if the statement contains a label in it.  If
4533e5dd7070Spatrick   /// this statement is not executed normally, it not containing a label means
4534e5dd7070Spatrick   /// that we can just remove the code.
4535e5dd7070Spatrick   static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false);
4536e5dd7070Spatrick 
4537e5dd7070Spatrick   /// containsBreak - Return true if the statement contains a break out of it.
4538e5dd7070Spatrick   /// If the statement (recursively) contains a switch or loop with a break
4539e5dd7070Spatrick   /// inside of it, this is fine.
4540e5dd7070Spatrick   static bool containsBreak(const Stmt *S);
4541e5dd7070Spatrick 
4542e5dd7070Spatrick   /// Determine if the given statement might introduce a declaration into the
4543e5dd7070Spatrick   /// current scope, by being a (possibly-labelled) DeclStmt.
4544e5dd7070Spatrick   static bool mightAddDeclToScope(const Stmt *S);
4545e5dd7070Spatrick 
4546e5dd7070Spatrick   /// ConstantFoldsToSimpleInteger - If the specified expression does not fold
4547e5dd7070Spatrick   /// to a constant, or if it does but contains a label, return false.  If it
4548e5dd7070Spatrick   /// constant folds return true and set the boolean result in Result.
4549e5dd7070Spatrick   bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result,
4550e5dd7070Spatrick                                     bool AllowLabels = false);
4551e5dd7070Spatrick 
4552e5dd7070Spatrick   /// ConstantFoldsToSimpleInteger - If the specified expression does not fold
4553e5dd7070Spatrick   /// to a constant, or if it does but contains a label, return false.  If it
4554e5dd7070Spatrick   /// constant folds return true and set the folded value.
4555e5dd7070Spatrick   bool ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APSInt &Result,
4556e5dd7070Spatrick                                     bool AllowLabels = false);
4557e5dd7070Spatrick 
4558a9ac8606Spatrick   /// isInstrumentedCondition - Determine whether the given condition is an
4559a9ac8606Spatrick   /// instrumentable condition (i.e. no "&&" or "||").
4560a9ac8606Spatrick   static bool isInstrumentedCondition(const Expr *C);
4561a9ac8606Spatrick 
4562a9ac8606Spatrick   /// EmitBranchToCounterBlock - Emit a conditional branch to a new block that
4563a9ac8606Spatrick   /// increments a profile counter based on the semantics of the given logical
4564a9ac8606Spatrick   /// operator opcode.  This is used to instrument branch condition coverage
4565a9ac8606Spatrick   /// for logical operators.
4566a9ac8606Spatrick   void EmitBranchToCounterBlock(const Expr *Cond, BinaryOperator::Opcode LOp,
4567a9ac8606Spatrick                                 llvm::BasicBlock *TrueBlock,
4568a9ac8606Spatrick                                 llvm::BasicBlock *FalseBlock,
4569a9ac8606Spatrick                                 uint64_t TrueCount = 0,
4570a9ac8606Spatrick                                 Stmt::Likelihood LH = Stmt::LH_None,
4571a9ac8606Spatrick                                 const Expr *CntrIdx = nullptr);
4572a9ac8606Spatrick 
4573e5dd7070Spatrick   /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an
4574e5dd7070Spatrick   /// if statement) to the specified blocks.  Based on the condition, this might
4575e5dd7070Spatrick   /// try to simplify the codegen of the conditional based on the branch.
4576e5dd7070Spatrick   /// TrueCount should be the number of times we expect the condition to
4577e5dd7070Spatrick   /// evaluate to true based on PGO data.
4578e5dd7070Spatrick   void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock,
4579a9ac8606Spatrick                             llvm::BasicBlock *FalseBlock, uint64_t TrueCount,
4580a9ac8606Spatrick                             Stmt::Likelihood LH = Stmt::LH_None);
4581e5dd7070Spatrick 
4582e5dd7070Spatrick   /// Given an assignment `*LHS = RHS`, emit a test that checks if \p RHS is
4583e5dd7070Spatrick   /// nonnull, if \p LHS is marked _Nonnull.
4584e5dd7070Spatrick   void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc);
4585e5dd7070Spatrick 
4586e5dd7070Spatrick   /// An enumeration which makes it easier to specify whether or not an
4587e5dd7070Spatrick   /// operation is a subtraction.
4588e5dd7070Spatrick   enum { NotSubtraction = false, IsSubtraction = true };
4589e5dd7070Spatrick 
4590e5dd7070Spatrick   /// Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to
4591e5dd7070Spatrick   /// detect undefined behavior when the pointer overflow sanitizer is enabled.
4592e5dd7070Spatrick   /// \p SignedIndices indicates whether any of the GEP indices are signed.
4593e5dd7070Spatrick   /// \p IsSubtraction indicates whether the expression used to form the GEP
4594e5dd7070Spatrick   /// is a subtraction.
4595*12c85518Srobert   llvm::Value *EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr,
4596e5dd7070Spatrick                                       ArrayRef<llvm::Value *> IdxList,
4597e5dd7070Spatrick                                       bool SignedIndices,
4598e5dd7070Spatrick                                       bool IsSubtraction,
4599e5dd7070Spatrick                                       SourceLocation Loc,
4600e5dd7070Spatrick                                       const Twine &Name = "");
4601e5dd7070Spatrick 
4602e5dd7070Spatrick   /// Specifies which type of sanitizer check to apply when handling a
4603e5dd7070Spatrick   /// particular builtin.
4604e5dd7070Spatrick   enum BuiltinCheckKind {
4605e5dd7070Spatrick     BCK_CTZPassedZero,
4606e5dd7070Spatrick     BCK_CLZPassedZero,
4607e5dd7070Spatrick   };
4608e5dd7070Spatrick 
4609e5dd7070Spatrick   /// Emits an argument for a call to a builtin. If the builtin sanitizer is
4610e5dd7070Spatrick   /// enabled, a runtime check specified by \p Kind is also emitted.
4611e5dd7070Spatrick   llvm::Value *EmitCheckedArgForBuiltin(const Expr *E, BuiltinCheckKind Kind);
4612e5dd7070Spatrick 
4613e5dd7070Spatrick   /// Emit a description of a type in a format suitable for passing to
4614e5dd7070Spatrick   /// a runtime sanitizer handler.
4615e5dd7070Spatrick   llvm::Constant *EmitCheckTypeDescriptor(QualType T);
4616e5dd7070Spatrick 
4617e5dd7070Spatrick   /// Convert a value into a format suitable for passing to a runtime
4618e5dd7070Spatrick   /// sanitizer handler.
4619e5dd7070Spatrick   llvm::Value *EmitCheckValue(llvm::Value *V);
4620e5dd7070Spatrick 
4621e5dd7070Spatrick   /// Emit a description of a source location in a format suitable for
4622e5dd7070Spatrick   /// passing to a runtime sanitizer handler.
4623e5dd7070Spatrick   llvm::Constant *EmitCheckSourceLocation(SourceLocation Loc);
4624e5dd7070Spatrick 
4625*12c85518Srobert   void EmitKCFIOperandBundle(const CGCallee &Callee,
4626*12c85518Srobert                              SmallVectorImpl<llvm::OperandBundleDef> &Bundles);
4627*12c85518Srobert 
4628e5dd7070Spatrick   /// Create a basic block that will either trap or call a handler function in
4629e5dd7070Spatrick   /// the UBSan runtime with the provided arguments, and create a conditional
4630e5dd7070Spatrick   /// branch to it.
4631e5dd7070Spatrick   void EmitCheck(ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked,
4632e5dd7070Spatrick                  SanitizerHandler Check, ArrayRef<llvm::Constant *> StaticArgs,
4633e5dd7070Spatrick                  ArrayRef<llvm::Value *> DynamicArgs);
4634e5dd7070Spatrick 
4635e5dd7070Spatrick   /// Emit a slow path cross-DSO CFI check which calls __cfi_slowpath
4636e5dd7070Spatrick   /// if Cond if false.
4637e5dd7070Spatrick   void EmitCfiSlowPathCheck(SanitizerMask Kind, llvm::Value *Cond,
4638e5dd7070Spatrick                             llvm::ConstantInt *TypeId, llvm::Value *Ptr,
4639e5dd7070Spatrick                             ArrayRef<llvm::Constant *> StaticArgs);
4640e5dd7070Spatrick 
4641e5dd7070Spatrick   /// Emit a reached-unreachable diagnostic if \p Loc is valid and runtime
4642e5dd7070Spatrick   /// checking is enabled. Otherwise, just emit an unreachable instruction.
4643e5dd7070Spatrick   void EmitUnreachable(SourceLocation Loc);
4644e5dd7070Spatrick 
4645e5dd7070Spatrick   /// Create a basic block that will call the trap intrinsic, and emit a
4646e5dd7070Spatrick   /// conditional branch to it, for the -ftrapv checks.
4647a9ac8606Spatrick   void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID);
4648e5dd7070Spatrick 
4649e5dd7070Spatrick   /// Emit a call to trap or debugtrap and attach function attribute
4650e5dd7070Spatrick   /// "trap-func-name" if specified.
4651e5dd7070Spatrick   llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID);
4652e5dd7070Spatrick 
4653e5dd7070Spatrick   /// Emit a stub for the cross-DSO CFI check function.
4654e5dd7070Spatrick   void EmitCfiCheckStub();
4655e5dd7070Spatrick 
4656e5dd7070Spatrick   /// Emit a cross-DSO CFI failure handling function.
4657e5dd7070Spatrick   void EmitCfiCheckFail();
4658e5dd7070Spatrick 
4659e5dd7070Spatrick   /// Create a check for a function parameter that may potentially be
4660e5dd7070Spatrick   /// declared as non-null.
4661e5dd7070Spatrick   void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc,
4662e5dd7070Spatrick                            AbstractCallee AC, unsigned ParmNum);
4663e5dd7070Spatrick 
4664e5dd7070Spatrick   /// EmitCallArg - Emit a single call argument.
4665e5dd7070Spatrick   void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);
4666e5dd7070Spatrick 
4667e5dd7070Spatrick   /// EmitDelegateCallArg - We are performing a delegate call; that
4668e5dd7070Spatrick   /// is, the current function is delegating to another one.  Produce
4669e5dd7070Spatrick   /// a r-value suitable for passing the given parameter.
4670e5dd7070Spatrick   void EmitDelegateCallArg(CallArgList &args, const VarDecl *param,
4671e5dd7070Spatrick                            SourceLocation loc);
4672e5dd7070Spatrick 
4673e5dd7070Spatrick   /// SetFPAccuracy - Set the minimum required accuracy of the given floating
4674e5dd7070Spatrick   /// point operation, expressed as the maximum relative error in ulp.
4675e5dd7070Spatrick   void SetFPAccuracy(llvm::Value *Val, float Accuracy);
4676e5dd7070Spatrick 
4677ec727ea7Spatrick   /// Set the codegen fast-math flags.
4678ec727ea7Spatrick   void SetFastMathFlags(FPOptions FPFeatures);
4679ec727ea7Spatrick 
4680*12c85518Srobert   // Truncate or extend a boolean vector to the requested number of elements.
4681*12c85518Srobert   llvm::Value *emitBoolVecConversion(llvm::Value *SrcVec,
4682*12c85518Srobert                                      unsigned NumElementsDst,
4683*12c85518Srobert                                      const llvm::Twine &Name = "");
4684*12c85518Srobert 
4685e5dd7070Spatrick private:
4686e5dd7070Spatrick   llvm::MDNode *getRangeForLoadFromType(QualType Ty);
4687e5dd7070Spatrick   void EmitReturnOfRValue(RValue RV, QualType Ty);
4688e5dd7070Spatrick 
4689e5dd7070Spatrick   void deferPlaceholderReplacement(llvm::Instruction *Old, llvm::Value *New);
4690e5dd7070Spatrick 
4691a9ac8606Spatrick   llvm::SmallVector<std::pair<llvm::WeakTrackingVH, llvm::Value *>, 4>
4692e5dd7070Spatrick       DeferredReplacements;
4693e5dd7070Spatrick 
4694e5dd7070Spatrick   /// Set the address of a local variable.
4695e5dd7070Spatrick   void setAddrOfLocalVar(const VarDecl *VD, Address Addr) {
4696e5dd7070Spatrick     assert(!LocalDeclMap.count(VD) && "Decl already exists in LocalDeclMap!");
4697e5dd7070Spatrick     LocalDeclMap.insert({VD, Addr});
4698e5dd7070Spatrick   }
4699e5dd7070Spatrick 
4700e5dd7070Spatrick   /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty
4701e5dd7070Spatrick   /// from function arguments into \arg Dst. See ABIArgInfo::Expand.
4702e5dd7070Spatrick   ///
4703e5dd7070Spatrick   /// \param AI - The first function argument of the expansion.
4704e5dd7070Spatrick   void ExpandTypeFromArgs(QualType Ty, LValue Dst,
4705ec727ea7Spatrick                           llvm::Function::arg_iterator &AI);
4706e5dd7070Spatrick 
4707e5dd7070Spatrick   /// ExpandTypeToArgs - Expand an CallArg \arg Arg, with the LLVM type for \arg
4708e5dd7070Spatrick   /// Ty, into individual arguments on the provided vector \arg IRCallArgs,
4709e5dd7070Spatrick   /// starting at index \arg IRCallArgPos. See ABIArgInfo::Expand.
4710e5dd7070Spatrick   void ExpandTypeToArgs(QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy,
4711e5dd7070Spatrick                         SmallVectorImpl<llvm::Value *> &IRCallArgs,
4712e5dd7070Spatrick                         unsigned &IRCallArgPos);
4713e5dd7070Spatrick 
4714*12c85518Srobert   std::pair<llvm::Value *, llvm::Type *>
4715*12c85518Srobert   EmitAsmInput(const TargetInfo::ConstraintInfo &Info, const Expr *InputExpr,
4716*12c85518Srobert                std::string &ConstraintStr);
4717e5dd7070Spatrick 
4718*12c85518Srobert   std::pair<llvm::Value *, llvm::Type *>
4719*12c85518Srobert   EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, LValue InputValue,
4720*12c85518Srobert                      QualType InputType, std::string &ConstraintStr,
4721e5dd7070Spatrick                      SourceLocation Loc);
4722e5dd7070Spatrick 
4723e5dd7070Spatrick   /// Attempts to statically evaluate the object size of E. If that
4724e5dd7070Spatrick   /// fails, emits code to figure the size of E out for us. This is
4725e5dd7070Spatrick   /// pass_object_size aware.
4726e5dd7070Spatrick   ///
4727e5dd7070Spatrick   /// If EmittedExpr is non-null, this will use that instead of re-emitting E.
4728e5dd7070Spatrick   llvm::Value *evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
4729e5dd7070Spatrick                                                llvm::IntegerType *ResType,
4730e5dd7070Spatrick                                                llvm::Value *EmittedE,
4731e5dd7070Spatrick                                                bool IsDynamic);
4732e5dd7070Spatrick 
4733e5dd7070Spatrick   /// Emits the size of E, as required by __builtin_object_size. This
4734e5dd7070Spatrick   /// function is aware of pass_object_size parameters, and will act accordingly
4735e5dd7070Spatrick   /// if E is a parameter with the pass_object_size attribute.
4736e5dd7070Spatrick   llvm::Value *emitBuiltinObjectSize(const Expr *E, unsigned Type,
4737e5dd7070Spatrick                                      llvm::IntegerType *ResType,
4738e5dd7070Spatrick                                      llvm::Value *EmittedE,
4739e5dd7070Spatrick                                      bool IsDynamic);
4740e5dd7070Spatrick 
4741e5dd7070Spatrick   void emitZeroOrPatternForAutoVarInit(QualType type, const VarDecl &D,
4742e5dd7070Spatrick                                        Address Loc);
4743e5dd7070Spatrick 
4744e5dd7070Spatrick public:
4745e5dd7070Spatrick   enum class EvaluationOrder {
4746e5dd7070Spatrick     ///! No language constraints on evaluation order.
4747e5dd7070Spatrick     Default,
4748e5dd7070Spatrick     ///! Language semantics require left-to-right evaluation.
4749e5dd7070Spatrick     ForceLeftToRight,
4750e5dd7070Spatrick     ///! Language semantics require right-to-left evaluation.
4751e5dd7070Spatrick     ForceRightToLeft
4752e5dd7070Spatrick   };
4753e5dd7070Spatrick 
4754a9ac8606Spatrick   // Wrapper for function prototype sources. Wraps either a FunctionProtoType or
4755a9ac8606Spatrick   // an ObjCMethodDecl.
4756a9ac8606Spatrick   struct PrototypeWrapper {
4757a9ac8606Spatrick     llvm::PointerUnion<const FunctionProtoType *, const ObjCMethodDecl *> P;
4758e5dd7070Spatrick 
4759a9ac8606Spatrick     PrototypeWrapper(const FunctionProtoType *FT) : P(FT) {}
4760a9ac8606Spatrick     PrototypeWrapper(const ObjCMethodDecl *MD) : P(MD) {}
4761a9ac8606Spatrick   };
4762e5dd7070Spatrick 
4763a9ac8606Spatrick   void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype,
4764e5dd7070Spatrick                     llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
4765e5dd7070Spatrick                     AbstractCallee AC = AbstractCallee(),
4766e5dd7070Spatrick                     unsigned ParamsToSkip = 0,
4767e5dd7070Spatrick                     EvaluationOrder Order = EvaluationOrder::Default);
4768e5dd7070Spatrick 
4769e5dd7070Spatrick   /// EmitPointerWithAlignment - Given an expression with a pointer type,
4770e5dd7070Spatrick   /// emit the value and compute our best estimate of the alignment of the
4771e5dd7070Spatrick   /// pointee.
4772e5dd7070Spatrick   ///
4773e5dd7070Spatrick   /// \param BaseInfo - If non-null, this will be initialized with
4774e5dd7070Spatrick   /// information about the source of the alignment and the may-alias
4775e5dd7070Spatrick   /// attribute.  Note that this function will conservatively fall back on
4776e5dd7070Spatrick   /// the type when it doesn't recognize the expression and may-alias will
4777e5dd7070Spatrick   /// be set to false.
4778e5dd7070Spatrick   ///
4779e5dd7070Spatrick   /// One reasonable way to use this information is when there's a language
4780e5dd7070Spatrick   /// guarantee that the pointer must be aligned to some stricter value, and
4781e5dd7070Spatrick   /// we're simply trying to ensure that sufficiently obvious uses of under-
4782e5dd7070Spatrick   /// aligned objects don't get miscompiled; for example, a placement new
4783e5dd7070Spatrick   /// into the address of a local variable.  In such a case, it's quite
4784e5dd7070Spatrick   /// reasonable to just ignore the returned alignment when it isn't from an
4785e5dd7070Spatrick   /// explicit source.
4786e5dd7070Spatrick   Address EmitPointerWithAlignment(const Expr *Addr,
4787e5dd7070Spatrick                                    LValueBaseInfo *BaseInfo = nullptr,
4788e5dd7070Spatrick                                    TBAAAccessInfo *TBAAInfo = nullptr);
4789e5dd7070Spatrick 
4790e5dd7070Spatrick   /// If \p E references a parameter with pass_object_size info or a constant
4791e5dd7070Spatrick   /// array size modifier, emit the object size divided by the size of \p EltTy.
4792e5dd7070Spatrick   /// Otherwise return null.
4793e5dd7070Spatrick   llvm::Value *LoadPassedObjectSize(const Expr *E, QualType EltTy);
4794e5dd7070Spatrick 
4795e5dd7070Spatrick   void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK);
4796e5dd7070Spatrick 
4797e5dd7070Spatrick   struct MultiVersionResolverOption {
4798e5dd7070Spatrick     llvm::Function *Function;
4799e5dd7070Spatrick     struct Conds {
4800e5dd7070Spatrick       StringRef Architecture;
4801e5dd7070Spatrick       llvm::SmallVector<StringRef, 8> Features;
4802e5dd7070Spatrick 
4803e5dd7070Spatrick       Conds(StringRef Arch, ArrayRef<StringRef> Feats)
4804e5dd7070Spatrick           : Architecture(Arch), Features(Feats.begin(), Feats.end()) {}
4805e5dd7070Spatrick     } Conditions;
4806e5dd7070Spatrick 
4807e5dd7070Spatrick     MultiVersionResolverOption(llvm::Function *F, StringRef Arch,
4808e5dd7070Spatrick                                ArrayRef<StringRef> Feats)
4809e5dd7070Spatrick         : Function(F), Conditions(Arch, Feats) {}
4810e5dd7070Spatrick   };
4811e5dd7070Spatrick 
4812e5dd7070Spatrick   // Emits the body of a multiversion function's resolver. Assumes that the
4813e5dd7070Spatrick   // options are already sorted in the proper order, with the 'default' option
4814e5dd7070Spatrick   // last (if it exists).
4815e5dd7070Spatrick   void EmitMultiVersionResolver(llvm::Function *Resolver,
4816e5dd7070Spatrick                                 ArrayRef<MultiVersionResolverOption> Options);
4817*12c85518Srobert   void
4818*12c85518Srobert   EmitX86MultiVersionResolver(llvm::Function *Resolver,
4819*12c85518Srobert                               ArrayRef<MultiVersionResolverOption> Options);
4820*12c85518Srobert   void
4821*12c85518Srobert   EmitAArch64MultiVersionResolver(llvm::Function *Resolver,
4822*12c85518Srobert                                   ArrayRef<MultiVersionResolverOption> Options);
4823e5dd7070Spatrick 
4824e5dd7070Spatrick private:
4825e5dd7070Spatrick   QualType getVarArgType(const Expr *Arg);
4826e5dd7070Spatrick 
4827e5dd7070Spatrick   void EmitDeclMetadata();
4828e5dd7070Spatrick 
4829e5dd7070Spatrick   BlockByrefHelpers *buildByrefHelpers(llvm::StructType &byrefType,
4830e5dd7070Spatrick                                   const AutoVarEmission &emission);
4831e5dd7070Spatrick 
4832e5dd7070Spatrick   void AddObjCARCExceptionMetadata(llvm::Instruction *Inst);
4833e5dd7070Spatrick 
4834e5dd7070Spatrick   llvm::Value *GetValueForARMHint(unsigned BuiltinID);
4835e5dd7070Spatrick   llvm::Value *EmitX86CpuIs(const CallExpr *E);
4836e5dd7070Spatrick   llvm::Value *EmitX86CpuIs(StringRef CPUStr);
4837e5dd7070Spatrick   llvm::Value *EmitX86CpuSupports(const CallExpr *E);
4838e5dd7070Spatrick   llvm::Value *EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs);
4839e5dd7070Spatrick   llvm::Value *EmitX86CpuSupports(uint64_t Mask);
4840e5dd7070Spatrick   llvm::Value *EmitX86CpuInit();
4841*12c85518Srobert   llvm::Value *FormX86ResolverCondition(const MultiVersionResolverOption &RO);
4842*12c85518Srobert   llvm::Value *EmitAArch64CpuInit();
4843*12c85518Srobert   llvm::Value *
4844*12c85518Srobert   FormAArch64ResolverCondition(const MultiVersionResolverOption &RO);
4845*12c85518Srobert   llvm::Value *EmitAArch64CpuSupports(ArrayRef<StringRef> FeatureStrs);
4846e5dd7070Spatrick };
4847e5dd7070Spatrick 
4848a9ac8606Spatrick 
4849e5dd7070Spatrick inline DominatingLLVMValue::saved_type
4850e5dd7070Spatrick DominatingLLVMValue::save(CodeGenFunction &CGF, llvm::Value *value) {
4851e5dd7070Spatrick   if (!needsSaving(value)) return saved_type(value, false);
4852e5dd7070Spatrick 
4853e5dd7070Spatrick   // Otherwise, we need an alloca.
4854e5dd7070Spatrick   auto align = CharUnits::fromQuantity(
4855*12c85518Srobert       CGF.CGM.getDataLayout().getPrefTypeAlign(value->getType()));
4856e5dd7070Spatrick   Address alloca =
4857e5dd7070Spatrick       CGF.CreateTempAlloca(value->getType(), align, "cond-cleanup.save");
4858e5dd7070Spatrick   CGF.Builder.CreateStore(value, alloca);
4859e5dd7070Spatrick 
4860e5dd7070Spatrick   return saved_type(alloca.getPointer(), true);
4861e5dd7070Spatrick }
4862e5dd7070Spatrick 
4863e5dd7070Spatrick inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF,
4864e5dd7070Spatrick                                                  saved_type value) {
4865e5dd7070Spatrick   // If the value says it wasn't saved, trust that it's still dominating.
4866e5dd7070Spatrick   if (!value.getInt()) return value.getPointer();
4867e5dd7070Spatrick 
4868e5dd7070Spatrick   // Otherwise, it should be an alloca instruction, as set up in save().
4869e5dd7070Spatrick   auto alloca = cast<llvm::AllocaInst>(value.getPointer());
4870a9ac8606Spatrick   return CGF.Builder.CreateAlignedLoad(alloca->getAllocatedType(), alloca,
4871a9ac8606Spatrick                                        alloca->getAlign());
4872e5dd7070Spatrick }
4873e5dd7070Spatrick 
4874e5dd7070Spatrick }  // end namespace CodeGen
4875ec727ea7Spatrick 
4876ec727ea7Spatrick // Map the LangOption for floating point exception behavior into
4877ec727ea7Spatrick // the corresponding enum in the IR.
4878ec727ea7Spatrick llvm::fp::ExceptionBehavior
4879ec727ea7Spatrick ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind);
4880e5dd7070Spatrick }  // end namespace clang
4881e5dd7070Spatrick 
4882e5dd7070Spatrick #endif
4883