xref: /src/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h (revision c80e69b00d976a5a3b3e84527f270fa7e72a8205)
1ec2b103cSEd Schouten //===-- CodeGenFunction.h - Per-Function state for LLVM CodeGen -*- C++ -*-===//
2ec2b103cSEd Schouten //
322989816SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
422989816SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
522989816SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ec2b103cSEd Schouten //
7ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
8ec2b103cSEd Schouten //
9ec2b103cSEd Schouten // This is the internal per-function state used for llvm translation.
10ec2b103cSEd Schouten //
11ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
12ec2b103cSEd Schouten 
1306d4ba38SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENFUNCTION_H
1406d4ba38SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CODEGENFUNCTION_H
15ec2b103cSEd Schouten 
16ec2b103cSEd Schouten #include "CGBuilder.h"
17dbe13110SDimitry Andric #include "CGDebugInfo.h"
189f4dbff6SDimitry Andric #include "CGLoopInfo.h"
19ec2b103cSEd Schouten #include "CGValue.h"
20809500fcSDimitry Andric #include "CodeGenModule.h"
219f4dbff6SDimitry Andric #include "CodeGenPGO.h"
229f4dbff6SDimitry Andric #include "EHScopeStack.h"
23bab175ecSDimitry Andric #include "VarBypassDetector.h"
24809500fcSDimitry Andric #include "clang/AST/CharUnits.h"
2522989816SDimitry Andric #include "clang/AST/CurrentSourceLocExprScope.h"
26809500fcSDimitry Andric #include "clang/AST/ExprCXX.h"
27809500fcSDimitry Andric #include "clang/AST/ExprObjC.h"
2845b53394SDimitry Andric #include "clang/AST/ExprOpenMP.h"
29ac9a064cSDimitry Andric #include "clang/AST/StmtOpenACC.h"
30cfca06d7SDimitry Andric #include "clang/AST/StmtOpenMP.h"
31809500fcSDimitry Andric #include "clang/AST/Type.h"
32809500fcSDimitry Andric #include "clang/Basic/ABI.h"
33bfef3995SDimitry Andric #include "clang/Basic/CapturedStmt.h"
34676fbe81SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
355e20cdd8SDimitry Andric #include "clang/Basic/OpenMPKinds.h"
36809500fcSDimitry Andric #include "clang/Basic/TargetInfo.h"
37809500fcSDimitry Andric #include "llvm/ADT/ArrayRef.h"
38809500fcSDimitry Andric #include "llvm/ADT/DenseMap.h"
3948675466SDimitry Andric #include "llvm/ADT/MapVector.h"
40809500fcSDimitry Andric #include "llvm/ADT/SmallVector.h"
41cfca06d7SDimitry Andric #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
42ac9a064cSDimitry Andric #include "llvm/IR/Instructions.h"
439f4dbff6SDimitry Andric #include "llvm/IR/ValueHandle.h"
44809500fcSDimitry Andric #include "llvm/Support/Debug.h"
452b6b257fSDimitry Andric #include "llvm/Transforms/Utils/SanitizerStats.h"
46e3b55780SDimitry Andric #include <optional>
47ec2b103cSEd Schouten 
48ec2b103cSEd Schouten namespace llvm {
49ec2b103cSEd Schouten class BasicBlock;
504c8b2481SRoman Divacky class LLVMContext;
510883ccd9SRoman Divacky class MDNode;
52ec2b103cSEd Schouten class SwitchInst;
5373490b89SRoman Divacky class Twine;
54ec2b103cSEd Schouten class Value;
55344a3780SDimitry Andric class CanonicalLoopInfo;
56ec2b103cSEd Schouten }
57ec2b103cSEd Schouten 
58ec2b103cSEd Schouten namespace clang {
59ec2b103cSEd Schouten class ASTContext;
60ec2b103cSEd Schouten class CXXDestructorDecl;
6101af97d3SDimitry Andric class CXXForRangeStmt;
624c8b2481SRoman Divacky class CXXTryStmt;
63ec2b103cSEd Schouten class Decl;
64bca07a45SDimitry Andric class LabelDecl;
65ec2b103cSEd Schouten class FunctionDecl;
66ec2b103cSEd Schouten class FunctionProtoType;
67ec2b103cSEd Schouten class LabelStmt;
68ec2b103cSEd Schouten class ObjCContainerDecl;
69ec2b103cSEd Schouten class ObjCInterfaceDecl;
70ec2b103cSEd Schouten class ObjCIvarDecl;
71ec2b103cSEd Schouten class ObjCMethodDecl;
72ec2b103cSEd Schouten class ObjCImplementationDecl;
73ec2b103cSEd Schouten class ObjCPropertyImplDecl;
74ec2b103cSEd Schouten class TargetInfo;
75ec2b103cSEd Schouten class VarDecl;
76ec2b103cSEd Schouten class ObjCForCollectionStmt;
77ec2b103cSEd Schouten class ObjCAtTryStmt;
78ec2b103cSEd Schouten class ObjCAtThrowStmt;
79ec2b103cSEd Schouten class ObjCAtSynchronizedStmt;
80180abc3dSDimitry Andric class ObjCAutoreleasePoolStmt;
81cfca06d7SDimitry Andric class OMPUseDevicePtrClause;
82cfca06d7SDimitry Andric class OMPUseDeviceAddrClause;
83cfca06d7SDimitry Andric class SVETypeFlags;
84cfca06d7SDimitry Andric class OMPExecutableDirective;
85ec2b103cSEd Schouten 
86461a67faSDimitry Andric namespace analyze_os_log {
87461a67faSDimitry Andric class OSLogBufferLayout;
88461a67faSDimitry Andric }
89461a67faSDimitry Andric 
90ec2b103cSEd Schouten namespace CodeGen {
91ec2b103cSEd Schouten class CodeGenTypes;
92bab175ecSDimitry Andric class CGCallee;
93ec2b103cSEd Schouten class CGFunctionInfo;
94d7279c4cSRoman Divacky class CGBlockInfo;
953d1dcd9bSDimitry Andric class CGCXXABI;
9645b53394SDimitry Andric class BlockByrefHelpers;
9745b53394SDimitry Andric class BlockByrefInfo;
98bca07a45SDimitry Andric class BlockFieldFlags;
992b6b257fSDimitry Andric class RegionCodeGenTy;
1002b6b257fSDimitry Andric class TargetCodeGenInfo;
1012b6b257fSDimitry Andric struct OMPTaskDataTy;
102bab175ecSDimitry Andric struct CGCoroData;
103ec2b103cSEd Schouten 
104809500fcSDimitry Andric /// The kind of evaluation to perform on values of a particular
105809500fcSDimitry Andric /// type.  Basically, is the code in CGExprScalar, CGExprComplex, or
106809500fcSDimitry Andric /// CGExprAgg?
107809500fcSDimitry Andric ///
108809500fcSDimitry Andric /// TODO: should vectors maybe be split out into their own thing?
109809500fcSDimitry Andric enum TypeEvaluationKind {
110809500fcSDimitry Andric   TEK_Scalar,
111809500fcSDimitry Andric   TEK_Complex,
112809500fcSDimitry Andric   TEK_Aggregate
113809500fcSDimitry Andric };
114809500fcSDimitry Andric 
115bab175ecSDimitry Andric #define LIST_SANITIZER_CHECKS                                                  \
116bab175ecSDimitry Andric   SANITIZER_CHECK(AddOverflow, add_overflow, 0)                                \
117bab175ecSDimitry Andric   SANITIZER_CHECK(BuiltinUnreachable, builtin_unreachable, 0)                  \
118bab175ecSDimitry Andric   SANITIZER_CHECK(CFICheckFail, cfi_check_fail, 0)                             \
119bab175ecSDimitry Andric   SANITIZER_CHECK(DivremOverflow, divrem_overflow, 0)                          \
120bab175ecSDimitry Andric   SANITIZER_CHECK(DynamicTypeCacheMiss, dynamic_type_cache_miss, 0)            \
121bab175ecSDimitry Andric   SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0)                   \
1227fa27ce4SDimitry Andric   SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 0)             \
123c7e70c43SDimitry Andric   SANITIZER_CHECK(ImplicitConversion, implicit_conversion, 0)                  \
124461a67faSDimitry Andric   SANITIZER_CHECK(InvalidBuiltin, invalid_builtin, 0)                          \
125cfca06d7SDimitry Andric   SANITIZER_CHECK(InvalidObjCCast, invalid_objc_cast, 0)                       \
126bab175ecSDimitry Andric   SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0)                     \
127bab175ecSDimitry Andric   SANITIZER_CHECK(MissingReturn, missing_return, 0)                            \
128bab175ecSDimitry Andric   SANITIZER_CHECK(MulOverflow, mul_overflow, 0)                                \
129bab175ecSDimitry Andric   SANITIZER_CHECK(NegateOverflow, negate_overflow, 0)                          \
1307442d6faSDimitry Andric   SANITIZER_CHECK(NullabilityArg, nullability_arg, 0)                          \
131ef915aabSDimitry Andric   SANITIZER_CHECK(NullabilityReturn, nullability_return, 1)                    \
132bab175ecSDimitry Andric   SANITIZER_CHECK(NonnullArg, nonnull_arg, 0)                                  \
133ef915aabSDimitry Andric   SANITIZER_CHECK(NonnullReturn, nonnull_return, 1)                            \
134bab175ecSDimitry Andric   SANITIZER_CHECK(OutOfBounds, out_of_bounds, 0)                               \
135416ada0fSDimitry Andric   SANITIZER_CHECK(PointerOverflow, pointer_overflow, 0)                        \
136bab175ecSDimitry Andric   SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0)                    \
137bab175ecSDimitry Andric   SANITIZER_CHECK(SubOverflow, sub_overflow, 0)                                \
1386694ed09SDimitry Andric   SANITIZER_CHECK(TypeMismatch, type_mismatch, 1)                              \
139676fbe81SDimitry Andric   SANITIZER_CHECK(AlignmentAssumption, alignment_assumption, 0)                \
140ac9a064cSDimitry Andric   SANITIZER_CHECK(VLABoundNotPositive, vla_bound_not_positive, 0)              \
141ac9a064cSDimitry Andric   SANITIZER_CHECK(BoundsSafety, bounds_safety, 0)
142bab175ecSDimitry Andric 
143bab175ecSDimitry Andric enum SanitizerHandler {
144bab175ecSDimitry Andric #define SANITIZER_CHECK(Enum, Name, Version) Enum,
145bab175ecSDimitry Andric   LIST_SANITIZER_CHECKS
146bab175ecSDimitry Andric #undef SANITIZER_CHECK
147bab175ecSDimitry Andric };
148bab175ecSDimitry Andric 
14948675466SDimitry Andric /// Helper class with most of the code for saving a value for a
15048675466SDimitry Andric /// conditional expression cleanup.
15148675466SDimitry Andric struct DominatingLLVMValue {
15248675466SDimitry Andric   typedef llvm::PointerIntPair<llvm::Value*, 1, bool> saved_type;
15348675466SDimitry Andric 
15448675466SDimitry Andric   /// Answer whether the given value needs extra work to be saved.
needsSavingDominatingLLVMValue15548675466SDimitry Andric   static bool needsSaving(llvm::Value *value) {
156ac9a064cSDimitry Andric     if (!value)
157ac9a064cSDimitry Andric       return false;
158ac9a064cSDimitry Andric 
15948675466SDimitry Andric     // If it's not an instruction, we don't need to save.
16048675466SDimitry Andric     if (!isa<llvm::Instruction>(value)) return false;
16148675466SDimitry Andric 
16248675466SDimitry Andric     // If it's an instruction in the entry block, we don't need to save.
16348675466SDimitry Andric     llvm::BasicBlock *block = cast<llvm::Instruction>(value)->getParent();
16448675466SDimitry Andric     return (block != &block->getParent()->getEntryBlock());
16548675466SDimitry Andric   }
16648675466SDimitry Andric 
16748675466SDimitry Andric   static saved_type save(CodeGenFunction &CGF, llvm::Value *value);
16848675466SDimitry Andric   static llvm::Value *restore(CodeGenFunction &CGF, saved_type value);
16948675466SDimitry Andric };
17048675466SDimitry Andric 
17148675466SDimitry Andric /// A partial specialization of DominatingValue for llvm::Values that
17248675466SDimitry Andric /// might be llvm::Instructions.
17348675466SDimitry Andric template <class T> struct DominatingPointer<T,true> : DominatingLLVMValue {
17448675466SDimitry Andric   typedef T *type;
17548675466SDimitry Andric   static type restore(CodeGenFunction &CGF, saved_type value) {
17648675466SDimitry Andric     return static_cast<T*>(DominatingLLVMValue::restore(CGF, value));
17748675466SDimitry Andric   }
17848675466SDimitry Andric };
17948675466SDimitry Andric 
18048675466SDimitry Andric /// A specialization of DominatingValue for Address.
18148675466SDimitry Andric template <> struct DominatingValue<Address> {
18248675466SDimitry Andric   typedef Address type;
18348675466SDimitry Andric 
18448675466SDimitry Andric   struct saved_type {
185ac9a064cSDimitry Andric     DominatingLLVMValue::saved_type BasePtr;
1866f8fc217SDimitry Andric     llvm::Type *ElementType;
18748675466SDimitry Andric     CharUnits Alignment;
188ac9a064cSDimitry Andric     DominatingLLVMValue::saved_type Offset;
189ac9a064cSDimitry Andric     llvm::PointerType *EffectiveType;
19048675466SDimitry Andric   };
19148675466SDimitry Andric 
19248675466SDimitry Andric   static bool needsSaving(type value) {
193ac9a064cSDimitry Andric     if (DominatingLLVMValue::needsSaving(value.getBasePointer()) ||
194ac9a064cSDimitry Andric         DominatingLLVMValue::needsSaving(value.getOffset()))
195ac9a064cSDimitry Andric       return true;
196ac9a064cSDimitry Andric     return false;
19748675466SDimitry Andric   }
19848675466SDimitry Andric   static saved_type save(CodeGenFunction &CGF, type value) {
199ac9a064cSDimitry Andric     return {DominatingLLVMValue::save(CGF, value.getBasePointer()),
200ac9a064cSDimitry Andric             value.getElementType(), value.getAlignment(),
201ac9a064cSDimitry Andric             DominatingLLVMValue::save(CGF, value.getOffset()), value.getType()};
20248675466SDimitry Andric   }
20348675466SDimitry Andric   static type restore(CodeGenFunction &CGF, saved_type value) {
204ac9a064cSDimitry Andric     return Address(DominatingLLVMValue::restore(CGF, value.BasePtr),
205ac9a064cSDimitry Andric                    value.ElementType, value.Alignment, CGPointerAuthInfo(),
206ac9a064cSDimitry Andric                    DominatingLLVMValue::restore(CGF, value.Offset));
20748675466SDimitry Andric   }
20848675466SDimitry Andric };
20948675466SDimitry Andric 
21048675466SDimitry Andric /// A specialization of DominatingValue for RValue.
21148675466SDimitry Andric template <> struct DominatingValue<RValue> {
21248675466SDimitry Andric   typedef RValue type;
21348675466SDimitry Andric   class saved_type {
21448675466SDimitry Andric     enum Kind { ScalarLiteral, ScalarAddress, AggregateLiteral,
21548675466SDimitry Andric                 AggregateAddress, ComplexAddress };
216ac9a064cSDimitry Andric     union {
217ac9a064cSDimitry Andric       struct {
218ac9a064cSDimitry Andric         DominatingLLVMValue::saved_type first, second;
219ac9a064cSDimitry Andric       } Vals;
220ac9a064cSDimitry Andric       DominatingValue<Address>::saved_type AggregateAddr;
221ac9a064cSDimitry Andric     };
222ac9a064cSDimitry Andric     LLVM_PREFERRED_TYPE(Kind)
22348675466SDimitry Andric     unsigned K : 3;
224ac9a064cSDimitry Andric 
225ac9a064cSDimitry Andric     saved_type(DominatingLLVMValue::saved_type Val1, unsigned K)
226ac9a064cSDimitry Andric         : Vals{Val1, DominatingLLVMValue::saved_type()}, K(K) {}
227ac9a064cSDimitry Andric 
228ac9a064cSDimitry Andric     saved_type(DominatingLLVMValue::saved_type Val1,
229ac9a064cSDimitry Andric                DominatingLLVMValue::saved_type Val2)
230ac9a064cSDimitry Andric         : Vals{Val1, Val2}, K(ComplexAddress) {}
231ac9a064cSDimitry Andric 
232ac9a064cSDimitry Andric     saved_type(DominatingValue<Address>::saved_type AggregateAddr, unsigned K)
233ac9a064cSDimitry Andric         : AggregateAddr(AggregateAddr), K(K) {}
23448675466SDimitry Andric 
23548675466SDimitry Andric   public:
23648675466SDimitry Andric     static bool needsSaving(RValue value);
23748675466SDimitry Andric     static saved_type save(CodeGenFunction &CGF, RValue value);
23848675466SDimitry Andric     RValue restore(CodeGenFunction &CGF);
23948675466SDimitry Andric 
24048675466SDimitry Andric     // implementations in CGCleanup.cpp
24148675466SDimitry Andric   };
24248675466SDimitry Andric 
24348675466SDimitry Andric   static bool needsSaving(type value) {
24448675466SDimitry Andric     return saved_type::needsSaving(value);
24548675466SDimitry Andric   }
24648675466SDimitry Andric   static saved_type save(CodeGenFunction &CGF, type value) {
24748675466SDimitry Andric     return saved_type::save(CGF, value);
24848675466SDimitry Andric   }
24948675466SDimitry Andric   static type restore(CodeGenFunction &CGF, saved_type value) {
25048675466SDimitry Andric     return value.restore(CGF);
25148675466SDimitry Andric   }
25248675466SDimitry Andric };
25348675466SDimitry Andric 
254ec2b103cSEd Schouten /// CodeGenFunction - This class organizes the per-function state that is used
255ec2b103cSEd Schouten /// while generating LLVM code.
256bca07a45SDimitry Andric class CodeGenFunction : public CodeGenTypeCache {
2575e20cdd8SDimitry Andric   CodeGenFunction(const CodeGenFunction &) = delete;
2585e20cdd8SDimitry Andric   void operator=(const CodeGenFunction &) = delete;
2594ba67500SRoman Divacky 
2603d1dcd9bSDimitry Andric   friend class CGCXXABI;
2613d1dcd9bSDimitry Andric public:
2623d1dcd9bSDimitry Andric   /// A jump destination is an abstract label, branching to which may
2633d1dcd9bSDimitry Andric   /// require a jump out through normal cleanups.
2643d1dcd9bSDimitry Andric   struct JumpDest {
2656f8fc217SDimitry Andric     JumpDest() : Block(nullptr), Index(0) {}
2666f8fc217SDimitry Andric     JumpDest(llvm::BasicBlock *Block, EHScopeStack::stable_iterator Depth,
2673d1dcd9bSDimitry Andric              unsigned Index)
2683d1dcd9bSDimitry Andric         : Block(Block), ScopeDepth(Depth), Index(Index) {}
2693d1dcd9bSDimitry Andric 
2709f4dbff6SDimitry Andric     bool isValid() const { return Block != nullptr; }
2713d1dcd9bSDimitry Andric     llvm::BasicBlock *getBlock() const { return Block; }
2723d1dcd9bSDimitry Andric     EHScopeStack::stable_iterator getScopeDepth() const { return ScopeDepth; }
2733d1dcd9bSDimitry Andric     unsigned getDestIndex() const { return Index; }
2743d1dcd9bSDimitry Andric 
275809500fcSDimitry Andric     // This should be used cautiously.
276809500fcSDimitry Andric     void setScopeDepth(EHScopeStack::stable_iterator depth) {
277809500fcSDimitry Andric       ScopeDepth = depth;
278809500fcSDimitry Andric     }
279809500fcSDimitry Andric 
2803d1dcd9bSDimitry Andric   private:
2814ba67500SRoman Divacky     llvm::BasicBlock *Block;
2824ba67500SRoman Divacky     EHScopeStack::stable_iterator ScopeDepth;
2833d1dcd9bSDimitry Andric     unsigned Index;
2843d1dcd9bSDimitry Andric   };
2853d1dcd9bSDimitry Andric 
286ec2b103cSEd Schouten   CodeGenModule &CGM;  // Per-module state.
287b3d5a323SRoman Divacky   const TargetInfo &Target;
288ec2b103cSEd Schouten 
289cfca06d7SDimitry Andric   // For EH/SEH outlined funclets, this field points to parent's CGF
290cfca06d7SDimitry Andric   CodeGenFunction *ParentCGF = nullptr;
291cfca06d7SDimitry Andric 
292ec2b103cSEd Schouten   typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
2939f4dbff6SDimitry Andric   LoopInfoStack LoopStack;
294ec2b103cSEd Schouten   CGBuilderTy Builder;
295ec2b103cSEd Schouten 
296bab175ecSDimitry Andric   // Stores variables for which we can't generate correct lifetime markers
297bab175ecSDimitry Andric   // because of jumps.
298bab175ecSDimitry Andric   VarBypassDetector Bypasses;
299bab175ecSDimitry Andric 
300344a3780SDimitry Andric   /// List of recently emitted OMPCanonicalLoops.
301344a3780SDimitry Andric   ///
302344a3780SDimitry Andric   /// Since OMPCanonicalLoops are nested inside other statements (in particular
303344a3780SDimitry Andric   /// CapturedStmt generated by OMPExecutableDirective and non-perfectly nested
304344a3780SDimitry Andric   /// loops), we cannot directly call OMPEmitOMPCanonicalLoop and receive its
305344a3780SDimitry Andric   /// llvm::CanonicalLoopInfo. Instead, we call EmitStmt and any
306344a3780SDimitry Andric   /// OMPEmitOMPCanonicalLoop called by it will add its CanonicalLoopInfo to
307344a3780SDimitry Andric   /// this stack when done. Entering a new loop requires clearing this list; it
308344a3780SDimitry Andric   /// either means we start parsing a new loop nest (in which case the previous
309344a3780SDimitry Andric   /// loop nest goes out of scope) or a second loop in the same level in which
310344a3780SDimitry Andric   /// case it would be ambiguous into which of the two (or more) loops the loop
311344a3780SDimitry Andric   /// nest would extend.
312344a3780SDimitry Andric   SmallVector<llvm::CanonicalLoopInfo *, 4> OMPLoopNestStack;
313344a3780SDimitry Andric 
314aca2e42cSDimitry Andric   /// Stack to track the Logical Operator recursion nest for MC/DC.
315aca2e42cSDimitry Andric   SmallVector<const BinaryOperator *, 16> MCDCLogOpStack;
316aca2e42cSDimitry Andric 
317ac9a064cSDimitry Andric   /// Stack to track the controlled convergence tokens.
318ac9a064cSDimitry Andric   SmallVector<llvm::IntrinsicInst *, 4> ConvergenceTokenStack;
319ac9a064cSDimitry Andric 
320c0981da4SDimitry Andric   /// Number of nested loop to be consumed by the last surrounding
321c0981da4SDimitry Andric   /// loop-associated directive.
322c0981da4SDimitry Andric   int ExpectedOMPLoopDepth = 0;
323c0981da4SDimitry Andric 
324f0c55418SDimitry Andric   // CodeGen lambda for loops and support for ordered clause
325f0c55418SDimitry Andric   typedef llvm::function_ref<void(CodeGenFunction &, const OMPLoopDirective &,
326f0c55418SDimitry Andric                                   JumpDest)>
327f0c55418SDimitry Andric       CodeGenLoopTy;
328f0c55418SDimitry Andric   typedef llvm::function_ref<void(CodeGenFunction &, SourceLocation,
329f0c55418SDimitry Andric                                   const unsigned, const bool)>
330f0c55418SDimitry Andric       CodeGenOrderedTy;
331f0c55418SDimitry Andric 
332f0c55418SDimitry Andric   // Codegen lambda for loop bounds in worksharing loop constructs
333f0c55418SDimitry Andric   typedef llvm::function_ref<std::pair<LValue, LValue>(
334f0c55418SDimitry Andric       CodeGenFunction &, const OMPExecutableDirective &S)>
335f0c55418SDimitry Andric       CodeGenLoopBoundsTy;
336f0c55418SDimitry Andric 
337f0c55418SDimitry Andric   // Codegen lambda for loop bounds in dispatch-based loop implementation
338f0c55418SDimitry Andric   typedef llvm::function_ref<std::pair<llvm::Value *, llvm::Value *>(
339f0c55418SDimitry Andric       CodeGenFunction &, const OMPExecutableDirective &S, Address LB,
340f0c55418SDimitry Andric       Address UB)>
341f0c55418SDimitry Andric       CodeGenDispatchBoundsTy;
342f0c55418SDimitry Andric 
34348675466SDimitry Andric   /// CGBuilder insert helper. This function is called after an
3449f4dbff6SDimitry Andric   /// instruction is created using Builder.
3459f4dbff6SDimitry Andric   void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
3469f4dbff6SDimitry Andric                     llvm::BasicBlock::iterator InsertPt) const;
3479f4dbff6SDimitry Andric 
3486a037251SDimitry Andric   /// CurFuncDecl - Holds the Decl for the current outermost
3496a037251SDimitry Andric   /// non-closure context.
3507fa27ce4SDimitry Andric   const Decl *CurFuncDecl = nullptr;
351ec2b103cSEd Schouten   /// CurCodeDecl - This is the inner-most code context, which includes blocks.
3527fa27ce4SDimitry Andric   const Decl *CurCodeDecl = nullptr;
3537fa27ce4SDimitry Andric   const CGFunctionInfo *CurFnInfo = nullptr;
354ec2b103cSEd Schouten   QualType FnRetTy;
35548675466SDimitry Andric   llvm::Function *CurFn = nullptr;
356ec2b103cSEd Schouten 
357344a3780SDimitry Andric   /// Save Parameter Decl for coroutine.
358344a3780SDimitry Andric   llvm::SmallVector<const ParmVarDecl *, 4> FnArgs;
359344a3780SDimitry Andric 
360bab175ecSDimitry Andric   // Holds coroutine data if the current function is a coroutine. We use a
361bab175ecSDimitry Andric   // wrapper to manage its lifetime, so that we don't have to define CGCoroData
362bab175ecSDimitry Andric   // in this header.
363bab175ecSDimitry Andric   struct CGCoroInfo {
364bab175ecSDimitry Andric     std::unique_ptr<CGCoroData> Data;
3657fa27ce4SDimitry Andric     bool InSuspendBlock = false;
366bab175ecSDimitry Andric     CGCoroInfo();
367bab175ecSDimitry Andric     ~CGCoroInfo();
368bab175ecSDimitry Andric   };
369bab175ecSDimitry Andric   CGCoroInfo CurCoro;
370bab175ecSDimitry Andric 
371461a67faSDimitry Andric   bool isCoroutine() const {
372461a67faSDimitry Andric     return CurCoro.Data != nullptr;
373461a67faSDimitry Andric   }
374461a67faSDimitry Andric 
3757fa27ce4SDimitry Andric   bool inSuspendBlock() const {
3767fa27ce4SDimitry Andric     return isCoroutine() && CurCoro.InSuspendBlock;
3777fa27ce4SDimitry Andric   }
3787fa27ce4SDimitry Andric 
379ac9a064cSDimitry Andric   // Holds FramePtr for await_suspend wrapper generation,
380ac9a064cSDimitry Andric   // so that __builtin_coro_frame call can be lowered
381ac9a064cSDimitry Andric   // directly to value of its second argument
382ac9a064cSDimitry Andric   struct AwaitSuspendWrapperInfo {
383ac9a064cSDimitry Andric     llvm::Value *FramePtr = nullptr;
384ac9a064cSDimitry Andric   };
385ac9a064cSDimitry Andric   AwaitSuspendWrapperInfo CurAwaitSuspendWrapper;
386ac9a064cSDimitry Andric 
387ac9a064cSDimitry Andric   // Generates wrapper function for `llvm.coro.await.suspend.*` intrinisics.
388ac9a064cSDimitry Andric   // It encapsulates SuspendExpr in a function, to separate it's body
389ac9a064cSDimitry Andric   // from the main coroutine to avoid miscompilations. Intrinisic
390ac9a064cSDimitry Andric   // is lowered to this function call in CoroSplit pass
391ac9a064cSDimitry Andric   // Function signature is:
392ac9a064cSDimitry Andric   // <type> __await_suspend_wrapper_<name>(ptr %awaiter, ptr %hdl)
393ac9a064cSDimitry Andric   // where type is one of (void, i1, ptr)
394ac9a064cSDimitry Andric   llvm::Function *generateAwaitSuspendWrapper(Twine const &CoroName,
395ac9a064cSDimitry Andric                                               Twine const &SuspendPointName,
396ac9a064cSDimitry Andric                                               CoroutineSuspendExpr const &S);
397ac9a064cSDimitry Andric 
39834d02d0bSRoman Divacky   /// CurGD - The GlobalDecl for the current function being compiled.
39934d02d0bSRoman Divacky   GlobalDecl CurGD;
40034d02d0bSRoman Divacky 
401180abc3dSDimitry Andric   /// PrologueCleanupDepth - The cleanup depth enclosing all the
402180abc3dSDimitry Andric   /// cleanups associated with the parameters.
403180abc3dSDimitry Andric   EHScopeStack::stable_iterator PrologueCleanupDepth;
404180abc3dSDimitry Andric 
405ec2b103cSEd Schouten   /// ReturnBlock - Unified return block.
4064ba67500SRoman Divacky   JumpDest ReturnBlock;
4074ba67500SRoman Divacky 
40845b53394SDimitry Andric   /// ReturnValue - The temporary alloca to hold the return
40945b53394SDimitry Andric   /// value. This is invalid iff the function has no return value.
41048675466SDimitry Andric   Address ReturnValue = Address::invalid();
411ec2b103cSEd Schouten 
41222989816SDimitry Andric   /// ReturnValuePointer - The temporary alloca to hold a pointer to sret.
41322989816SDimitry Andric   /// This is invalid if sret is not in use.
41422989816SDimitry Andric   Address ReturnValuePointer = Address::invalid();
41522989816SDimitry Andric 
416cfca06d7SDimitry Andric   /// If a return statement is being visited, this holds the return statment's
417cfca06d7SDimitry Andric   /// result expression.
418cfca06d7SDimitry Andric   const Expr *RetExpr = nullptr;
419cfca06d7SDimitry Andric 
4207442d6faSDimitry Andric   /// Return true if a label was seen in the current scope.
4217442d6faSDimitry Andric   bool hasLabelBeenSeenInCurrentScope() const {
4227442d6faSDimitry Andric     if (CurLexicalScope)
4237442d6faSDimitry Andric       return CurLexicalScope->hasLabels();
4247442d6faSDimitry Andric     return !LabelMap.empty();
4257442d6faSDimitry Andric   }
4267442d6faSDimitry Andric 
427ec2b103cSEd Schouten   /// AllocaInsertPoint - This is an instruction in the entry block before which
428ec2b103cSEd Schouten   /// we prefer to insert allocas.
429ec2b103cSEd Schouten   llvm::AssertingVH<llvm::Instruction> AllocaInsertPt;
430ec2b103cSEd Schouten 
431c0981da4SDimitry Andric private:
432c0981da4SDimitry Andric   /// PostAllocaInsertPt - This is a place in the prologue where code can be
433c0981da4SDimitry Andric   /// inserted that will be dominated by all the static allocas. This helps
434c0981da4SDimitry Andric   /// achieve two things:
435c0981da4SDimitry Andric   ///   1. Contiguity of all static allocas (within the prologue) is maintained.
436c0981da4SDimitry Andric   ///   2. All other prologue code (which are dominated by static allocas) do
437c0981da4SDimitry Andric   ///      appear in the source order immediately after all static allocas.
438c0981da4SDimitry Andric   ///
439c0981da4SDimitry Andric   /// PostAllocaInsertPt will be lazily created when it is *really* required.
440c0981da4SDimitry Andric   llvm::AssertingVH<llvm::Instruction> PostAllocaInsertPt = nullptr;
441c0981da4SDimitry Andric 
442c0981da4SDimitry Andric public:
443c0981da4SDimitry Andric   /// Return PostAllocaInsertPt. If it is not yet created, then insert it
444c0981da4SDimitry Andric   /// immediately after AllocaInsertPt.
445c0981da4SDimitry Andric   llvm::Instruction *getPostAllocaInsertPoint() {
446c0981da4SDimitry Andric     if (!PostAllocaInsertPt) {
447c0981da4SDimitry Andric       assert(AllocaInsertPt &&
448c0981da4SDimitry Andric              "Expected static alloca insertion point at function prologue");
449c0981da4SDimitry Andric       assert(AllocaInsertPt->getParent()->isEntryBlock() &&
450c0981da4SDimitry Andric              "EBB should be entry block of the current code gen function");
451c0981da4SDimitry Andric       PostAllocaInsertPt = AllocaInsertPt->clone();
452c0981da4SDimitry Andric       PostAllocaInsertPt->setName("postallocapt");
453c0981da4SDimitry Andric       PostAllocaInsertPt->insertAfter(AllocaInsertPt);
454c0981da4SDimitry Andric     }
455c0981da4SDimitry Andric 
456c0981da4SDimitry Andric     return PostAllocaInsertPt;
457c0981da4SDimitry Andric   }
458c0981da4SDimitry Andric 
45948675466SDimitry Andric   /// API for captured statement code generation.
460bfef3995SDimitry Andric   class CGCapturedStmtInfo {
461bfef3995SDimitry Andric   public:
46206d4ba38SDimitry Andric     explicit CGCapturedStmtInfo(CapturedRegionKind K = CR_Default)
46306d4ba38SDimitry Andric         : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {}
464bfef3995SDimitry Andric     explicit CGCapturedStmtInfo(const CapturedStmt &S,
465bfef3995SDimitry Andric                                 CapturedRegionKind K = CR_Default)
4669f4dbff6SDimitry Andric       : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {
467bfef3995SDimitry Andric 
468bfef3995SDimitry Andric       RecordDecl::field_iterator Field =
469bfef3995SDimitry Andric         S.getCapturedRecordDecl()->field_begin();
470bfef3995SDimitry Andric       for (CapturedStmt::const_capture_iterator I = S.capture_begin(),
471bfef3995SDimitry Andric                                                 E = S.capture_end();
472bfef3995SDimitry Andric            I != E; ++I, ++Field) {
473bfef3995SDimitry Andric         if (I->capturesThis())
474bfef3995SDimitry Andric           CXXThisFieldDecl = *Field;
47506d4ba38SDimitry Andric         else if (I->capturesVariable())
476461a67faSDimitry Andric           CaptureFields[I->getCapturedVar()->getCanonicalDecl()] = *Field;
4772b6b257fSDimitry Andric         else if (I->capturesVariableByCopy())
478461a67faSDimitry Andric           CaptureFields[I->getCapturedVar()->getCanonicalDecl()] = *Field;
479bfef3995SDimitry Andric       }
480bfef3995SDimitry Andric     }
481bfef3995SDimitry Andric 
482bfef3995SDimitry Andric     virtual ~CGCapturedStmtInfo();
483bfef3995SDimitry Andric 
484bfef3995SDimitry Andric     CapturedRegionKind getKind() const { return Kind; }
485bfef3995SDimitry Andric 
4865e20cdd8SDimitry Andric     virtual void setContextValue(llvm::Value *V) { ThisValue = V; }
48748675466SDimitry Andric     // Retrieve the value of the context parameter.
4885e20cdd8SDimitry Andric     virtual llvm::Value *getContextValue() const { return ThisValue; }
489bfef3995SDimitry Andric 
49048675466SDimitry Andric     /// Lookup the captured field decl for a variable.
4915e20cdd8SDimitry Andric     virtual const FieldDecl *lookup(const VarDecl *VD) const {
492461a67faSDimitry Andric       return CaptureFields.lookup(VD->getCanonicalDecl());
493bfef3995SDimitry Andric     }
494bfef3995SDimitry Andric 
4955e20cdd8SDimitry Andric     bool isCXXThisExprCaptured() const { return getThisFieldDecl() != nullptr; }
4965e20cdd8SDimitry Andric     virtual FieldDecl *getThisFieldDecl() const { return CXXThisFieldDecl; }
497bfef3995SDimitry Andric 
49806d4ba38SDimitry Andric     static bool classof(const CGCapturedStmtInfo *) {
49906d4ba38SDimitry Andric       return true;
50006d4ba38SDimitry Andric     }
50106d4ba38SDimitry Andric 
50248675466SDimitry Andric     /// Emit the captured statement body.
5035e20cdd8SDimitry Andric     virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S) {
5045e20cdd8SDimitry Andric       CGF.incrementProfileCounter(S);
505bfef3995SDimitry Andric       CGF.EmitStmt(S);
506bfef3995SDimitry Andric     }
507bfef3995SDimitry Andric 
50848675466SDimitry Andric     /// Get the name of the capture helper.
509bfef3995SDimitry Andric     virtual StringRef getHelperName() const { return "__captured_stmt"; }
510bfef3995SDimitry Andric 
51177fc4c14SDimitry Andric     /// Get the CaptureFields
51277fc4c14SDimitry Andric     llvm::SmallDenseMap<const VarDecl *, FieldDecl *> getCaptureFields() {
51377fc4c14SDimitry Andric       return CaptureFields;
51477fc4c14SDimitry Andric     }
51577fc4c14SDimitry Andric 
516bfef3995SDimitry Andric   private:
51748675466SDimitry Andric     /// The kind of captured statement being generated.
518bfef3995SDimitry Andric     CapturedRegionKind Kind;
519bfef3995SDimitry Andric 
52048675466SDimitry Andric     /// Keep the map between VarDecl and FieldDecl.
521bfef3995SDimitry Andric     llvm::SmallDenseMap<const VarDecl *, FieldDecl *> CaptureFields;
522bfef3995SDimitry Andric 
52348675466SDimitry Andric     /// The base address of the captured record, passed in as the first
524bfef3995SDimitry Andric     /// argument of the parallel region function.
525bfef3995SDimitry Andric     llvm::Value *ThisValue;
526bfef3995SDimitry Andric 
52748675466SDimitry Andric     /// Captured 'this' type.
528bfef3995SDimitry Andric     FieldDecl *CXXThisFieldDecl;
529bfef3995SDimitry Andric   };
53048675466SDimitry Andric   CGCapturedStmtInfo *CapturedStmtInfo = nullptr;
531bfef3995SDimitry Andric 
53248675466SDimitry Andric   /// RAII for correct setting/restoring of CapturedStmtInfo.
533c192b3dcSDimitry Andric   class CGCapturedStmtRAII {
534c192b3dcSDimitry Andric   private:
535c192b3dcSDimitry Andric     CodeGenFunction &CGF;
536c192b3dcSDimitry Andric     CGCapturedStmtInfo *PrevCapturedStmtInfo;
537c192b3dcSDimitry Andric   public:
538c192b3dcSDimitry Andric     CGCapturedStmtRAII(CodeGenFunction &CGF,
539c192b3dcSDimitry Andric                        CGCapturedStmtInfo *NewCapturedStmtInfo)
540c192b3dcSDimitry Andric         : CGF(CGF), PrevCapturedStmtInfo(CGF.CapturedStmtInfo) {
541c192b3dcSDimitry Andric       CGF.CapturedStmtInfo = NewCapturedStmtInfo;
542c192b3dcSDimitry Andric     }
543c192b3dcSDimitry Andric     ~CGCapturedStmtRAII() { CGF.CapturedStmtInfo = PrevCapturedStmtInfo; }
544c192b3dcSDimitry Andric   };
545c192b3dcSDimitry Andric 
5467442d6faSDimitry Andric   /// An abstract representation of regular/ObjC call/message targets.
5477442d6faSDimitry Andric   class AbstractCallee {
5487442d6faSDimitry Andric     /// The function declaration of the callee.
5497442d6faSDimitry Andric     const Decl *CalleeDecl;
5507442d6faSDimitry Andric 
5517442d6faSDimitry Andric   public:
5527442d6faSDimitry Andric     AbstractCallee() : CalleeDecl(nullptr) {}
5537442d6faSDimitry Andric     AbstractCallee(const FunctionDecl *FD) : CalleeDecl(FD) {}
5547442d6faSDimitry Andric     AbstractCallee(const ObjCMethodDecl *OMD) : CalleeDecl(OMD) {}
5557442d6faSDimitry Andric     bool hasFunctionDecl() const {
556c0981da4SDimitry Andric       return isa_and_nonnull<FunctionDecl>(CalleeDecl);
5577442d6faSDimitry Andric     }
5587442d6faSDimitry Andric     const Decl *getDecl() const { return CalleeDecl; }
5597442d6faSDimitry Andric     unsigned getNumParams() const {
5607442d6faSDimitry Andric       if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl))
5617442d6faSDimitry Andric         return FD->getNumParams();
5627442d6faSDimitry Andric       return cast<ObjCMethodDecl>(CalleeDecl)->param_size();
5637442d6faSDimitry Andric     }
5647442d6faSDimitry Andric     const ParmVarDecl *getParamDecl(unsigned I) const {
5657442d6faSDimitry Andric       if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl))
5667442d6faSDimitry Andric         return FD->getParamDecl(I);
5677442d6faSDimitry Andric       return *(cast<ObjCMethodDecl>(CalleeDecl)->param_begin() + I);
5687442d6faSDimitry Andric     }
5697442d6faSDimitry Andric   };
5707442d6faSDimitry Andric 
57148675466SDimitry Andric   /// Sanitizers enabled for this function.
57206d4ba38SDimitry Andric   SanitizerSet SanOpts;
573809500fcSDimitry Andric 
57448675466SDimitry Andric   /// True if CodeGen currently emits code implementing sanitizer checks.
57548675466SDimitry Andric   bool IsSanitizerScope = false;
5769f4dbff6SDimitry Andric 
57748675466SDimitry Andric   /// RAII object to set/unset CodeGenFunction::IsSanitizerScope.
5789f4dbff6SDimitry Andric   class SanitizerScope {
5799f4dbff6SDimitry Andric     CodeGenFunction *CGF;
5809f4dbff6SDimitry Andric   public:
5819f4dbff6SDimitry Andric     SanitizerScope(CodeGenFunction *CGF);
5829f4dbff6SDimitry Andric     ~SanitizerScope();
5839f4dbff6SDimitry Andric   };
5849f4dbff6SDimitry Andric 
58506d4ba38SDimitry Andric   /// In C++, whether we are code generating a thunk.  This controls whether we
58606d4ba38SDimitry Andric   /// should emit cleanups.
58748675466SDimitry Andric   bool CurFuncIsThunk = false;
58806d4ba38SDimitry Andric 
589180abc3dSDimitry Andric   /// In ARC, whether we should autorelease the return value.
59048675466SDimitry Andric   bool AutoreleaseResult = false;
591180abc3dSDimitry Andric 
59206d4ba38SDimitry Andric   /// Whether we processed a Microsoft-style asm block during CodeGen. These can
59306d4ba38SDimitry Andric   /// potentially set the return value.
59448675466SDimitry Andric   bool SawAsmBlock = false;
59506d4ba38SDimitry Andric 
596e3b55780SDimitry Andric   GlobalDecl CurSEHParent;
5972b6b257fSDimitry Andric 
5985e20cdd8SDimitry Andric   /// True if the current function is an outlined SEH helper. This can be a
5995e20cdd8SDimitry Andric   /// finally block or filter expression.
60048675466SDimitry Andric   bool IsOutlinedSEHHelper = false;
6015e20cdd8SDimitry Andric 
60222989816SDimitry Andric   /// True if CodeGen currently emits code inside presereved access index
60322989816SDimitry Andric   /// region.
60422989816SDimitry Andric   bool IsInPreservedAIRegion = false;
60522989816SDimitry Andric 
606cfca06d7SDimitry Andric   /// True if the current statement has nomerge attribute.
607cfca06d7SDimitry Andric   bool InNoMergeAttributedStmt = false;
608cfca06d7SDimitry Andric 
609145449b1SDimitry Andric   /// True if the current statement has noinline attribute.
610145449b1SDimitry Andric   bool InNoInlineAttributedStmt = false;
611145449b1SDimitry Andric 
612145449b1SDimitry Andric   /// True if the current statement has always_inline attribute.
613145449b1SDimitry Andric   bool InAlwaysInlineAttributedStmt = false;
614145449b1SDimitry Andric 
615344a3780SDimitry Andric   // The CallExpr within the current statement that the musttail attribute
616344a3780SDimitry Andric   // applies to.  nullptr if there is no 'musttail' on the current statement.
617344a3780SDimitry Andric   const CallExpr *MustTailCall = nullptr;
618b60736ecSDimitry Andric 
619344a3780SDimitry Andric   /// Returns true if a function must make progress, which means the
620344a3780SDimitry Andric   /// mustprogress attribute can be added.
621344a3780SDimitry Andric   bool checkIfFunctionMustProgress() {
622344a3780SDimitry Andric     if (CGM.getCodeGenOpts().getFiniteLoops() ==
623344a3780SDimitry Andric         CodeGenOptions::FiniteLoopsKind::Never)
624344a3780SDimitry Andric       return false;
625344a3780SDimitry Andric 
626344a3780SDimitry Andric     // C++11 and later guarantees that a thread eventually will do one of the
627e3b55780SDimitry Andric     // following (C++11 [intro.multithread]p24 and C++17 [intro.progress]p1):
628344a3780SDimitry Andric     // - terminate,
629344a3780SDimitry Andric     //  - make a call to a library I/O function,
630344a3780SDimitry Andric     //  - perform an access through a volatile glvalue, or
631344a3780SDimitry Andric     //  - perform a synchronization operation or an atomic operation.
632344a3780SDimitry Andric     //
633344a3780SDimitry Andric     // Hence each function is 'mustprogress' in C++11 or later.
634344a3780SDimitry Andric     return getLangOpts().CPlusPlus11;
635b60736ecSDimitry Andric   }
636b60736ecSDimitry Andric 
637344a3780SDimitry Andric   /// Returns true if a loop must make progress, which means the mustprogress
638344a3780SDimitry Andric   /// attribute can be added. \p HasConstantCond indicates whether the branch
639344a3780SDimitry Andric   /// condition is a known constant.
640ac9a064cSDimitry Andric   bool checkIfLoopMustProgress(const Expr *, bool HasEmptyBody);
641b60736ecSDimitry Andric 
64248675466SDimitry Andric   const CodeGen::CGBlockInfo *BlockInfo = nullptr;
64348675466SDimitry Andric   llvm::Value *BlockPointer = nullptr;
644bca07a45SDimitry Andric 
645e3b55780SDimitry Andric   llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
64648675466SDimitry Andric   FieldDecl *LambdaThisCaptureField = nullptr;
647dbe13110SDimitry Andric 
64848675466SDimitry Andric   /// A mapping from NRVO variables to the flags used to indicate
649d7279c4cSRoman Divacky   /// when the NRVO has been applied to this variable.
650d7279c4cSRoman Divacky   llvm::DenseMap<const VarDecl *, llvm::Value *> NRVOFlags;
651d7279c4cSRoman Divacky 
6524ba67500SRoman Divacky   EHScopeStack EHStack;
653bfef3995SDimitry Andric   llvm::SmallVector<char, 256> LifetimeExtendedCleanupStack;
654ac9a064cSDimitry Andric 
655ac9a064cSDimitry Andric   // A stack of cleanups which were added to EHStack but have to be deactivated
656ac9a064cSDimitry Andric   // later before being popped or emitted. These are usually deactivated on
657ac9a064cSDimitry Andric   // exiting a `CleanupDeactivationScope` scope. For instance, after a
658ac9a064cSDimitry Andric   // full-expr.
659ac9a064cSDimitry Andric   //
660ac9a064cSDimitry Andric   // These are specially useful for correctly emitting cleanups while
661ac9a064cSDimitry Andric   // encountering branches out of expression (through stmt-expr or coroutine
662ac9a064cSDimitry Andric   // suspensions).
663ac9a064cSDimitry Andric   struct DeferredDeactivateCleanup {
664ac9a064cSDimitry Andric     EHScopeStack::stable_iterator Cleanup;
665ac9a064cSDimitry Andric     llvm::Instruction *DominatingIP;
666ac9a064cSDimitry Andric   };
667ac9a064cSDimitry Andric   llvm::SmallVector<DeferredDeactivateCleanup> DeferredDeactivationCleanupStack;
668ac9a064cSDimitry Andric 
669ac9a064cSDimitry Andric   // Enters a new scope for capturing cleanups which are deferred to be
670ac9a064cSDimitry Andric   // deactivated, all of which will be deactivated once the scope is exited.
671ac9a064cSDimitry Andric   struct CleanupDeactivationScope {
672ac9a064cSDimitry Andric     CodeGenFunction &CGF;
673ac9a064cSDimitry Andric     size_t OldDeactivateCleanupStackSize;
674ac9a064cSDimitry Andric     bool Deactivated;
675ac9a064cSDimitry Andric     CleanupDeactivationScope(CodeGenFunction &CGF)
676ac9a064cSDimitry Andric         : CGF(CGF), OldDeactivateCleanupStackSize(
677ac9a064cSDimitry Andric                         CGF.DeferredDeactivationCleanupStack.size()),
678ac9a064cSDimitry Andric           Deactivated(false) {}
679ac9a064cSDimitry Andric 
680ac9a064cSDimitry Andric     void ForceDeactivate() {
681ac9a064cSDimitry Andric       assert(!Deactivated && "Deactivating already deactivated scope");
682ac9a064cSDimitry Andric       auto &Stack = CGF.DeferredDeactivationCleanupStack;
683ac9a064cSDimitry Andric       for (size_t I = Stack.size(); I > OldDeactivateCleanupStackSize; I--) {
684ac9a064cSDimitry Andric         CGF.DeactivateCleanupBlock(Stack[I - 1].Cleanup,
685ac9a064cSDimitry Andric                                    Stack[I - 1].DominatingIP);
686ac9a064cSDimitry Andric         Stack[I - 1].DominatingIP->eraseFromParent();
687ac9a064cSDimitry Andric       }
688ac9a064cSDimitry Andric       Stack.resize(OldDeactivateCleanupStackSize);
689ac9a064cSDimitry Andric       Deactivated = true;
690ac9a064cSDimitry Andric     }
691ac9a064cSDimitry Andric 
692ac9a064cSDimitry Andric     ~CleanupDeactivationScope() {
693ac9a064cSDimitry Andric       if (Deactivated)
694ac9a064cSDimitry Andric         return;
695ac9a064cSDimitry Andric       ForceDeactivate();
696ac9a064cSDimitry Andric     }
697ac9a064cSDimitry Andric   };
698ac9a064cSDimitry Andric 
6995e20cdd8SDimitry Andric   llvm::SmallVector<const JumpDest *, 2> SEHTryEpilogueStack;
700bfef3995SDimitry Andric 
70145b53394SDimitry Andric   llvm::Instruction *CurrentFuncletPad = nullptr;
70245b53394SDimitry Andric 
7032b6b257fSDimitry Andric   class CallLifetimeEnd final : public EHScopeStack::Cleanup {
704344a3780SDimitry Andric     bool isRedundantBeforeReturn() override { return true; }
705344a3780SDimitry Andric 
7062b6b257fSDimitry Andric     llvm::Value *Addr;
7072b6b257fSDimitry Andric     llvm::Value *Size;
7082b6b257fSDimitry Andric 
7092b6b257fSDimitry Andric   public:
710ac9a064cSDimitry Andric     CallLifetimeEnd(RawAddress addr, llvm::Value *size)
7112b6b257fSDimitry Andric         : Addr(addr.getPointer()), Size(size) {}
7122b6b257fSDimitry Andric 
7132b6b257fSDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
7142b6b257fSDimitry Andric       CGF.EmitLifetimeEnd(Size, Addr);
7152b6b257fSDimitry Andric     }
7162b6b257fSDimitry Andric   };
7172b6b257fSDimitry Andric 
718bfef3995SDimitry Andric   /// Header for data within LifetimeExtendedCleanupStack.
719bfef3995SDimitry Andric   struct LifetimeExtendedCleanupHeader {
720bfef3995SDimitry Andric     /// The size of the following cleanup object.
721c192b3dcSDimitry Andric     unsigned Size;
722ac9a064cSDimitry Andric     /// The kind of cleanup to push.
723ac9a064cSDimitry Andric     LLVM_PREFERRED_TYPE(CleanupKind)
72448675466SDimitry Andric     unsigned Kind : 31;
72548675466SDimitry Andric     /// Whether this is a conditional cleanup.
726ac9a064cSDimitry Andric     LLVM_PREFERRED_TYPE(bool)
72748675466SDimitry Andric     unsigned IsConditional : 1;
728bfef3995SDimitry Andric 
729c192b3dcSDimitry Andric     size_t getSize() const { return Size; }
73048675466SDimitry Andric     CleanupKind getKind() const { return (CleanupKind)Kind; }
73148675466SDimitry Andric     bool isConditional() const { return IsConditional; }
732bfef3995SDimitry Andric   };
7334ba67500SRoman Divacky 
7343d1dcd9bSDimitry Andric   /// i32s containing the indexes of the cleanup destinations.
735ac9a064cSDimitry Andric   RawAddress NormalCleanupDest = RawAddress::invalid();
7363d1dcd9bSDimitry Andric 
73748675466SDimitry Andric   unsigned NextCleanupDestIndex = 1;
7383d1dcd9bSDimitry Andric 
73936981b17SDimitry Andric   /// EHResumeBlock - Unified block containing a call to llvm.eh.resume.
74048675466SDimitry Andric   llvm::BasicBlock *EHResumeBlock = nullptr;
74136981b17SDimitry Andric 
74236981b17SDimitry Andric   /// The exception slot.  All landing pads write the current exception pointer
74336981b17SDimitry Andric   /// into this alloca.
74448675466SDimitry Andric   llvm::Value *ExceptionSlot = nullptr;
7454ba67500SRoman Divacky 
74636981b17SDimitry Andric   /// The selector slot.  Under the MandatoryCleanup model, all landing pads
74736981b17SDimitry Andric   /// write the current selector value into this alloca.
74848675466SDimitry Andric   llvm::AllocaInst *EHSelectorSlot = nullptr;
74929cafa66SDimitry Andric 
75051ece4aaSDimitry Andric   /// A stack of exception code slots. Entering an __except block pushes a slot
75151ece4aaSDimitry Andric   /// on the stack and leaving pops one. The __exception_code() intrinsic loads
75251ece4aaSDimitry Andric   /// a value from the top of the stack.
75345b53394SDimitry Andric   SmallVector<Address, 1> SEHCodeSlotStack;
7545e20cdd8SDimitry Andric 
75551ece4aaSDimitry Andric   /// Value returned by __exception_info intrinsic.
75651ece4aaSDimitry Andric   llvm::Value *SEHInfo = nullptr;
7575e20cdd8SDimitry Andric 
7584ba67500SRoman Divacky   /// Emits a landing pad for the current EH stack.
7594ba67500SRoman Divacky   llvm::BasicBlock *EmitLandingPad();
7604ba67500SRoman Divacky 
7614ba67500SRoman Divacky   llvm::BasicBlock *getInvokeDestImpl();
7624ba67500SRoman Divacky 
763cfca06d7SDimitry Andric   /// Parent loop-based directive for scan directive.
764cfca06d7SDimitry Andric   const OMPExecutableDirective *OMPParentLoopDirectiveForScan = nullptr;
765cfca06d7SDimitry Andric   llvm::BasicBlock *OMPBeforeScanBlock = nullptr;
766cfca06d7SDimitry Andric   llvm::BasicBlock *OMPAfterScanBlock = nullptr;
767cfca06d7SDimitry Andric   llvm::BasicBlock *OMPScanExitBlock = nullptr;
768cfca06d7SDimitry Andric   llvm::BasicBlock *OMPScanDispatch = nullptr;
769cfca06d7SDimitry Andric   bool OMPFirstScanLoop = false;
770cfca06d7SDimitry Andric 
771cfca06d7SDimitry Andric   /// Manages parent directive for scan directives.
772cfca06d7SDimitry Andric   class ParentLoopDirectiveForScanRegion {
773cfca06d7SDimitry Andric     CodeGenFunction &CGF;
774cfca06d7SDimitry Andric     const OMPExecutableDirective *ParentLoopDirectiveForScan;
775cfca06d7SDimitry Andric 
776cfca06d7SDimitry Andric   public:
777cfca06d7SDimitry Andric     ParentLoopDirectiveForScanRegion(
778cfca06d7SDimitry Andric         CodeGenFunction &CGF,
779cfca06d7SDimitry Andric         const OMPExecutableDirective &ParentLoopDirectiveForScan)
780cfca06d7SDimitry Andric         : CGF(CGF),
781cfca06d7SDimitry Andric           ParentLoopDirectiveForScan(CGF.OMPParentLoopDirectiveForScan) {
782cfca06d7SDimitry Andric       CGF.OMPParentLoopDirectiveForScan = &ParentLoopDirectiveForScan;
783cfca06d7SDimitry Andric     }
784cfca06d7SDimitry Andric     ~ParentLoopDirectiveForScanRegion() {
785cfca06d7SDimitry Andric       CGF.OMPParentLoopDirectiveForScan = ParentLoopDirectiveForScan;
786cfca06d7SDimitry Andric     }
787cfca06d7SDimitry Andric   };
788cfca06d7SDimitry Andric 
789bca07a45SDimitry Andric   template <class T>
790bca07a45SDimitry Andric   typename DominatingValue<T>::saved_type saveValueInCond(T value) {
791bca07a45SDimitry Andric     return DominatingValue<T>::save(*this, value);
792bca07a45SDimitry Andric   }
793bca07a45SDimitry Andric 
794cfca06d7SDimitry Andric   class CGFPOptionsRAII {
795cfca06d7SDimitry Andric   public:
796cfca06d7SDimitry Andric     CGFPOptionsRAII(CodeGenFunction &CGF, FPOptions FPFeatures);
797b60736ecSDimitry Andric     CGFPOptionsRAII(CodeGenFunction &CGF, const Expr *E);
798cfca06d7SDimitry Andric     ~CGFPOptionsRAII();
799cfca06d7SDimitry Andric 
800cfca06d7SDimitry Andric   private:
801b60736ecSDimitry Andric     void ConstructorHelper(FPOptions FPFeatures);
802cfca06d7SDimitry Andric     CodeGenFunction &CGF;
803cfca06d7SDimitry Andric     FPOptions OldFPFeatures;
804b60736ecSDimitry Andric     llvm::fp::ExceptionBehavior OldExcept;
805b60736ecSDimitry Andric     llvm::RoundingMode OldRounding;
806e3b55780SDimitry Andric     std::optional<CGBuilderTy::FastMathFlagGuard> FMFGuard;
807cfca06d7SDimitry Andric   };
808cfca06d7SDimitry Andric   FPOptions CurFPFeatures;
809cfca06d7SDimitry Andric 
810ec2b103cSEd Schouten public:
811ec2b103cSEd Schouten   /// ObjCEHValueStack - Stack of Objective-C exception values, used for
812ec2b103cSEd Schouten   /// rethrows.
81336981b17SDimitry Andric   SmallVector<llvm::Value*, 8> ObjCEHValueStack;
814ec2b103cSEd Schouten 
815180abc3dSDimitry Andric   /// A class controlling the emission of a finally block.
816180abc3dSDimitry Andric   class FinallyInfo {
817180abc3dSDimitry Andric     /// Where the catchall's edge through the cleanup should go.
818180abc3dSDimitry Andric     JumpDest RethrowDest;
81934d02d0bSRoman Divacky 
820180abc3dSDimitry Andric     /// A function to call to enter the catch.
82122989816SDimitry Andric     llvm::FunctionCallee BeginCatchFn;
822180abc3dSDimitry Andric 
823180abc3dSDimitry Andric     /// An i1 variable indicating whether or not the @finally is
824180abc3dSDimitry Andric     /// running for an exception.
8257fa27ce4SDimitry Andric     llvm::AllocaInst *ForEHVar = nullptr;
826180abc3dSDimitry Andric 
827180abc3dSDimitry Andric     /// An i8* variable into which the exception pointer to rethrow
828180abc3dSDimitry Andric     /// has been saved.
8297fa27ce4SDimitry Andric     llvm::AllocaInst *SavedExnVar = nullptr;
830180abc3dSDimitry Andric 
831180abc3dSDimitry Andric   public:
832180abc3dSDimitry Andric     void enter(CodeGenFunction &CGF, const Stmt *Finally,
83322989816SDimitry Andric                llvm::FunctionCallee beginCatchFn,
83422989816SDimitry Andric                llvm::FunctionCallee endCatchFn, llvm::FunctionCallee rethrowFn);
835180abc3dSDimitry Andric     void exit(CodeGenFunction &CGF);
836180abc3dSDimitry Andric   };
837ec2b103cSEd Schouten 
8385e20cdd8SDimitry Andric   /// Returns true inside SEH __try blocks.
8395e20cdd8SDimitry Andric   bool isSEHTryScope() const { return !SEHTryEpilogueStack.empty(); }
8405e20cdd8SDimitry Andric 
84145b53394SDimitry Andric   /// Returns true while emitting a cleanuppad.
84245b53394SDimitry Andric   bool isCleanupPadScope() const {
84345b53394SDimitry Andric     return CurrentFuncletPad && isa<llvm::CleanupPadInst>(CurrentFuncletPad);
84445b53394SDimitry Andric   }
84545b53394SDimitry Andric 
846bca07a45SDimitry Andric   /// pushFullExprCleanup - Push a cleanup to be run at the end of the
847bca07a45SDimitry Andric   /// current full-expression.  Safe against the possibility that
848bca07a45SDimitry Andric   /// we're currently inside a conditionally-evaluated expression.
8495e20cdd8SDimitry Andric   template <class T, class... As>
8505e20cdd8SDimitry Andric   void pushFullExprCleanup(CleanupKind kind, As... A) {
851bca07a45SDimitry Andric     // If we're not in a conditional branch, or if none of the
852bca07a45SDimitry Andric     // arguments requires saving, then use the unconditional cleanup.
853180abc3dSDimitry Andric     if (!isInConditionalBranch())
8545e20cdd8SDimitry Andric       return EHStack.pushCleanup<T>(kind, A...);
855bca07a45SDimitry Andric 
8565e20cdd8SDimitry Andric     // Stash values in a tuple so we can guarantee the order of saves.
8575e20cdd8SDimitry Andric     typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple;
8585e20cdd8SDimitry Andric     SavedTuple Saved{saveValueInCond(A)...};
859bca07a45SDimitry Andric 
8605e20cdd8SDimitry Andric     typedef EHScopeStack::ConditionalCleanup<T, As...> CleanupType;
8615e20cdd8SDimitry Andric     EHStack.pushCleanupTuple<CleanupType>(kind, Saved);
862180abc3dSDimitry Andric     initFullExprCleanup();
863180abc3dSDimitry Andric   }
864180abc3dSDimitry Andric 
865b60736ecSDimitry Andric   /// Queue a cleanup to be pushed after finishing the current full-expression,
866b60736ecSDimitry Andric   /// potentially with an active flag.
8675e20cdd8SDimitry Andric   template <class T, class... As>
8685e20cdd8SDimitry Andric   void pushCleanupAfterFullExpr(CleanupKind Kind, As... A) {
86948675466SDimitry Andric     if (!isInConditionalBranch())
870ac9a064cSDimitry Andric       return pushCleanupAfterFullExprWithActiveFlag<T>(
871ac9a064cSDimitry Andric           Kind, RawAddress::invalid(), A...);
872bfef3995SDimitry Andric 
873ac9a064cSDimitry Andric     RawAddress ActiveFlag = createCleanupActiveFlag();
87448675466SDimitry Andric     assert(!DominatingValue<Address>::needsSaving(ActiveFlag) &&
87548675466SDimitry Andric            "cleanup active flag should never need saving");
87648675466SDimitry Andric 
87748675466SDimitry Andric     typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple;
87848675466SDimitry Andric     SavedTuple Saved{saveValueInCond(A)...};
87948675466SDimitry Andric 
88048675466SDimitry Andric     typedef EHScopeStack::ConditionalCleanup<T, As...> CleanupType;
881b60736ecSDimitry Andric     pushCleanupAfterFullExprWithActiveFlag<CleanupType>(Kind, ActiveFlag, Saved);
88248675466SDimitry Andric   }
88348675466SDimitry Andric 
88448675466SDimitry Andric   template <class T, class... As>
885b60736ecSDimitry Andric   void pushCleanupAfterFullExprWithActiveFlag(CleanupKind Kind,
886ac9a064cSDimitry Andric                                               RawAddress ActiveFlag, As... A) {
88748675466SDimitry Andric     LifetimeExtendedCleanupHeader Header = {sizeof(T), Kind,
88848675466SDimitry Andric                                             ActiveFlag.isValid()};
889bfef3995SDimitry Andric 
890bfef3995SDimitry Andric     size_t OldSize = LifetimeExtendedCleanupStack.size();
891bfef3995SDimitry Andric     LifetimeExtendedCleanupStack.resize(
89248675466SDimitry Andric         LifetimeExtendedCleanupStack.size() + sizeof(Header) + Header.Size +
89348675466SDimitry Andric         (Header.IsConditional ? sizeof(ActiveFlag) : 0));
894bfef3995SDimitry Andric 
895bab175ecSDimitry Andric     static_assert(sizeof(Header) % alignof(T) == 0,
896c192b3dcSDimitry Andric                   "Cleanup will be allocated on misaligned address");
897bfef3995SDimitry Andric     char *Buffer = &LifetimeExtendedCleanupStack[OldSize];
898bfef3995SDimitry Andric     new (Buffer) LifetimeExtendedCleanupHeader(Header);
8995e20cdd8SDimitry Andric     new (Buffer + sizeof(Header)) T(A...);
90048675466SDimitry Andric     if (Header.IsConditional)
901ac9a064cSDimitry Andric       new (Buffer + sizeof(Header) + sizeof(T)) RawAddress(ActiveFlag);
902ac9a064cSDimitry Andric   }
903ac9a064cSDimitry Andric 
904ac9a064cSDimitry Andric   // Push a cleanup onto EHStack and deactivate it later. It is usually
905ac9a064cSDimitry Andric   // deactivated when exiting a `CleanupDeactivationScope` (for example: after a
906ac9a064cSDimitry Andric   // full expression).
907ac9a064cSDimitry Andric   template <class T, class... As>
908ac9a064cSDimitry Andric   void pushCleanupAndDeferDeactivation(CleanupKind Kind, As... A) {
909ac9a064cSDimitry Andric     // Placeholder dominating IP for this cleanup.
910ac9a064cSDimitry Andric     llvm::Instruction *DominatingIP =
911ac9a064cSDimitry Andric         Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy));
912ac9a064cSDimitry Andric     EHStack.pushCleanup<T>(Kind, A...);
913ac9a064cSDimitry Andric     DeferredDeactivationCleanupStack.push_back(
914ac9a064cSDimitry Andric         {EHStack.stable_begin(), DominatingIP});
915bfef3995SDimitry Andric   }
916bfef3995SDimitry Andric 
91748675466SDimitry Andric   /// Set up the last cleanup that was pushed as a conditional
918dbe13110SDimitry Andric   /// full-expression cleanup.
91948675466SDimitry Andric   void initFullExprCleanup() {
92048675466SDimitry Andric     initFullExprCleanupWithFlag(createCleanupActiveFlag());
92148675466SDimitry Andric   }
92248675466SDimitry Andric 
923ac9a064cSDimitry Andric   void initFullExprCleanupWithFlag(RawAddress ActiveFlag);
924ac9a064cSDimitry Andric   RawAddress createCleanupActiveFlag();
925dbe13110SDimitry Andric 
9264ba67500SRoman Divacky   /// PushDestructorCleanup - Push a cleanup to call the
9274ba67500SRoman Divacky   /// complete-object destructor of an object of the given type at the
9284ba67500SRoman Divacky   /// given address.  Does nothing if T is not a C++ class type with a
9294ba67500SRoman Divacky   /// non-trivial destructor.
93045b53394SDimitry Andric   void PushDestructorCleanup(QualType T, Address Addr);
9314ba67500SRoman Divacky 
9323d1dcd9bSDimitry Andric   /// PushDestructorCleanup - Push a cleanup to call the
9333d1dcd9bSDimitry Andric   /// complete-object variant of the given destructor on the object at
9343d1dcd9bSDimitry Andric   /// the given address.
93522989816SDimitry Andric   void PushDestructorCleanup(const CXXDestructorDecl *Dtor, QualType T,
93622989816SDimitry Andric                              Address Addr);
9373d1dcd9bSDimitry Andric 
9384ba67500SRoman Divacky   /// PopCleanupBlock - Will pop the cleanup entry on the stack and
9394ba67500SRoman Divacky   /// process all branch fixups.
940ac9a064cSDimitry Andric   void PopCleanupBlock(bool FallThroughIsBranchThrough = false,
941ac9a064cSDimitry Andric                        bool ForDeactivation = false);
9424ba67500SRoman Divacky 
943bca07a45SDimitry Andric   /// DeactivateCleanupBlock - Deactivates the given cleanup block.
944bca07a45SDimitry Andric   /// The block cannot be reactivated.  Pops it if it's the top of the
945bca07a45SDimitry Andric   /// stack.
946dbe13110SDimitry Andric   ///
947dbe13110SDimitry Andric   /// \param DominatingIP - An instruction which is known to
948dbe13110SDimitry Andric   ///   dominate the current IP (if set) and which lies along
949dbe13110SDimitry Andric   ///   all paths of execution between the current IP and the
950dbe13110SDimitry Andric   ///   the point at which the cleanup comes into scope.
951dbe13110SDimitry Andric   void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup,
952dbe13110SDimitry Andric                               llvm::Instruction *DominatingIP);
953bca07a45SDimitry Andric 
954bca07a45SDimitry Andric   /// ActivateCleanupBlock - Activates an initially-inactive cleanup.
955bca07a45SDimitry Andric   /// Cannot be used to resurrect a deactivated cleanup.
956dbe13110SDimitry Andric   ///
957dbe13110SDimitry Andric   /// \param DominatingIP - An instruction which is known to
958dbe13110SDimitry Andric   ///   dominate the current IP (if set) and which lies along
959dbe13110SDimitry Andric   ///   all paths of execution between the current IP and the
960dbe13110SDimitry Andric   ///   the point at which the cleanup comes into scope.
961dbe13110SDimitry Andric   void ActivateCleanupBlock(EHScopeStack::stable_iterator Cleanup,
962dbe13110SDimitry Andric                             llvm::Instruction *DominatingIP);
963ec2b103cSEd Schouten 
96448675466SDimitry Andric   /// Enters a new scope for capturing cleanups, all of which
9654ba67500SRoman Divacky   /// will be executed once the scope is exited.
9664ba67500SRoman Divacky   class RunCleanupsScope {
96748675466SDimitry Andric     EHScopeStack::stable_iterator CleanupStackDepth, OldCleanupScopeDepth;
968bfef3995SDimitry Andric     size_t LifetimeExtendedCleanupStackSize;
969ac9a064cSDimitry Andric     CleanupDeactivationScope DeactivateCleanups;
9701569ce68SRoman Divacky     bool OldDidCallStackSave;
971809500fcSDimitry Andric   protected:
9721569ce68SRoman Divacky     bool PerformCleanup;
973809500fcSDimitry Andric   private:
9741569ce68SRoman Divacky 
9755e20cdd8SDimitry Andric     RunCleanupsScope(const RunCleanupsScope &) = delete;
9765e20cdd8SDimitry Andric     void operator=(const RunCleanupsScope &) = delete;
9771569ce68SRoman Divacky 
978dbe13110SDimitry Andric   protected:
979dbe13110SDimitry Andric     CodeGenFunction& CGF;
980dbe13110SDimitry Andric 
9811569ce68SRoman Divacky   public:
98248675466SDimitry Andric     /// Enter a new cleanup scope.
9834ba67500SRoman Divacky     explicit RunCleanupsScope(CodeGenFunction &CGF)
984ac9a064cSDimitry Andric         : DeactivateCleanups(CGF), PerformCleanup(true), CGF(CGF) {
9854ba67500SRoman Divacky       CleanupStackDepth = CGF.EHStack.stable_begin();
986bfef3995SDimitry Andric       LifetimeExtendedCleanupStackSize =
987bfef3995SDimitry Andric           CGF.LifetimeExtendedCleanupStack.size();
9881569ce68SRoman Divacky       OldDidCallStackSave = CGF.DidCallStackSave;
989bca07a45SDimitry Andric       CGF.DidCallStackSave = false;
99048675466SDimitry Andric       OldCleanupScopeDepth = CGF.CurrentCleanupScopeDepth;
99148675466SDimitry Andric       CGF.CurrentCleanupScopeDepth = CleanupStackDepth;
9921569ce68SRoman Divacky     }
9931569ce68SRoman Divacky 
99448675466SDimitry Andric     /// Exit this cleanup scope, emitting any accumulated cleanups.
9954ba67500SRoman Divacky     ~RunCleanupsScope() {
9967442d6faSDimitry Andric       if (PerformCleanup)
9977442d6faSDimitry Andric         ForceCleanup();
9981569ce68SRoman Divacky     }
9991569ce68SRoman Divacky 
100048675466SDimitry Andric     /// Determine whether this scope requires any cleanups.
10011569ce68SRoman Divacky     bool requiresCleanups() const {
10024ba67500SRoman Divacky       return CGF.EHStack.stable_begin() != CleanupStackDepth;
10031569ce68SRoman Divacky     }
10041569ce68SRoman Divacky 
100548675466SDimitry Andric     /// Force the emission of cleanups now, instead of waiting
10061569ce68SRoman Divacky     /// until this object is destroyed.
10077442d6faSDimitry Andric     /// \param ValuesToReload - A list of values that need to be available at
10087442d6faSDimitry Andric     /// the insertion point after cleanup emission. If cleanup emission created
10097442d6faSDimitry Andric     /// a shared cleanup block, these value pointers will be rewritten.
10107442d6faSDimitry Andric     /// Otherwise, they not will be modified.
10117442d6faSDimitry Andric     void ForceCleanup(std::initializer_list<llvm::Value**> ValuesToReload = {}) {
10121569ce68SRoman Divacky       assert(PerformCleanup && "Already forced cleanup");
10131569ce68SRoman Divacky       CGF.DidCallStackSave = OldDidCallStackSave;
1014ac9a064cSDimitry Andric       DeactivateCleanups.ForceDeactivate();
10157442d6faSDimitry Andric       CGF.PopCleanupBlocks(CleanupStackDepth, LifetimeExtendedCleanupStackSize,
10167442d6faSDimitry Andric                            ValuesToReload);
10171569ce68SRoman Divacky       PerformCleanup = false;
101848675466SDimitry Andric       CGF.CurrentCleanupScopeDepth = OldCleanupScopeDepth;
10191569ce68SRoman Divacky     }
10201569ce68SRoman Divacky   };
10211569ce68SRoman Divacky 
102248675466SDimitry Andric   // Cleanup stack depth of the RunCleanupsScope that was pushed most recently.
102348675466SDimitry Andric   EHScopeStack::stable_iterator CurrentCleanupScopeDepth =
102448675466SDimitry Andric       EHScopeStack::stable_end();
102548675466SDimitry Andric 
102606d4ba38SDimitry Andric   class LexicalScope : public RunCleanupsScope {
1027dbe13110SDimitry Andric     SourceRange Range;
1028809500fcSDimitry Andric     SmallVector<const LabelDecl*, 4> Labels;
1029809500fcSDimitry Andric     LexicalScope *ParentScope;
1030dbe13110SDimitry Andric 
10315e20cdd8SDimitry Andric     LexicalScope(const LexicalScope &) = delete;
10325e20cdd8SDimitry Andric     void operator=(const LexicalScope &) = delete;
1033dbe13110SDimitry Andric 
1034dbe13110SDimitry Andric   public:
103548675466SDimitry Andric     /// Enter a new cleanup scope.
1036dbe13110SDimitry Andric     explicit LexicalScope(CodeGenFunction &CGF, SourceRange Range)
1037809500fcSDimitry Andric       : RunCleanupsScope(CGF), Range(Range), ParentScope(CGF.CurLexicalScope) {
1038809500fcSDimitry Andric       CGF.CurLexicalScope = this;
1039dbe13110SDimitry Andric       if (CGDebugInfo *DI = CGF.getDebugInfo())
1040dbe13110SDimitry Andric         DI->EmitLexicalBlockStart(CGF.Builder, Range.getBegin());
1041dbe13110SDimitry Andric     }
1042dbe13110SDimitry Andric 
1043809500fcSDimitry Andric     void addLabel(const LabelDecl *label) {
1044809500fcSDimitry Andric       assert(PerformCleanup && "adding label to dead scope?");
1045809500fcSDimitry Andric       Labels.push_back(label);
1046809500fcSDimitry Andric     }
1047809500fcSDimitry Andric 
104848675466SDimitry Andric     /// Exit this cleanup scope, emitting any accumulated
1049dbe13110SDimitry Andric     /// cleanups.
1050dbe13110SDimitry Andric     ~LexicalScope() {
1051809500fcSDimitry Andric       if (CGDebugInfo *DI = CGF.getDebugInfo())
1052809500fcSDimitry Andric         DI->EmitLexicalBlockEnd(CGF.Builder, Range.getEnd());
1053809500fcSDimitry Andric 
1054809500fcSDimitry Andric       // If we should perform a cleanup, force them now.  Note that
1055809500fcSDimitry Andric       // this ends the cleanup scope before rescoping any labels.
10565e20cdd8SDimitry Andric       if (PerformCleanup) {
10575e20cdd8SDimitry Andric         ApplyDebugLocation DL(CGF, Range.getEnd());
10585e20cdd8SDimitry Andric         ForceCleanup();
10595e20cdd8SDimitry Andric       }
1060dbe13110SDimitry Andric     }
1061dbe13110SDimitry Andric 
106248675466SDimitry Andric     /// Force the emission of cleanups now, instead of waiting
1063dbe13110SDimitry Andric     /// until this object is destroyed.
1064dbe13110SDimitry Andric     void ForceCleanup() {
1065809500fcSDimitry Andric       CGF.CurLexicalScope = ParentScope;
1066dbe13110SDimitry Andric       RunCleanupsScope::ForceCleanup();
1067809500fcSDimitry Andric 
1068809500fcSDimitry Andric       if (!Labels.empty())
1069809500fcSDimitry Andric         rescopeLabels();
1070dbe13110SDimitry Andric     }
1071809500fcSDimitry Andric 
10727442d6faSDimitry Andric     bool hasLabels() const {
10737442d6faSDimitry Andric       return !Labels.empty();
10747442d6faSDimitry Andric     }
10757442d6faSDimitry Andric 
1076809500fcSDimitry Andric     void rescopeLabels();
1077dbe13110SDimitry Andric   };
1078dbe13110SDimitry Andric 
107945b53394SDimitry Andric   typedef llvm::DenseMap<const Decl *, Address> DeclMapTy;
108045b53394SDimitry Andric 
108148675466SDimitry Andric   /// The class used to assign some variables some temporarily addresses.
108248675466SDimitry Andric   class OMPMapVars {
108345b53394SDimitry Andric     DeclMapTy SavedLocals;
108448675466SDimitry Andric     DeclMapTy SavedTempAddresses;
108548675466SDimitry Andric     OMPMapVars(const OMPMapVars &) = delete;
108648675466SDimitry Andric     void operator=(const OMPMapVars &) = delete;
108706d4ba38SDimitry Andric 
108806d4ba38SDimitry Andric   public:
108948675466SDimitry Andric     explicit OMPMapVars() = default;
109048675466SDimitry Andric     ~OMPMapVars() {
109148675466SDimitry Andric       assert(SavedLocals.empty() && "Did not restored original addresses.");
109248675466SDimitry Andric     };
109306d4ba38SDimitry Andric 
109448675466SDimitry Andric     /// Sets the address of the variable \p LocalVD to be \p TempAddr in
109548675466SDimitry Andric     /// function \p CGF.
109648675466SDimitry Andric     /// \return true if at least one variable was set already, false otherwise.
109748675466SDimitry Andric     bool setVarAddr(CodeGenFunction &CGF, const VarDecl *LocalVD,
109848675466SDimitry Andric                     Address TempAddr) {
1099461a67faSDimitry Andric       LocalVD = LocalVD->getCanonicalDecl();
110045b53394SDimitry Andric       // Only save it once.
110145b53394SDimitry Andric       if (SavedLocals.count(LocalVD)) return false;
110245b53394SDimitry Andric 
110345b53394SDimitry Andric       // Copy the existing local entry to SavedLocals.
110445b53394SDimitry Andric       auto it = CGF.LocalDeclMap.find(LocalVD);
110548675466SDimitry Andric       if (it != CGF.LocalDeclMap.end())
110648675466SDimitry Andric         SavedLocals.try_emplace(LocalVD, it->second);
110748675466SDimitry Andric       else
110848675466SDimitry Andric         SavedLocals.try_emplace(LocalVD, Address::invalid());
110945b53394SDimitry Andric 
111045b53394SDimitry Andric       // Generate the private entry.
111145b53394SDimitry Andric       QualType VarTy = LocalVD->getType();
111245b53394SDimitry Andric       if (VarTy->isReferenceType()) {
111345b53394SDimitry Andric         Address Temp = CGF.CreateMemTemp(VarTy);
1114ac9a064cSDimitry Andric         CGF.Builder.CreateStore(TempAddr.emitRawPointer(CGF), Temp);
111548675466SDimitry Andric         TempAddr = Temp;
111645b53394SDimitry Andric       }
111748675466SDimitry Andric       SavedTempAddresses.try_emplace(LocalVD, TempAddr);
111845b53394SDimitry Andric 
111906d4ba38SDimitry Andric       return true;
112006d4ba38SDimitry Andric     }
112106d4ba38SDimitry Andric 
112248675466SDimitry Andric     /// Applies new addresses to the list of the variables.
112348675466SDimitry Andric     /// \return true if at least one variable is using new address, false
112448675466SDimitry Andric     /// otherwise.
112548675466SDimitry Andric     bool apply(CodeGenFunction &CGF) {
112648675466SDimitry Andric       copyInto(SavedTempAddresses, CGF.LocalDeclMap);
112748675466SDimitry Andric       SavedTempAddresses.clear();
112848675466SDimitry Andric       return !SavedLocals.empty();
112948675466SDimitry Andric     }
113048675466SDimitry Andric 
113148675466SDimitry Andric     /// Restores original addresses of the variables.
113248675466SDimitry Andric     void restore(CodeGenFunction &CGF) {
113348675466SDimitry Andric       if (!SavedLocals.empty()) {
113448675466SDimitry Andric         copyInto(SavedLocals, CGF.LocalDeclMap);
113548675466SDimitry Andric         SavedLocals.clear();
113648675466SDimitry Andric       }
113748675466SDimitry Andric     }
113848675466SDimitry Andric 
113948675466SDimitry Andric   private:
114048675466SDimitry Andric     /// Copy all the entries in the source map over the corresponding
114148675466SDimitry Andric     /// entries in the destination, which must exist.
114248675466SDimitry Andric     static void copyInto(const DeclMapTy &Src, DeclMapTy &Dest) {
114348675466SDimitry Andric       for (auto &Pair : Src) {
114448675466SDimitry Andric         if (!Pair.second.isValid()) {
114548675466SDimitry Andric           Dest.erase(Pair.first);
114648675466SDimitry Andric           continue;
114748675466SDimitry Andric         }
114848675466SDimitry Andric 
114948675466SDimitry Andric         auto I = Dest.find(Pair.first);
115048675466SDimitry Andric         if (I != Dest.end())
115148675466SDimitry Andric           I->second = Pair.second;
115248675466SDimitry Andric         else
115348675466SDimitry Andric           Dest.insert(Pair);
115448675466SDimitry Andric       }
115548675466SDimitry Andric     }
115648675466SDimitry Andric   };
115748675466SDimitry Andric 
115848675466SDimitry Andric   /// The scope used to remap some variables as private in the OpenMP loop body
115948675466SDimitry Andric   /// (or other captured region emitted without outlining), and to restore old
116048675466SDimitry Andric   /// vars back on exit.
116148675466SDimitry Andric   class OMPPrivateScope : public RunCleanupsScope {
116248675466SDimitry Andric     OMPMapVars MappedVars;
116348675466SDimitry Andric     OMPPrivateScope(const OMPPrivateScope &) = delete;
116448675466SDimitry Andric     void operator=(const OMPPrivateScope &) = delete;
116548675466SDimitry Andric 
116648675466SDimitry Andric   public:
116748675466SDimitry Andric     /// Enter a new OpenMP private scope.
116848675466SDimitry Andric     explicit OMPPrivateScope(CodeGenFunction &CGF) : RunCleanupsScope(CGF) {}
116948675466SDimitry Andric 
1170145449b1SDimitry Andric     /// Registers \p LocalVD variable as a private with \p Addr as the address
1171145449b1SDimitry Andric     /// of the corresponding private variable. \p
1172145449b1SDimitry Andric     /// PrivateGen is the address of the generated private variable.
117348675466SDimitry Andric     /// \return true if the variable is registered as private, false if it has
117448675466SDimitry Andric     /// been privatized already.
1175145449b1SDimitry Andric     bool addPrivate(const VarDecl *LocalVD, Address Addr) {
117648675466SDimitry Andric       assert(PerformCleanup && "adding private to dead scope");
1177145449b1SDimitry Andric       return MappedVars.setVarAddr(CGF, LocalVD, Addr);
117848675466SDimitry Andric     }
117948675466SDimitry Andric 
118048675466SDimitry Andric     /// Privatizes local variables previously registered as private.
118106d4ba38SDimitry Andric     /// Registration is separate from the actual privatization to allow
118206d4ba38SDimitry Andric     /// initializers use values of the original variables, not the private one.
118306d4ba38SDimitry Andric     /// This is important, for example, if the private variable is a class
118406d4ba38SDimitry Andric     /// variable initialized by a constructor that references other private
118506d4ba38SDimitry Andric     /// variables. But at initialization original variables must be used, not
118606d4ba38SDimitry Andric     /// private copies.
118706d4ba38SDimitry Andric     /// \return true if at least one variable was privatized, false otherwise.
118848675466SDimitry Andric     bool Privatize() { return MappedVars.apply(CGF); }
118906d4ba38SDimitry Andric 
119006d4ba38SDimitry Andric     void ForceCleanup() {
119106d4ba38SDimitry Andric       RunCleanupsScope::ForceCleanup();
1192e3b55780SDimitry Andric       restoreMap();
119306d4ba38SDimitry Andric     }
119406d4ba38SDimitry Andric 
119548675466SDimitry Andric     /// Exit scope - all the mapped variables are restored.
11965e20cdd8SDimitry Andric     ~OMPPrivateScope() {
11975e20cdd8SDimitry Andric       if (PerformCleanup)
11985e20cdd8SDimitry Andric         ForceCleanup();
11995e20cdd8SDimitry Andric     }
120045b53394SDimitry Andric 
12012b6b257fSDimitry Andric     /// Checks if the global variable is captured in current function.
12022b6b257fSDimitry Andric     bool isGlobalVarCaptured(const VarDecl *VD) const {
1203461a67faSDimitry Andric       VD = VD->getCanonicalDecl();
12042b6b257fSDimitry Andric       return !VD->isLocalVarDeclOrParm() && CGF.LocalDeclMap.count(VD) > 0;
12052b6b257fSDimitry Andric     }
1206e3b55780SDimitry Andric 
1207e3b55780SDimitry Andric     /// Restore all mapped variables w/o clean up. This is usefully when we want
1208e3b55780SDimitry Andric     /// to reference the original variables but don't want the clean up because
1209e3b55780SDimitry Andric     /// that could emit lifetime end too early, causing backend issue #56913.
1210e3b55780SDimitry Andric     void restoreMap() { MappedVars.restore(CGF); }
121106d4ba38SDimitry Andric   };
121211d2b2d2SRoman Divacky 
1213706b4fc4SDimitry Andric   /// Save/restore original map of previously emitted local vars in case when we
1214706b4fc4SDimitry Andric   /// need to duplicate emission of the same code several times in the same
1215706b4fc4SDimitry Andric   /// function for OpenMP code.
1216706b4fc4SDimitry Andric   class OMPLocalDeclMapRAII {
1217706b4fc4SDimitry Andric     CodeGenFunction &CGF;
1218706b4fc4SDimitry Andric     DeclMapTy SavedMap;
1219706b4fc4SDimitry Andric 
1220706b4fc4SDimitry Andric   public:
1221706b4fc4SDimitry Andric     OMPLocalDeclMapRAII(CodeGenFunction &CGF)
1222706b4fc4SDimitry Andric         : CGF(CGF), SavedMap(CGF.LocalDeclMap) {}
1223706b4fc4SDimitry Andric     ~OMPLocalDeclMapRAII() { SavedMap.swap(CGF.LocalDeclMap); }
1224706b4fc4SDimitry Andric   };
1225706b4fc4SDimitry Andric 
122648675466SDimitry Andric   /// Takes the old cleanup stack size and emits the cleanup blocks
1227bfef3995SDimitry Andric   /// that have been added.
12287442d6faSDimitry Andric   void
12297442d6faSDimitry Andric   PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize,
12307442d6faSDimitry Andric                    std::initializer_list<llvm::Value **> ValuesToReload = {});
1231bfef3995SDimitry Andric 
123248675466SDimitry Andric   /// Takes the old cleanup stack size and emits the cleanup blocks
1233bfef3995SDimitry Andric   /// that have been added, then adds all lifetime-extended cleanups from
1234bfef3995SDimitry Andric   /// the given position to the stack.
12357442d6faSDimitry Andric   void
12367442d6faSDimitry Andric   PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize,
12377442d6faSDimitry Andric                    size_t OldLifetimeExtendedStackSize,
12387442d6faSDimitry Andric                    std::initializer_list<llvm::Value **> ValuesToReload = {});
123911d2b2d2SRoman Divacky 
12403d1dcd9bSDimitry Andric   void ResolveBranchFixups(llvm::BasicBlock *Target);
12413d1dcd9bSDimitry Andric 
12424ba67500SRoman Divacky   /// The given basic block lies in the current EH scope, but may be a
12434ba67500SRoman Divacky   /// target of a potentially scope-crossing jump; get a stable handle
12444ba67500SRoman Divacky   /// to which we can perform this jump later.
12453d1dcd9bSDimitry Andric   JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target) {
12463d1dcd9bSDimitry Andric     return JumpDest(Target,
12473d1dcd9bSDimitry Andric                     EHStack.getInnermostNormalCleanup(),
12483d1dcd9bSDimitry Andric                     NextCleanupDestIndex++);
124911d2b2d2SRoman Divacky   }
125011d2b2d2SRoman Divacky 
12514ba67500SRoman Divacky   /// The given basic block lies in the current EH scope, but may be a
12524ba67500SRoman Divacky   /// target of a potentially scope-crossing jump; get a stable handle
12534ba67500SRoman Divacky   /// to which we can perform this jump later.
125436981b17SDimitry Andric   JumpDest getJumpDestInCurrentScope(StringRef Name = StringRef()) {
12553d1dcd9bSDimitry Andric     return getJumpDestInCurrentScope(createBasicBlock(Name));
12564ba67500SRoman Divacky   }
125711d2b2d2SRoman Divacky 
12584ba67500SRoman Divacky   /// EmitBranchThroughCleanup - Emit a branch from the current insert
12594ba67500SRoman Divacky   /// block through the normal cleanup handling code (if any) and then
12604ba67500SRoman Divacky   /// on to \arg Dest.
12614ba67500SRoman Divacky   void EmitBranchThroughCleanup(JumpDest Dest);
1262ec2b103cSEd Schouten 
126301af97d3SDimitry Andric   /// isObviouslyBranchWithoutCleanups - Return true if a branch to the
126401af97d3SDimitry Andric   /// specified destination obviously has no cleanups to run.  'false' is always
126501af97d3SDimitry Andric   /// a conservatively correct answer for this method.
126601af97d3SDimitry Andric   bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const;
126701af97d3SDimitry Andric 
126836981b17SDimitry Andric   /// popCatchScope - Pops the catch scope at the top of the EHScope
126936981b17SDimitry Andric   /// stack, emitting any required code (other than the catch handlers
127036981b17SDimitry Andric   /// themselves).
127136981b17SDimitry Andric   void popCatchScope();
12723d1dcd9bSDimitry Andric 
127313cc256eSDimitry Andric   llvm::BasicBlock *getEHResumeBlock(bool isCleanup);
127436981b17SDimitry Andric   llvm::BasicBlock *getEHDispatchBlock(EHScopeStack::stable_iterator scope);
127548675466SDimitry Andric   llvm::BasicBlock *
127648675466SDimitry Andric   getFuncletEHDispatchBlock(EHScopeStack::stable_iterator scope);
1277ec2b103cSEd Schouten 
1278bca07a45SDimitry Andric   /// An object to manage conditionally-evaluated expressions.
1279bca07a45SDimitry Andric   class ConditionalEvaluation {
1280bca07a45SDimitry Andric     llvm::BasicBlock *StartBB;
1281bca07a45SDimitry Andric 
1282bca07a45SDimitry Andric   public:
1283bca07a45SDimitry Andric     ConditionalEvaluation(CodeGenFunction &CGF)
1284bca07a45SDimitry Andric       : StartBB(CGF.Builder.GetInsertBlock()) {}
1285bca07a45SDimitry Andric 
1286bca07a45SDimitry Andric     void begin(CodeGenFunction &CGF) {
1287bca07a45SDimitry Andric       assert(CGF.OutermostConditional != this);
1288bca07a45SDimitry Andric       if (!CGF.OutermostConditional)
1289bca07a45SDimitry Andric         CGF.OutermostConditional = this;
12901569ce68SRoman Divacky     }
129137f6c480SEd Schouten 
1292bca07a45SDimitry Andric     void end(CodeGenFunction &CGF) {
12939f4dbff6SDimitry Andric       assert(CGF.OutermostConditional != nullptr);
1294bca07a45SDimitry Andric       if (CGF.OutermostConditional == this)
12959f4dbff6SDimitry Andric         CGF.OutermostConditional = nullptr;
12961569ce68SRoman Divacky     }
129737f6c480SEd Schouten 
1298bca07a45SDimitry Andric     /// Returns a block which will be executed prior to each
1299bca07a45SDimitry Andric     /// evaluation of the conditional code.
1300bca07a45SDimitry Andric     llvm::BasicBlock *getStartingBlock() const {
1301bca07a45SDimitry Andric       return StartBB;
1302bca07a45SDimitry Andric     }
1303bca07a45SDimitry Andric   };
1304bca07a45SDimitry Andric 
1305bca07a45SDimitry Andric   /// isInConditionalBranch - Return true if we're currently emitting
1306bca07a45SDimitry Andric   /// one branch or the other of a conditional expression.
13079f4dbff6SDimitry Andric   bool isInConditionalBranch() const { return OutermostConditional != nullptr; }
1308bca07a45SDimitry Andric 
1309ac9a064cSDimitry Andric   void setBeforeOutermostConditional(llvm::Value *value, Address addr,
1310ac9a064cSDimitry Andric                                      CodeGenFunction &CGF) {
1311dbe13110SDimitry Andric     assert(isInConditionalBranch());
1312dbe13110SDimitry Andric     llvm::BasicBlock *block = OutermostConditional->getStartingBlock();
1313ac9a064cSDimitry Andric     auto store =
1314ac9a064cSDimitry Andric         new llvm::StoreInst(value, addr.emitRawPointer(CGF), &block->back());
1315519fc96cSDimitry Andric     store->setAlignment(addr.getAlignment().getAsAlign());
1316dbe13110SDimitry Andric   }
1317dbe13110SDimitry Andric 
1318bca07a45SDimitry Andric   /// An RAII object to record that we're evaluating a statement
1319bca07a45SDimitry Andric   /// expression.
1320bca07a45SDimitry Andric   class StmtExprEvaluation {
1321bca07a45SDimitry Andric     CodeGenFunction &CGF;
1322bca07a45SDimitry Andric 
1323bca07a45SDimitry Andric     /// We have to save the outermost conditional: cleanups in a
1324bca07a45SDimitry Andric     /// statement expression aren't conditional just because the
1325bca07a45SDimitry Andric     /// StmtExpr is.
1326bca07a45SDimitry Andric     ConditionalEvaluation *SavedOutermostConditional;
1327bca07a45SDimitry Andric 
1328bca07a45SDimitry Andric   public:
1329bca07a45SDimitry Andric     StmtExprEvaluation(CodeGenFunction &CGF)
1330bca07a45SDimitry Andric       : CGF(CGF), SavedOutermostConditional(CGF.OutermostConditional) {
13319f4dbff6SDimitry Andric       CGF.OutermostConditional = nullptr;
1332bca07a45SDimitry Andric     }
1333bca07a45SDimitry Andric 
1334bca07a45SDimitry Andric     ~StmtExprEvaluation() {
1335bca07a45SDimitry Andric       CGF.OutermostConditional = SavedOutermostConditional;
1336bca07a45SDimitry Andric       CGF.EnsureInsertPoint();
1337bca07a45SDimitry Andric     }
1338bca07a45SDimitry Andric   };
1339bca07a45SDimitry Andric 
1340bca07a45SDimitry Andric   /// An object which temporarily prevents a value from being
1341bca07a45SDimitry Andric   /// destroyed by aggressive peephole optimizations that assume that
1342bca07a45SDimitry Andric   /// all uses of a value have been realized in the IR.
1343bca07a45SDimitry Andric   class PeepholeProtection {
1344b1c73532SDimitry Andric     llvm::Instruction *Inst = nullptr;
1345bca07a45SDimitry Andric     friend class CodeGenFunction;
1346bca07a45SDimitry Andric 
1347bca07a45SDimitry Andric   public:
1348b1c73532SDimitry Andric     PeepholeProtection() = default;
1349bca07a45SDimitry Andric   };
1350bca07a45SDimitry Andric 
1351dbe13110SDimitry Andric   /// A non-RAII class containing all the information about a bound
1352dbe13110SDimitry Andric   /// opaque value.  OpaqueValueMapping, below, is a RAII wrapper for
1353dbe13110SDimitry Andric   /// this which makes individual mappings very simple; using this
1354dbe13110SDimitry Andric   /// class directly is useful when you have a variable number of
1355dbe13110SDimitry Andric   /// opaque values or don't want the RAII functionality for some
1356dbe13110SDimitry Andric   /// reason.
1357dbe13110SDimitry Andric   class OpaqueValueMappingData {
1358bca07a45SDimitry Andric     const OpaqueValueExpr *OpaqueValue;
1359bca07a45SDimitry Andric     bool BoundLValue;
1360bca07a45SDimitry Andric     CodeGenFunction::PeepholeProtection Protection;
1361bca07a45SDimitry Andric 
1362dbe13110SDimitry Andric     OpaqueValueMappingData(const OpaqueValueExpr *ov,
1363dbe13110SDimitry Andric                            bool boundLValue)
1364dbe13110SDimitry Andric       : OpaqueValue(ov), BoundLValue(boundLValue) {}
1365dbe13110SDimitry Andric   public:
13669f4dbff6SDimitry Andric     OpaqueValueMappingData() : OpaqueValue(nullptr) {}
1367dbe13110SDimitry Andric 
1368dbe13110SDimitry Andric     static bool shouldBindAsLValue(const Expr *expr) {
1369dbe13110SDimitry Andric       // gl-values should be bound as l-values for obvious reasons.
1370dbe13110SDimitry Andric       // Records should be bound as l-values because IR generation
1371dbe13110SDimitry Andric       // always keeps them in memory.  Expressions of function type
1372dbe13110SDimitry Andric       // act exactly like l-values but are formally required to be
1373dbe13110SDimitry Andric       // r-values in C.
1374dbe13110SDimitry Andric       return expr->isGLValue() ||
13759f4dbff6SDimitry Andric              expr->getType()->isFunctionType() ||
13769f4dbff6SDimitry Andric              hasAggregateEvaluationKind(expr->getType());
1377dbe13110SDimitry Andric     }
1378dbe13110SDimitry Andric 
1379dbe13110SDimitry Andric     static OpaqueValueMappingData bind(CodeGenFunction &CGF,
1380dbe13110SDimitry Andric                                        const OpaqueValueExpr *ov,
1381dbe13110SDimitry Andric                                        const Expr *e) {
1382dbe13110SDimitry Andric       if (shouldBindAsLValue(ov))
1383dbe13110SDimitry Andric         return bind(CGF, ov, CGF.EmitLValue(e));
1384dbe13110SDimitry Andric       return bind(CGF, ov, CGF.EmitAnyExpr(e));
1385dbe13110SDimitry Andric     }
1386dbe13110SDimitry Andric 
1387dbe13110SDimitry Andric     static OpaqueValueMappingData bind(CodeGenFunction &CGF,
1388dbe13110SDimitry Andric                                        const OpaqueValueExpr *ov,
1389dbe13110SDimitry Andric                                        const LValue &lv) {
1390dbe13110SDimitry Andric       assert(shouldBindAsLValue(ov));
1391dbe13110SDimitry Andric       CGF.OpaqueLValues.insert(std::make_pair(ov, lv));
1392dbe13110SDimitry Andric       return OpaqueValueMappingData(ov, true);
1393dbe13110SDimitry Andric     }
1394dbe13110SDimitry Andric 
1395dbe13110SDimitry Andric     static OpaqueValueMappingData bind(CodeGenFunction &CGF,
1396dbe13110SDimitry Andric                                        const OpaqueValueExpr *ov,
1397dbe13110SDimitry Andric                                        const RValue &rv) {
1398dbe13110SDimitry Andric       assert(!shouldBindAsLValue(ov));
1399dbe13110SDimitry Andric       CGF.OpaqueRValues.insert(std::make_pair(ov, rv));
1400dbe13110SDimitry Andric 
1401dbe13110SDimitry Andric       OpaqueValueMappingData data(ov, false);
1402dbe13110SDimitry Andric 
1403dbe13110SDimitry Andric       // Work around an extremely aggressive peephole optimization in
1404dbe13110SDimitry Andric       // EmitScalarConversion which assumes that all other uses of a
1405dbe13110SDimitry Andric       // value are extant.
1406dbe13110SDimitry Andric       data.Protection = CGF.protectFromPeepholes(rv);
1407dbe13110SDimitry Andric 
1408dbe13110SDimitry Andric       return data;
1409dbe13110SDimitry Andric     }
1410dbe13110SDimitry Andric 
14119f4dbff6SDimitry Andric     bool isValid() const { return OpaqueValue != nullptr; }
14129f4dbff6SDimitry Andric     void clear() { OpaqueValue = nullptr; }
1413dbe13110SDimitry Andric 
1414dbe13110SDimitry Andric     void unbind(CodeGenFunction &CGF) {
1415dbe13110SDimitry Andric       assert(OpaqueValue && "no data to unbind!");
1416dbe13110SDimitry Andric 
1417dbe13110SDimitry Andric       if (BoundLValue) {
1418dbe13110SDimitry Andric         CGF.OpaqueLValues.erase(OpaqueValue);
1419dbe13110SDimitry Andric       } else {
1420dbe13110SDimitry Andric         CGF.OpaqueRValues.erase(OpaqueValue);
1421dbe13110SDimitry Andric         CGF.unprotectFromPeepholes(Protection);
1422dbe13110SDimitry Andric       }
1423dbe13110SDimitry Andric     }
1424dbe13110SDimitry Andric   };
1425dbe13110SDimitry Andric 
1426dbe13110SDimitry Andric   /// An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
1427dbe13110SDimitry Andric   class OpaqueValueMapping {
1428dbe13110SDimitry Andric     CodeGenFunction &CGF;
1429dbe13110SDimitry Andric     OpaqueValueMappingData Data;
1430dbe13110SDimitry Andric 
1431bca07a45SDimitry Andric   public:
1432bca07a45SDimitry Andric     static bool shouldBindAsLValue(const Expr *expr) {
1433dbe13110SDimitry Andric       return OpaqueValueMappingData::shouldBindAsLValue(expr);
1434bca07a45SDimitry Andric     }
1435bca07a45SDimitry Andric 
1436bca07a45SDimitry Andric     /// Build the opaque value mapping for the given conditional
1437bca07a45SDimitry Andric     /// operator if it's the GNU ?: extension.  This is a common
1438bca07a45SDimitry Andric     /// enough pattern that the convenience operator is really
1439bca07a45SDimitry Andric     /// helpful.
1440bca07a45SDimitry Andric     ///
1441bca07a45SDimitry Andric     OpaqueValueMapping(CodeGenFunction &CGF,
1442bca07a45SDimitry Andric                        const AbstractConditionalOperator *op) : CGF(CGF) {
1443dbe13110SDimitry Andric       if (isa<ConditionalOperator>(op))
1444dbe13110SDimitry Andric         // Leave Data empty.
1445bca07a45SDimitry Andric         return;
1446bca07a45SDimitry Andric 
1447bca07a45SDimitry Andric       const BinaryConditionalOperator *e = cast<BinaryConditionalOperator>(op);
1448dbe13110SDimitry Andric       Data = OpaqueValueMappingData::bind(CGF, e->getOpaqueValue(),
1449dbe13110SDimitry Andric                                           e->getCommon());
1450bca07a45SDimitry Andric     }
1451bca07a45SDimitry Andric 
1452bab175ecSDimitry Andric     /// Build the opaque value mapping for an OpaqueValueExpr whose source
1453bab175ecSDimitry Andric     /// expression is set to the expression the OVE represents.
1454bab175ecSDimitry Andric     OpaqueValueMapping(CodeGenFunction &CGF, const OpaqueValueExpr *OV)
1455bab175ecSDimitry Andric         : CGF(CGF) {
1456bab175ecSDimitry Andric       if (OV) {
1457bab175ecSDimitry Andric         assert(OV->getSourceExpr() && "wrong form of OpaqueValueMapping used "
1458bab175ecSDimitry Andric                                       "for OVE with no source expression");
1459bab175ecSDimitry Andric         Data = OpaqueValueMappingData::bind(CGF, OV, OV->getSourceExpr());
1460bab175ecSDimitry Andric       }
1461bab175ecSDimitry Andric     }
1462bab175ecSDimitry Andric 
1463bca07a45SDimitry Andric     OpaqueValueMapping(CodeGenFunction &CGF,
1464bca07a45SDimitry Andric                        const OpaqueValueExpr *opaqueValue,
1465bca07a45SDimitry Andric                        LValue lvalue)
1466dbe13110SDimitry Andric       : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, lvalue)) {
1467bca07a45SDimitry Andric     }
1468bca07a45SDimitry Andric 
1469bca07a45SDimitry Andric     OpaqueValueMapping(CodeGenFunction &CGF,
1470bca07a45SDimitry Andric                        const OpaqueValueExpr *opaqueValue,
1471bca07a45SDimitry Andric                        RValue rvalue)
1472dbe13110SDimitry Andric       : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, rvalue)) {
1473bca07a45SDimitry Andric     }
1474bca07a45SDimitry Andric 
1475bca07a45SDimitry Andric     void pop() {
1476dbe13110SDimitry Andric       Data.unbind(CGF);
1477dbe13110SDimitry Andric       Data.clear();
1478bca07a45SDimitry Andric     }
1479bca07a45SDimitry Andric 
1480bca07a45SDimitry Andric     ~OpaqueValueMapping() {
1481dbe13110SDimitry Andric       if (Data.isValid()) Data.unbind(CGF);
1482bca07a45SDimitry Andric     }
1483bca07a45SDimitry Andric   };
1484bca07a45SDimitry Andric 
1485ec2b103cSEd Schouten private:
1486ec2b103cSEd Schouten   CGDebugInfo *DebugInfo;
1487676fbe81SDimitry Andric   /// Used to create unique names for artificial VLA size debug info variables.
1488676fbe81SDimitry Andric   unsigned VLAExprCounter = 0;
148948675466SDimitry Andric   bool DisableDebugInfo = false;
1490ec2b103cSEd Schouten 
149129cafa66SDimitry Andric   /// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid
149229cafa66SDimitry Andric   /// calling llvm.stacksave for multiple VLAs in the same scope.
149348675466SDimitry Andric   bool DidCallStackSave = false;
149429cafa66SDimitry Andric 
14951569ce68SRoman Divacky   /// IndirectBranch - The first time an indirect goto is seen we create a block
14961569ce68SRoman Divacky   /// with an indirect branch.  Every time we see the address of a label taken,
14971569ce68SRoman Divacky   /// we add the label to the indirect goto.  Every subsequent indirect goto is
14981569ce68SRoman Divacky   /// codegen'd as a jump to the IndirectBranch's basic block.
149948675466SDimitry Andric   llvm::IndirectBrInst *IndirectBranch = nullptr;
1500ec2b103cSEd Schouten 
1501ec2b103cSEd Schouten   /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
1502ec2b103cSEd Schouten   /// decls.
1503bca07a45SDimitry Andric   DeclMapTy LocalDeclMap;
1504ec2b103cSEd Schouten 
150548675466SDimitry Andric   // Keep track of the cleanups for callee-destructed parameters pushed to the
150648675466SDimitry Andric   // cleanup stack so that they can be deactivated later.
150748675466SDimitry Andric   llvm::DenseMap<const ParmVarDecl *, EHScopeStack::stable_iterator>
150848675466SDimitry Andric       CalleeDestructedParamCleanups;
150948675466SDimitry Andric 
151045b53394SDimitry Andric   /// SizeArguments - If a ParmVarDecl had the pass_object_size attribute, this
151145b53394SDimitry Andric   /// will contain a mapping from said ParmVarDecl to its implicit "object_size"
151245b53394SDimitry Andric   /// parameter.
151345b53394SDimitry Andric   llvm::SmallDenseMap<const ParmVarDecl *, const ImplicitParamDecl *, 2>
151445b53394SDimitry Andric       SizeArguments;
151545b53394SDimitry Andric 
15165e20cdd8SDimitry Andric   /// Track escaped local variables with auto storage. Used during SEH
151751ece4aaSDimitry Andric   /// outlining to produce a call to llvm.localescape.
15185e20cdd8SDimitry Andric   llvm::DenseMap<llvm::AllocaInst *, int> EscapedLocals;
15195e20cdd8SDimitry Andric 
1520ec2b103cSEd Schouten   /// LabelMap - This keeps track of the LLVM basic block for each C label.
1521bca07a45SDimitry Andric   llvm::DenseMap<const LabelDecl*, JumpDest> LabelMap;
1522ec2b103cSEd Schouten 
1523ec2b103cSEd Schouten   // BreakContinueStack - This keeps track of where break and continue
1524ec2b103cSEd Schouten   // statements should jump to.
1525ec2b103cSEd Schouten   struct BreakContinue {
15264ba67500SRoman Divacky     BreakContinue(JumpDest Break, JumpDest Continue)
15274ba67500SRoman Divacky       : BreakBlock(Break), ContinueBlock(Continue) {}
1528ec2b103cSEd Schouten 
15294ba67500SRoman Divacky     JumpDest BreakBlock;
15304ba67500SRoman Divacky     JumpDest ContinueBlock;
1531ec2b103cSEd Schouten   };
153236981b17SDimitry Andric   SmallVector<BreakContinue, 8> BreakContinueStack;
1533ec2b103cSEd Schouten 
1534545937e1SDimitry Andric   /// Handles cancellation exit points in OpenMP-related constructs.
1535545937e1SDimitry Andric   class OpenMPCancelExitStack {
1536545937e1SDimitry Andric     /// Tracks cancellation exit point and join point for cancel-related exit
1537545937e1SDimitry Andric     /// and normal exit.
1538545937e1SDimitry Andric     struct CancelExit {
1539545937e1SDimitry Andric       CancelExit() = default;
1540545937e1SDimitry Andric       CancelExit(OpenMPDirectiveKind Kind, JumpDest ExitBlock,
1541545937e1SDimitry Andric                  JumpDest ContBlock)
1542545937e1SDimitry Andric           : Kind(Kind), ExitBlock(ExitBlock), ContBlock(ContBlock) {}
1543706b4fc4SDimitry Andric       OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown;
1544545937e1SDimitry Andric       /// true if the exit block has been emitted already by the special
1545545937e1SDimitry Andric       /// emitExit() call, false if the default codegen is used.
1546545937e1SDimitry Andric       bool HasBeenEmitted = false;
154717c7957fSDimitry Andric       JumpDest ExitBlock;
1548545937e1SDimitry Andric       JumpDest ContBlock;
154917c7957fSDimitry Andric     };
1550545937e1SDimitry Andric 
1551545937e1SDimitry Andric     SmallVector<CancelExit, 8> Stack;
1552545937e1SDimitry Andric 
1553545937e1SDimitry Andric   public:
1554545937e1SDimitry Andric     OpenMPCancelExitStack() : Stack(1) {}
1555545937e1SDimitry Andric     ~OpenMPCancelExitStack() = default;
1556545937e1SDimitry Andric     /// Fetches the exit block for the current OpenMP construct.
1557545937e1SDimitry Andric     JumpDest getExitBlock() const { return Stack.back().ExitBlock; }
1558545937e1SDimitry Andric     /// Emits exit block with special codegen procedure specific for the related
1559545937e1SDimitry Andric     /// OpenMP construct + emits code for normal construct cleanup.
1560545937e1SDimitry Andric     void emitExit(CodeGenFunction &CGF, OpenMPDirectiveKind Kind,
156148675466SDimitry Andric                   const llvm::function_ref<void(CodeGenFunction &)> CodeGen) {
1562545937e1SDimitry Andric       if (Stack.back().Kind == Kind && getExitBlock().isValid()) {
1563545937e1SDimitry Andric         assert(CGF.getOMPCancelDestination(Kind).isValid());
1564545937e1SDimitry Andric         assert(CGF.HaveInsertPoint());
1565545937e1SDimitry Andric         assert(!Stack.back().HasBeenEmitted);
1566545937e1SDimitry Andric         auto IP = CGF.Builder.saveAndClearIP();
1567545937e1SDimitry Andric         CGF.EmitBlock(Stack.back().ExitBlock.getBlock());
1568545937e1SDimitry Andric         CodeGen(CGF);
1569b5ea630dSDimitry Andric         CGF.EmitBranch(Stack.back().ContBlock.getBlock());
1570545937e1SDimitry Andric         CGF.Builder.restoreIP(IP);
1571545937e1SDimitry Andric         Stack.back().HasBeenEmitted = true;
1572545937e1SDimitry Andric       }
1573545937e1SDimitry Andric       CodeGen(CGF);
1574545937e1SDimitry Andric     }
1575545937e1SDimitry Andric     /// Enter the cancel supporting \a Kind construct.
1576545937e1SDimitry Andric     /// \param Kind OpenMP directive that supports cancel constructs.
1577545937e1SDimitry Andric     /// \param HasCancel true, if the construct has inner cancel directive,
1578545937e1SDimitry Andric     /// false otherwise.
1579545937e1SDimitry Andric     void enter(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, bool HasCancel) {
1580545937e1SDimitry Andric       Stack.push_back({Kind,
1581545937e1SDimitry Andric                        HasCancel ? CGF.getJumpDestInCurrentScope("cancel.exit")
1582545937e1SDimitry Andric                                  : JumpDest(),
1583545937e1SDimitry Andric                        HasCancel ? CGF.getJumpDestInCurrentScope("cancel.cont")
1584545937e1SDimitry Andric                                  : JumpDest()});
1585545937e1SDimitry Andric     }
1586545937e1SDimitry Andric     /// Emits default exit point for the cancel construct (if the special one
1587545937e1SDimitry Andric     /// has not be used) + join point for cancel/normal exits.
1588545937e1SDimitry Andric     void exit(CodeGenFunction &CGF) {
1589545937e1SDimitry Andric       if (getExitBlock().isValid()) {
1590545937e1SDimitry Andric         assert(CGF.getOMPCancelDestination(Stack.back().Kind).isValid());
1591545937e1SDimitry Andric         bool HaveIP = CGF.HaveInsertPoint();
1592545937e1SDimitry Andric         if (!Stack.back().HasBeenEmitted) {
1593545937e1SDimitry Andric           if (HaveIP)
1594545937e1SDimitry Andric             CGF.EmitBranchThroughCleanup(Stack.back().ContBlock);
1595545937e1SDimitry Andric           CGF.EmitBlock(Stack.back().ExitBlock.getBlock());
1596545937e1SDimitry Andric           CGF.EmitBranchThroughCleanup(Stack.back().ContBlock);
1597545937e1SDimitry Andric         }
1598545937e1SDimitry Andric         CGF.EmitBlock(Stack.back().ContBlock.getBlock());
1599545937e1SDimitry Andric         if (!HaveIP) {
1600545937e1SDimitry Andric           CGF.Builder.CreateUnreachable();
1601545937e1SDimitry Andric           CGF.Builder.ClearInsertionPoint();
1602545937e1SDimitry Andric         }
1603545937e1SDimitry Andric       }
1604545937e1SDimitry Andric       Stack.pop_back();
1605545937e1SDimitry Andric     }
1606545937e1SDimitry Andric   };
1607545937e1SDimitry Andric   OpenMPCancelExitStack OMPCancelStack;
160817c7957fSDimitry Andric 
1609344a3780SDimitry Andric   /// Lower the Likelihood knowledge about the \p Cond via llvm.expect intrin.
1610344a3780SDimitry Andric   llvm::Value *emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond,
1611344a3780SDimitry Andric                                                     Stmt::Likelihood LH);
1612b60736ecSDimitry Andric 
16139f4dbff6SDimitry Andric   CodeGenPGO PGO;
16149f4dbff6SDimitry Andric 
1615aca2e42cSDimitry Andric   /// Bitmap used by MC/DC to track condition outcomes of a boolean expression.
1616aca2e42cSDimitry Andric   Address MCDCCondBitmapAddr = Address::invalid();
1617aca2e42cSDimitry Andric 
16185e20cdd8SDimitry Andric   /// Calculate branch weights appropriate for PGO data
1619b60736ecSDimitry Andric   llvm::MDNode *createProfileWeights(uint64_t TrueCount,
1620b60736ecSDimitry Andric                                      uint64_t FalseCount) const;
1621b60736ecSDimitry Andric   llvm::MDNode *createProfileWeights(ArrayRef<uint64_t> Weights) const;
16225e20cdd8SDimitry Andric   llvm::MDNode *createProfileWeightsForLoop(const Stmt *Cond,
1623b60736ecSDimitry Andric                                             uint64_t LoopCount) const;
1624b60736ecSDimitry Andric 
16259f4dbff6SDimitry Andric public:
16267442d6faSDimitry Andric   /// Increment the profiler's counter for the given statement by \p StepV.
16277442d6faSDimitry Andric   /// If \p StepV is null, the default increment is 1.
16287442d6faSDimitry Andric   void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) {
1629b60736ecSDimitry Andric     if (CGM.getCodeGenOpts().hasProfileClangInstr() &&
1630e3b55780SDimitry Andric         !CurFn->hasFnAttribute(llvm::Attribute::NoProfile) &&
1631ac9a064cSDimitry Andric         !CurFn->hasFnAttribute(llvm::Attribute::SkipProfile)) {
1632ac9a064cSDimitry Andric       auto AL = ApplyDebugLocation::CreateArtificial(*this);
1633ac9a064cSDimitry Andric       PGO.emitCounterSetOrIncrement(Builder, S, StepV);
1634ac9a064cSDimitry Andric     }
16355e20cdd8SDimitry Andric     PGO.setCurrentStmt(S);
16369f4dbff6SDimitry Andric   }
16375e20cdd8SDimitry Andric 
1638aca2e42cSDimitry Andric   bool isMCDCCoverageEnabled() const {
1639aca2e42cSDimitry Andric     return (CGM.getCodeGenOpts().hasProfileClangInstr() &&
1640aca2e42cSDimitry Andric             CGM.getCodeGenOpts().MCDCCoverage &&
1641aca2e42cSDimitry Andric             !CurFn->hasFnAttribute(llvm::Attribute::NoProfile));
1642aca2e42cSDimitry Andric   }
1643aca2e42cSDimitry Andric 
1644aca2e42cSDimitry Andric   /// Allocate a temp value on the stack that MCDC can use to track condition
1645aca2e42cSDimitry Andric   /// results.
1646aca2e42cSDimitry Andric   void maybeCreateMCDCCondBitmap() {
1647aca2e42cSDimitry Andric     if (isMCDCCoverageEnabled()) {
1648aca2e42cSDimitry Andric       PGO.emitMCDCParameters(Builder);
1649aca2e42cSDimitry Andric       MCDCCondBitmapAddr =
1650aca2e42cSDimitry Andric           CreateIRTemp(getContext().UnsignedIntTy, "mcdc.addr");
1651aca2e42cSDimitry Andric     }
1652aca2e42cSDimitry Andric   }
1653aca2e42cSDimitry Andric 
1654aca2e42cSDimitry Andric   bool isBinaryLogicalOp(const Expr *E) const {
1655aca2e42cSDimitry Andric     const BinaryOperator *BOp = dyn_cast<BinaryOperator>(E->IgnoreParens());
1656aca2e42cSDimitry Andric     return (BOp && BOp->isLogicalOp());
1657aca2e42cSDimitry Andric   }
1658aca2e42cSDimitry Andric 
1659aca2e42cSDimitry Andric   /// Zero-init the MCDC temp value.
1660aca2e42cSDimitry Andric   void maybeResetMCDCCondBitmap(const Expr *E) {
1661aca2e42cSDimitry Andric     if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) {
1662aca2e42cSDimitry Andric       PGO.emitMCDCCondBitmapReset(Builder, E, MCDCCondBitmapAddr);
1663aca2e42cSDimitry Andric       PGO.setCurrentStmt(E);
1664aca2e42cSDimitry Andric     }
1665aca2e42cSDimitry Andric   }
1666aca2e42cSDimitry Andric 
1667aca2e42cSDimitry Andric   /// Increment the profiler's counter for the given expression by \p StepV.
1668aca2e42cSDimitry Andric   /// If \p StepV is null, the default increment is 1.
1669aca2e42cSDimitry Andric   void maybeUpdateMCDCTestVectorBitmap(const Expr *E) {
1670aca2e42cSDimitry Andric     if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) {
1671ac9a064cSDimitry Andric       PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, MCDCCondBitmapAddr, *this);
1672aca2e42cSDimitry Andric       PGO.setCurrentStmt(E);
1673aca2e42cSDimitry Andric     }
1674aca2e42cSDimitry Andric   }
1675aca2e42cSDimitry Andric 
1676aca2e42cSDimitry Andric   /// Update the MCDC temp value with the condition's evaluated result.
1677aca2e42cSDimitry Andric   void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val) {
1678aca2e42cSDimitry Andric     if (isMCDCCoverageEnabled()) {
1679ac9a064cSDimitry Andric       PGO.emitMCDCCondBitmapUpdate(Builder, E, MCDCCondBitmapAddr, Val, *this);
1680aca2e42cSDimitry Andric       PGO.setCurrentStmt(E);
1681aca2e42cSDimitry Andric     }
1682aca2e42cSDimitry Andric   }
1683aca2e42cSDimitry Andric 
16845e20cdd8SDimitry Andric   /// Get the profiler's count for the given statement.
16855e20cdd8SDimitry Andric   uint64_t getProfileCount(const Stmt *S) {
1686145449b1SDimitry Andric     return PGO.getStmtCount(S).value_or(0);
16875e20cdd8SDimitry Andric   }
16885e20cdd8SDimitry Andric 
16895e20cdd8SDimitry Andric   /// Set the profiler's current count.
16905e20cdd8SDimitry Andric   void setCurrentProfileCount(uint64_t Count) {
16915e20cdd8SDimitry Andric     PGO.setCurrentRegionCount(Count);
16925e20cdd8SDimitry Andric   }
16935e20cdd8SDimitry Andric 
16945e20cdd8SDimitry Andric   /// Get the profiler's current count. This is generally the count for the most
16955e20cdd8SDimitry Andric   /// recently incremented counter.
16965e20cdd8SDimitry Andric   uint64_t getCurrentProfileCount() {
16975e20cdd8SDimitry Andric     return PGO.getCurrentRegionCount();
16985e20cdd8SDimitry Andric   }
16995e20cdd8SDimitry Andric 
17009f4dbff6SDimitry Andric private:
17019f4dbff6SDimitry Andric 
1702dbe13110SDimitry Andric   /// SwitchInsn - This is nearest current switch instruction. It is null if
1703ec2b103cSEd Schouten   /// current context is not in a switch.
170448675466SDimitry Andric   llvm::SwitchInst *SwitchInsn = nullptr;
17059f4dbff6SDimitry Andric   /// The branch weights of SwitchInsn when doing instrumentation based PGO.
170648675466SDimitry Andric   SmallVector<uint64_t, 16> *SwitchWeights = nullptr;
1707ec2b103cSEd Schouten 
1708b60736ecSDimitry Andric   /// The likelihood attributes of the SwitchCase.
1709b60736ecSDimitry Andric   SmallVector<Stmt::Likelihood, 16> *SwitchLikelihood = nullptr;
1710b60736ecSDimitry Andric 
1711ec2b103cSEd Schouten   /// CaseRangeBlock - This block holds if condition check for last case
1712ec2b103cSEd Schouten   /// statement range in current switch instruction.
171348675466SDimitry Andric   llvm::BasicBlock *CaseRangeBlock = nullptr;
1714ec2b103cSEd Schouten 
1715bca07a45SDimitry Andric   /// OpaqueLValues - Keeps track of the current set of opaque value
1716bca07a45SDimitry Andric   /// expressions.
1717bca07a45SDimitry Andric   llvm::DenseMap<const OpaqueValueExpr *, LValue> OpaqueLValues;
1718bca07a45SDimitry Andric   llvm::DenseMap<const OpaqueValueExpr *, RValue> OpaqueRValues;
1719bca07a45SDimitry Andric 
1720ec2b103cSEd Schouten   // VLASizeMap - This keeps track of the associated size for each VLA type.
17214c8b2481SRoman Divacky   // We track this by the size expression rather than the type itself because
17224c8b2481SRoman Divacky   // in certain situations, like a const qualifier applied to an VLA typedef,
17234c8b2481SRoman Divacky   // multiple VLA types can share the same size expression.
1724ec2b103cSEd Schouten   // FIXME: Maybe this could be a stack of maps that is pushed/popped as we
1725ec2b103cSEd Schouten   // enter/leave scopes.
17264c8b2481SRoman Divacky   llvm::DenseMap<const Expr*, llvm::Value*> VLASizeMap;
1727ec2b103cSEd Schouten 
17284ba67500SRoman Divacky   /// A block containing a single 'unreachable' instruction.  Created
17294ba67500SRoman Divacky   /// lazily by getUnreachableBlock().
173048675466SDimitry Andric   llvm::BasicBlock *UnreachableBlock = nullptr;
1731ec2b103cSEd Schouten 
17326a037251SDimitry Andric   /// Counts of the number return expressions in the function.
173348675466SDimitry Andric   unsigned NumReturnExprs = 0;
17346a037251SDimitry Andric 
17356a037251SDimitry Andric   /// Count the number of simple (constant) return expressions in the function.
173648675466SDimitry Andric   unsigned NumSimpleReturnExprs = 0;
17376a037251SDimitry Andric 
17386a037251SDimitry Andric   /// The last regular (non-return) debug location (breakpoint) in the function.
17396a037251SDimitry Andric   SourceLocation LastStopPoint;
17406a037251SDimitry Andric 
17416a037251SDimitry Andric public:
174222989816SDimitry Andric   /// Source location information about the default argument or member
174322989816SDimitry Andric   /// initializer expression we're evaluating, if any.
174422989816SDimitry Andric   CurrentSourceLocExprScope CurSourceLocExprScope;
174522989816SDimitry Andric   using SourceLocExprScopeGuard =
174622989816SDimitry Andric       CurrentSourceLocExprScope::SourceLocExprScopeGuard;
174722989816SDimitry Andric 
17486a037251SDimitry Andric   /// A scope within which we are constructing the fields of an object which
17496a037251SDimitry Andric   /// might use a CXXDefaultInitExpr. This stashes away a 'this' value to use
17506a037251SDimitry Andric   /// if we need to evaluate a CXXDefaultInitExpr within the evaluation.
17516a037251SDimitry Andric   class FieldConstructionScope {
17526a037251SDimitry Andric   public:
175345b53394SDimitry Andric     FieldConstructionScope(CodeGenFunction &CGF, Address This)
17546a037251SDimitry Andric         : CGF(CGF), OldCXXDefaultInitExprThis(CGF.CXXDefaultInitExprThis) {
17556a037251SDimitry Andric       CGF.CXXDefaultInitExprThis = This;
17566a037251SDimitry Andric     }
17576a037251SDimitry Andric     ~FieldConstructionScope() {
17586a037251SDimitry Andric       CGF.CXXDefaultInitExprThis = OldCXXDefaultInitExprThis;
17596a037251SDimitry Andric     }
17606a037251SDimitry Andric 
17616a037251SDimitry Andric   private:
17626a037251SDimitry Andric     CodeGenFunction &CGF;
176345b53394SDimitry Andric     Address OldCXXDefaultInitExprThis;
17646a037251SDimitry Andric   };
17656a037251SDimitry Andric 
17666a037251SDimitry Andric   /// The scope of a CXXDefaultInitExpr. Within this scope, the value of 'this'
17676a037251SDimitry Andric   /// is overridden to be the object under construction.
17686a037251SDimitry Andric   class CXXDefaultInitExprScope  {
17696a037251SDimitry Andric   public:
177022989816SDimitry Andric     CXXDefaultInitExprScope(CodeGenFunction &CGF, const CXXDefaultInitExpr *E)
177145b53394SDimitry Andric         : CGF(CGF), OldCXXThisValue(CGF.CXXThisValue),
177222989816SDimitry Andric           OldCXXThisAlignment(CGF.CXXThisAlignment),
177322989816SDimitry Andric           SourceLocScope(E, CGF.CurSourceLocExprScope) {
1774ac9a064cSDimitry Andric       CGF.CXXThisValue = CGF.CXXDefaultInitExprThis.getBasePointer();
177545b53394SDimitry Andric       CGF.CXXThisAlignment = CGF.CXXDefaultInitExprThis.getAlignment();
17766a037251SDimitry Andric     }
17776a037251SDimitry Andric     ~CXXDefaultInitExprScope() {
17786a037251SDimitry Andric       CGF.CXXThisValue = OldCXXThisValue;
177945b53394SDimitry Andric       CGF.CXXThisAlignment = OldCXXThisAlignment;
17806a037251SDimitry Andric     }
17816a037251SDimitry Andric 
17826a037251SDimitry Andric   public:
17836a037251SDimitry Andric     CodeGenFunction &CGF;
17846a037251SDimitry Andric     llvm::Value *OldCXXThisValue;
178545b53394SDimitry Andric     CharUnits OldCXXThisAlignment;
178622989816SDimitry Andric     SourceLocExprScopeGuard SourceLocScope;
178722989816SDimitry Andric   };
178822989816SDimitry Andric 
178922989816SDimitry Andric   struct CXXDefaultArgExprScope : SourceLocExprScopeGuard {
179022989816SDimitry Andric     CXXDefaultArgExprScope(CodeGenFunction &CGF, const CXXDefaultArgExpr *E)
179122989816SDimitry Andric         : SourceLocExprScopeGuard(E, CGF.CurSourceLocExprScope) {}
17926a037251SDimitry Andric   };
17936a037251SDimitry Andric 
1794bab175ecSDimitry Andric   /// The scope of an ArrayInitLoopExpr. Within this scope, the value of the
1795bab175ecSDimitry Andric   /// current loop index is overridden.
1796bab175ecSDimitry Andric   class ArrayInitLoopExprScope {
1797bab175ecSDimitry Andric   public:
1798bab175ecSDimitry Andric     ArrayInitLoopExprScope(CodeGenFunction &CGF, llvm::Value *Index)
1799bab175ecSDimitry Andric       : CGF(CGF), OldArrayInitIndex(CGF.ArrayInitIndex) {
1800bab175ecSDimitry Andric       CGF.ArrayInitIndex = Index;
1801bab175ecSDimitry Andric     }
1802bab175ecSDimitry Andric     ~ArrayInitLoopExprScope() {
1803bab175ecSDimitry Andric       CGF.ArrayInitIndex = OldArrayInitIndex;
1804bab175ecSDimitry Andric     }
1805bab175ecSDimitry Andric 
1806bab175ecSDimitry Andric   private:
1807bab175ecSDimitry Andric     CodeGenFunction &CGF;
1808bab175ecSDimitry Andric     llvm::Value *OldArrayInitIndex;
1809bab175ecSDimitry Andric   };
1810bab175ecSDimitry Andric 
18112b6b257fSDimitry Andric   class InlinedInheritingConstructorScope {
18122b6b257fSDimitry Andric   public:
18132b6b257fSDimitry Andric     InlinedInheritingConstructorScope(CodeGenFunction &CGF, GlobalDecl GD)
18142b6b257fSDimitry Andric         : CGF(CGF), OldCurGD(CGF.CurGD), OldCurFuncDecl(CGF.CurFuncDecl),
18152b6b257fSDimitry Andric           OldCurCodeDecl(CGF.CurCodeDecl),
18162b6b257fSDimitry Andric           OldCXXABIThisDecl(CGF.CXXABIThisDecl),
18172b6b257fSDimitry Andric           OldCXXABIThisValue(CGF.CXXABIThisValue),
18182b6b257fSDimitry Andric           OldCXXThisValue(CGF.CXXThisValue),
18192b6b257fSDimitry Andric           OldCXXABIThisAlignment(CGF.CXXABIThisAlignment),
18202b6b257fSDimitry Andric           OldCXXThisAlignment(CGF.CXXThisAlignment),
18212b6b257fSDimitry Andric           OldReturnValue(CGF.ReturnValue), OldFnRetTy(CGF.FnRetTy),
18222b6b257fSDimitry Andric           OldCXXInheritedCtorInitExprArgs(
18232b6b257fSDimitry Andric               std::move(CGF.CXXInheritedCtorInitExprArgs)) {
18242b6b257fSDimitry Andric       CGF.CurGD = GD;
18252b6b257fSDimitry Andric       CGF.CurFuncDecl = CGF.CurCodeDecl =
18262b6b257fSDimitry Andric           cast<CXXConstructorDecl>(GD.getDecl());
18272b6b257fSDimitry Andric       CGF.CXXABIThisDecl = nullptr;
18282b6b257fSDimitry Andric       CGF.CXXABIThisValue = nullptr;
18292b6b257fSDimitry Andric       CGF.CXXThisValue = nullptr;
18302b6b257fSDimitry Andric       CGF.CXXABIThisAlignment = CharUnits();
18312b6b257fSDimitry Andric       CGF.CXXThisAlignment = CharUnits();
18322b6b257fSDimitry Andric       CGF.ReturnValue = Address::invalid();
18332b6b257fSDimitry Andric       CGF.FnRetTy = QualType();
18342b6b257fSDimitry Andric       CGF.CXXInheritedCtorInitExprArgs.clear();
18352b6b257fSDimitry Andric     }
18362b6b257fSDimitry Andric     ~InlinedInheritingConstructorScope() {
18372b6b257fSDimitry Andric       CGF.CurGD = OldCurGD;
18382b6b257fSDimitry Andric       CGF.CurFuncDecl = OldCurFuncDecl;
18392b6b257fSDimitry Andric       CGF.CurCodeDecl = OldCurCodeDecl;
18402b6b257fSDimitry Andric       CGF.CXXABIThisDecl = OldCXXABIThisDecl;
18412b6b257fSDimitry Andric       CGF.CXXABIThisValue = OldCXXABIThisValue;
18422b6b257fSDimitry Andric       CGF.CXXThisValue = OldCXXThisValue;
18432b6b257fSDimitry Andric       CGF.CXXABIThisAlignment = OldCXXABIThisAlignment;
18442b6b257fSDimitry Andric       CGF.CXXThisAlignment = OldCXXThisAlignment;
18452b6b257fSDimitry Andric       CGF.ReturnValue = OldReturnValue;
18462b6b257fSDimitry Andric       CGF.FnRetTy = OldFnRetTy;
18472b6b257fSDimitry Andric       CGF.CXXInheritedCtorInitExprArgs =
18482b6b257fSDimitry Andric           std::move(OldCXXInheritedCtorInitExprArgs);
18492b6b257fSDimitry Andric     }
18502b6b257fSDimitry Andric 
18512b6b257fSDimitry Andric   private:
18522b6b257fSDimitry Andric     CodeGenFunction &CGF;
18532b6b257fSDimitry Andric     GlobalDecl OldCurGD;
18542b6b257fSDimitry Andric     const Decl *OldCurFuncDecl;
18552b6b257fSDimitry Andric     const Decl *OldCurCodeDecl;
18562b6b257fSDimitry Andric     ImplicitParamDecl *OldCXXABIThisDecl;
18572b6b257fSDimitry Andric     llvm::Value *OldCXXABIThisValue;
18582b6b257fSDimitry Andric     llvm::Value *OldCXXThisValue;
18592b6b257fSDimitry Andric     CharUnits OldCXXABIThisAlignment;
18602b6b257fSDimitry Andric     CharUnits OldCXXThisAlignment;
18612b6b257fSDimitry Andric     Address OldReturnValue;
18622b6b257fSDimitry Andric     QualType OldFnRetTy;
18632b6b257fSDimitry Andric     CallArgList OldCXXInheritedCtorInitExprArgs;
18642b6b257fSDimitry Andric   };
18652b6b257fSDimitry Andric 
1866cfca06d7SDimitry Andric   // Helper class for the OpenMP IR Builder. Allows reusability of code used for
1867cfca06d7SDimitry Andric   // region body, and finalization codegen callbacks. This will class will also
1868cfca06d7SDimitry Andric   // contain privatization functions used by the privatization call backs
1869cfca06d7SDimitry Andric   //
1870cfca06d7SDimitry Andric   // TODO: this is temporary class for things that are being moved out of
1871cfca06d7SDimitry Andric   // CGOpenMPRuntime, new versions of current CodeGenFunction methods, or
1872cfca06d7SDimitry Andric   // utility function for use with the OMPBuilder. Once that move to use the
1873cfca06d7SDimitry Andric   // OMPBuilder is done, everything here will either become part of CodeGenFunc.
1874cfca06d7SDimitry Andric   // directly, or a new helper class that will contain functions used by both
1875cfca06d7SDimitry Andric   // this and the OMPBuilder
1876cfca06d7SDimitry Andric 
1877cfca06d7SDimitry Andric   struct OMPBuilderCBHelpers {
1878cfca06d7SDimitry Andric 
1879cfca06d7SDimitry Andric     OMPBuilderCBHelpers() = delete;
1880cfca06d7SDimitry Andric     OMPBuilderCBHelpers(const OMPBuilderCBHelpers &) = delete;
1881cfca06d7SDimitry Andric     OMPBuilderCBHelpers &operator=(const OMPBuilderCBHelpers &) = delete;
1882cfca06d7SDimitry Andric 
1883cfca06d7SDimitry Andric     using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
1884cfca06d7SDimitry Andric 
1885cfca06d7SDimitry Andric     /// Cleanup action for allocate support.
1886cfca06d7SDimitry Andric     class OMPAllocateCleanupTy final : public EHScopeStack::Cleanup {
1887cfca06d7SDimitry Andric 
1888cfca06d7SDimitry Andric     private:
1889cfca06d7SDimitry Andric       llvm::CallInst *RTLFnCI;
1890cfca06d7SDimitry Andric 
1891cfca06d7SDimitry Andric     public:
1892cfca06d7SDimitry Andric       OMPAllocateCleanupTy(llvm::CallInst *RLFnCI) : RTLFnCI(RLFnCI) {
1893cfca06d7SDimitry Andric         RLFnCI->removeFromParent();
1894cfca06d7SDimitry Andric       }
1895cfca06d7SDimitry Andric 
1896cfca06d7SDimitry Andric       void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
1897cfca06d7SDimitry Andric         if (!CGF.HaveInsertPoint())
1898cfca06d7SDimitry Andric           return;
1899cfca06d7SDimitry Andric         CGF.Builder.Insert(RTLFnCI);
1900cfca06d7SDimitry Andric       }
1901cfca06d7SDimitry Andric     };
1902cfca06d7SDimitry Andric 
1903cfca06d7SDimitry Andric     /// Returns address of the threadprivate variable for the current
1904cfca06d7SDimitry Andric     /// thread. This Also create any necessary OMP runtime calls.
1905cfca06d7SDimitry Andric     ///
1906cfca06d7SDimitry Andric     /// \param VD VarDecl for Threadprivate variable.
1907cfca06d7SDimitry Andric     /// \param VDAddr Address of the Vardecl
1908cfca06d7SDimitry Andric     /// \param Loc  The location where the barrier directive was encountered
1909cfca06d7SDimitry Andric     static Address getAddrOfThreadPrivate(CodeGenFunction &CGF,
1910cfca06d7SDimitry Andric                                           const VarDecl *VD, Address VDAddr,
1911cfca06d7SDimitry Andric                                           SourceLocation Loc);
1912cfca06d7SDimitry Andric 
1913cfca06d7SDimitry Andric     /// Gets the OpenMP-specific address of the local variable /p VD.
1914cfca06d7SDimitry Andric     static Address getAddressOfLocalVariable(CodeGenFunction &CGF,
1915cfca06d7SDimitry Andric                                              const VarDecl *VD);
1916cfca06d7SDimitry Andric     /// Get the platform-specific name separator.
1917cfca06d7SDimitry Andric     /// \param Parts different parts of the final name that needs separation
1918cfca06d7SDimitry Andric     /// \param FirstSeparator First separator used between the initial two
1919cfca06d7SDimitry Andric     ///        parts of the name.
1920cfca06d7SDimitry Andric     /// \param Separator separator used between all of the rest consecutinve
1921cfca06d7SDimitry Andric     ///        parts of the name
1922cfca06d7SDimitry Andric     static std::string getNameWithSeparators(ArrayRef<StringRef> Parts,
1923cfca06d7SDimitry Andric                                              StringRef FirstSeparator = ".",
1924cfca06d7SDimitry Andric                                              StringRef Separator = ".");
1925cfca06d7SDimitry Andric     /// Emit the Finalization for an OMP region
1926cfca06d7SDimitry Andric     /// \param CGF	The Codegen function this belongs to
1927cfca06d7SDimitry Andric     /// \param IP	Insertion point for generating the finalization code.
1928cfca06d7SDimitry Andric     static void FinalizeOMPRegion(CodeGenFunction &CGF, InsertPointTy IP) {
1929cfca06d7SDimitry Andric       CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
1930cfca06d7SDimitry Andric       assert(IP.getBlock()->end() != IP.getPoint() &&
1931cfca06d7SDimitry Andric              "OpenMP IR Builder should cause terminated block!");
1932cfca06d7SDimitry Andric 
1933cfca06d7SDimitry Andric       llvm::BasicBlock *IPBB = IP.getBlock();
1934cfca06d7SDimitry Andric       llvm::BasicBlock *DestBB = IPBB->getUniqueSuccessor();
1935cfca06d7SDimitry Andric       assert(DestBB && "Finalization block should have one successor!");
1936cfca06d7SDimitry Andric 
1937cfca06d7SDimitry Andric       // erase and replace with cleanup branch.
1938cfca06d7SDimitry Andric       IPBB->getTerminator()->eraseFromParent();
1939cfca06d7SDimitry Andric       CGF.Builder.SetInsertPoint(IPBB);
1940cfca06d7SDimitry Andric       CodeGenFunction::JumpDest Dest = CGF.getJumpDestInCurrentScope(DestBB);
1941cfca06d7SDimitry Andric       CGF.EmitBranchThroughCleanup(Dest);
1942cfca06d7SDimitry Andric     }
1943cfca06d7SDimitry Andric 
1944cfca06d7SDimitry Andric     /// Emit the body of an OMP region
1945cfca06d7SDimitry Andric     /// \param CGF	          The Codegen function this belongs to
1946cfca06d7SDimitry Andric     /// \param RegionBodyStmt The body statement for the OpenMP region being
1947cfca06d7SDimitry Andric     ///                       generated
1948145449b1SDimitry Andric     /// \param AllocaIP       Where to insert alloca instructions
1949145449b1SDimitry Andric     /// \param CodeGenIP      Where to insert the region code
1950145449b1SDimitry Andric     /// \param RegionName     Name to be used for new blocks
1951145449b1SDimitry Andric     static void EmitOMPInlinedRegionBody(CodeGenFunction &CGF,
1952cfca06d7SDimitry Andric                                          const Stmt *RegionBodyStmt,
1953145449b1SDimitry Andric                                          InsertPointTy AllocaIP,
1954cfca06d7SDimitry Andric                                          InsertPointTy CodeGenIP,
1955145449b1SDimitry Andric                                          Twine RegionName);
1956cfca06d7SDimitry Andric 
1957c0981da4SDimitry Andric     static void EmitCaptureStmt(CodeGenFunction &CGF, InsertPointTy CodeGenIP,
1958c0981da4SDimitry Andric                                 llvm::BasicBlock &FiniBB, llvm::Function *Fn,
1959c0981da4SDimitry Andric                                 ArrayRef<llvm::Value *> Args) {
1960c0981da4SDimitry Andric       llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock();
1961c0981da4SDimitry Andric       if (llvm::Instruction *CodeGenIPBBTI = CodeGenIPBB->getTerminator())
1962c0981da4SDimitry Andric         CodeGenIPBBTI->eraseFromParent();
1963c0981da4SDimitry Andric 
1964c0981da4SDimitry Andric       CGF.Builder.SetInsertPoint(CodeGenIPBB);
1965c0981da4SDimitry Andric 
1966c0981da4SDimitry Andric       if (Fn->doesNotThrow())
1967c0981da4SDimitry Andric         CGF.EmitNounwindRuntimeCall(Fn, Args);
1968c0981da4SDimitry Andric       else
1969c0981da4SDimitry Andric         CGF.EmitRuntimeCall(Fn, Args);
1970c0981da4SDimitry Andric 
1971c0981da4SDimitry Andric       if (CGF.Builder.saveIP().isSet())
1972c0981da4SDimitry Andric         CGF.Builder.CreateBr(&FiniBB);
1973c0981da4SDimitry Andric     }
1974c0981da4SDimitry Andric 
1975145449b1SDimitry Andric     /// Emit the body of an OMP region that will be outlined in
1976145449b1SDimitry Andric     /// OpenMPIRBuilder::finalize().
1977145449b1SDimitry Andric     /// \param CGF	          The Codegen function this belongs to
1978145449b1SDimitry Andric     /// \param RegionBodyStmt The body statement for the OpenMP region being
1979145449b1SDimitry Andric     ///                       generated
1980145449b1SDimitry Andric     /// \param AllocaIP       Where to insert alloca instructions
1981145449b1SDimitry Andric     /// \param CodeGenIP      Where to insert the region code
1982145449b1SDimitry Andric     /// \param RegionName     Name to be used for new blocks
1983145449b1SDimitry Andric     static void EmitOMPOutlinedRegionBody(CodeGenFunction &CGF,
1984145449b1SDimitry Andric                                           const Stmt *RegionBodyStmt,
1985145449b1SDimitry Andric                                           InsertPointTy AllocaIP,
1986145449b1SDimitry Andric                                           InsertPointTy CodeGenIP,
1987145449b1SDimitry Andric                                           Twine RegionName);
1988145449b1SDimitry Andric 
1989cfca06d7SDimitry Andric     /// RAII for preserving necessary info during Outlined region body codegen.
1990cfca06d7SDimitry Andric     class OutlinedRegionBodyRAII {
1991cfca06d7SDimitry Andric 
1992cfca06d7SDimitry Andric       llvm::AssertingVH<llvm::Instruction> OldAllocaIP;
1993cfca06d7SDimitry Andric       CodeGenFunction::JumpDest OldReturnBlock;
1994cfca06d7SDimitry Andric       CodeGenFunction &CGF;
1995cfca06d7SDimitry Andric 
1996cfca06d7SDimitry Andric     public:
1997cfca06d7SDimitry Andric       OutlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP,
1998cfca06d7SDimitry Andric                              llvm::BasicBlock &RetBB)
1999cfca06d7SDimitry Andric           : CGF(cgf) {
2000cfca06d7SDimitry Andric         assert(AllocaIP.isSet() &&
2001cfca06d7SDimitry Andric                "Must specify Insertion point for allocas of outlined function");
2002cfca06d7SDimitry Andric         OldAllocaIP = CGF.AllocaInsertPt;
2003cfca06d7SDimitry Andric         CGF.AllocaInsertPt = &*AllocaIP.getPoint();
2004cfca06d7SDimitry Andric 
2005cfca06d7SDimitry Andric         OldReturnBlock = CGF.ReturnBlock;
2006cfca06d7SDimitry Andric         CGF.ReturnBlock = CGF.getJumpDestInCurrentScope(&RetBB);
2007cfca06d7SDimitry Andric       }
2008cfca06d7SDimitry Andric 
2009cfca06d7SDimitry Andric       ~OutlinedRegionBodyRAII() {
2010cfca06d7SDimitry Andric         CGF.AllocaInsertPt = OldAllocaIP;
2011cfca06d7SDimitry Andric         CGF.ReturnBlock = OldReturnBlock;
2012cfca06d7SDimitry Andric       }
2013cfca06d7SDimitry Andric     };
2014cfca06d7SDimitry Andric 
2015cfca06d7SDimitry Andric     /// RAII for preserving necessary info during inlined region body codegen.
2016cfca06d7SDimitry Andric     class InlinedRegionBodyRAII {
2017cfca06d7SDimitry Andric 
2018cfca06d7SDimitry Andric       llvm::AssertingVH<llvm::Instruction> OldAllocaIP;
2019cfca06d7SDimitry Andric       CodeGenFunction &CGF;
2020cfca06d7SDimitry Andric 
2021cfca06d7SDimitry Andric     public:
2022cfca06d7SDimitry Andric       InlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP,
2023cfca06d7SDimitry Andric                             llvm::BasicBlock &FiniBB)
2024cfca06d7SDimitry Andric           : CGF(cgf) {
2025cfca06d7SDimitry Andric         // Alloca insertion block should be in the entry block of the containing
2026cfca06d7SDimitry Andric         // function so it expects an empty AllocaIP in which case will reuse the
2027cfca06d7SDimitry Andric         // old alloca insertion point, or a new AllocaIP in the same block as
2028cfca06d7SDimitry Andric         // the old one
2029cfca06d7SDimitry Andric         assert((!AllocaIP.isSet() ||
2030cfca06d7SDimitry Andric                 CGF.AllocaInsertPt->getParent() == AllocaIP.getBlock()) &&
2031cfca06d7SDimitry Andric                "Insertion point should be in the entry block of containing "
2032cfca06d7SDimitry Andric                "function!");
2033cfca06d7SDimitry Andric         OldAllocaIP = CGF.AllocaInsertPt;
2034cfca06d7SDimitry Andric         if (AllocaIP.isSet())
2035cfca06d7SDimitry Andric           CGF.AllocaInsertPt = &*AllocaIP.getPoint();
2036cfca06d7SDimitry Andric 
2037cfca06d7SDimitry Andric         // TODO: Remove the call, after making sure the counter is not used by
2038cfca06d7SDimitry Andric         //       the EHStack.
2039cfca06d7SDimitry Andric         // Since this is an inlined region, it should not modify the
2040cfca06d7SDimitry Andric         // ReturnBlock, and should reuse the one for the enclosing outlined
2041cfca06d7SDimitry Andric         // region. So, the JumpDest being return by the function is discarded
2042cfca06d7SDimitry Andric         (void)CGF.getJumpDestInCurrentScope(&FiniBB);
2043cfca06d7SDimitry Andric       }
2044cfca06d7SDimitry Andric 
2045cfca06d7SDimitry Andric       ~InlinedRegionBodyRAII() { CGF.AllocaInsertPt = OldAllocaIP; }
2046cfca06d7SDimitry Andric     };
2047cfca06d7SDimitry Andric   };
2048cfca06d7SDimitry Andric 
20496a037251SDimitry Andric private:
20501569ce68SRoman Divacky   /// CXXThisDecl - When generating code for a C++ member function,
20511569ce68SRoman Divacky   /// this will hold the implicit 'this' declaration.
205248675466SDimitry Andric   ImplicitParamDecl *CXXABIThisDecl = nullptr;
205348675466SDimitry Andric   llvm::Value *CXXABIThisValue = nullptr;
205448675466SDimitry Andric   llvm::Value *CXXThisValue = nullptr;
205545b53394SDimitry Andric   CharUnits CXXABIThisAlignment;
205645b53394SDimitry Andric   CharUnits CXXThisAlignment;
2057ec2b103cSEd Schouten 
20586a037251SDimitry Andric   /// The value of 'this' to use when evaluating CXXDefaultInitExprs within
20596a037251SDimitry Andric   /// this expression.
206045b53394SDimitry Andric   Address CXXDefaultInitExprThis = Address::invalid();
20616a037251SDimitry Andric 
2062bab175ecSDimitry Andric   /// The current array initialization index when evaluating an
2063bab175ecSDimitry Andric   /// ArrayInitIndexExpr within an ArrayInitLoopExpr.
2064bab175ecSDimitry Andric   llvm::Value *ArrayInitIndex = nullptr;
2065bab175ecSDimitry Andric 
20662b6b257fSDimitry Andric   /// The values of function arguments to use when evaluating
20672b6b257fSDimitry Andric   /// CXXInheritedCtorInitExprs within this context.
20682b6b257fSDimitry Andric   CallArgList CXXInheritedCtorInitExprArgs;
20692b6b257fSDimitry Andric 
2070809500fcSDimitry Andric   /// CXXStructorImplicitParamDecl - When generating code for a constructor or
2071809500fcSDimitry Andric   /// destructor, this will hold the implicit argument (e.g. VTT).
207248675466SDimitry Andric   ImplicitParamDecl *CXXStructorImplicitParamDecl = nullptr;
207348675466SDimitry Andric   llvm::Value *CXXStructorImplicitParamValue = nullptr;
20741569ce68SRoman Divacky 
2075bca07a45SDimitry Andric   /// OutermostConditional - Points to the outermost active
2076bca07a45SDimitry Andric   /// conditional control.  This is used so that we know if a
2077bca07a45SDimitry Andric   /// temporary should be destroyed conditionally.
207848675466SDimitry Andric   ConditionalEvaluation *OutermostConditional = nullptr;
207937f6c480SEd Schouten 
2080809500fcSDimitry Andric   /// The current lexical scope.
208148675466SDimitry Andric   LexicalScope *CurLexicalScope = nullptr;
20824c8b2481SRoman Divacky 
2083bfef3995SDimitry Andric   /// The current source location that should be used for exception
2084bfef3995SDimitry Andric   /// handling code.
2085bfef3995SDimitry Andric   SourceLocation CurEHLocation;
2086bfef3995SDimitry Andric 
208745b53394SDimitry Andric   /// BlockByrefInfos - For each __block variable, contains
208845b53394SDimitry Andric   /// information about the layout of the variable.
208945b53394SDimitry Andric   llvm::DenseMap<const ValueDecl *, BlockByrefInfo> BlockByrefInfos;
20904c8b2481SRoman Divacky 
20917442d6faSDimitry Andric   /// Used by -fsanitize=nullability-return to determine whether the return
20927442d6faSDimitry Andric   /// value can be checked.
20937442d6faSDimitry Andric   llvm::Value *RetValNullabilityPrecondition = nullptr;
20947442d6faSDimitry Andric 
20957442d6faSDimitry Andric   /// Check if -fsanitize=nullability-return instrumentation is required for
20967442d6faSDimitry Andric   /// this function.
20977442d6faSDimitry Andric   bool requiresReturnValueNullabilityCheck() const {
20987442d6faSDimitry Andric     return RetValNullabilityPrecondition;
20997442d6faSDimitry Andric   }
21007442d6faSDimitry Andric 
2101ef915aabSDimitry Andric   /// Used to store precise source locations for return statements by the
2102ef915aabSDimitry Andric   /// runtime return value checks.
2103ef915aabSDimitry Andric   Address ReturnLocation = Address::invalid();
2104ef915aabSDimitry Andric 
2105ef915aabSDimitry Andric   /// Check if the return value of this function requires sanitization.
2106706b4fc4SDimitry Andric   bool requiresReturnValueCheck() const;
2107ef915aabSDimitry Andric 
2108b1c73532SDimitry Andric   bool isInAllocaArgument(CGCXXABI &ABI, QualType Ty);
2109b1c73532SDimitry Andric   bool hasInAllocaArg(const CXXMethodDecl *MD);
2110b1c73532SDimitry Andric 
211148675466SDimitry Andric   llvm::BasicBlock *TerminateLandingPad = nullptr;
211248675466SDimitry Andric   llvm::BasicBlock *TerminateHandler = nullptr;
2113b60736ecSDimitry Andric   llvm::SmallVector<llvm::BasicBlock *, 2> TrapBBs;
211448675466SDimitry Andric 
211548675466SDimitry Andric   /// Terminate funclets keyed by parent funclet pad.
211648675466SDimitry Andric   llvm::MapVector<llvm::Value *, llvm::BasicBlock *> TerminateFunclets;
211748675466SDimitry Andric 
211848675466SDimitry Andric   /// Largest vector width used in ths function. Will be used to create a
211948675466SDimitry Andric   /// function attribute.
212048675466SDimitry Andric   unsigned LargestVectorWidth = 0;
212134d02d0bSRoman Divacky 
2122344a3780SDimitry Andric   /// True if we need emit the life-time markers. This is initially set in
2123344a3780SDimitry Andric   /// the constructor, but could be overwritten to true if this is a coroutine.
2124344a3780SDimitry Andric   bool ShouldEmitLifetimeMarkers;
2125bab175ecSDimitry Andric 
212648675466SDimitry Andric   /// Add OpenCL kernel arg metadata and the kernel attribute metadata to
21270a5fb09bSDimitry Andric   /// the function metadata.
2128145449b1SDimitry Andric   void EmitKernelMetadata(const FunctionDecl *FD, llvm::Function *Fn);
212956d91b49SDimitry Andric 
2130ec2b103cSEd Schouten public:
213156d91b49SDimitry Andric   CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext=false);
2132dbe13110SDimitry Andric   ~CodeGenFunction();
2133ec2b103cSEd Schouten 
21343d1dcd9bSDimitry Andric   CodeGenTypes &getTypes() const { return CGM.getTypes(); }
213529cafa66SDimitry Andric   ASTContext &getContext() const { return CGM.getContext(); }
213601af97d3SDimitry Andric   CGDebugInfo *getDebugInfo() {
213701af97d3SDimitry Andric     if (DisableDebugInfo)
21389f4dbff6SDimitry Andric       return nullptr;
213901af97d3SDimitry Andric     return DebugInfo;
214001af97d3SDimitry Andric   }
214101af97d3SDimitry Andric   void disableDebugInfo() { DisableDebugInfo = true; }
214201af97d3SDimitry Andric   void enableDebugInfo() { DisableDebugInfo = false; }
214301af97d3SDimitry Andric 
2144180abc3dSDimitry Andric   bool shouldUseFusedARCCalls() {
2145180abc3dSDimitry Andric     return CGM.getCodeGenOpts().OptimizationLevel == 0;
2146180abc3dSDimitry Andric   }
2147ec2b103cSEd Schouten 
2148dbe13110SDimitry Andric   const LangOptions &getLangOpts() const { return CGM.getLangOpts(); }
2149bca07a45SDimitry Andric 
215036981b17SDimitry Andric   /// Returns a pointer to the function's exception object and selector slot,
215136981b17SDimitry Andric   /// which is assigned in every landing pad.
215245b53394SDimitry Andric   Address getExceptionSlot();
215345b53394SDimitry Andric   Address getEHSelectorSlot();
21544ba67500SRoman Divacky 
215536981b17SDimitry Andric   /// Returns the contents of the function's exception object and selector
215636981b17SDimitry Andric   /// slots.
215736981b17SDimitry Andric   llvm::Value *getExceptionFromSlot();
215836981b17SDimitry Andric   llvm::Value *getSelectorFromSlot();
215936981b17SDimitry Andric 
2160ac9a064cSDimitry Andric   RawAddress getNormalCleanupDestSlot();
21613d1dcd9bSDimitry Andric 
21624ba67500SRoman Divacky   llvm::BasicBlock *getUnreachableBlock() {
21634ba67500SRoman Divacky     if (!UnreachableBlock) {
21644ba67500SRoman Divacky       UnreachableBlock = createBasicBlock("unreachable");
21654ba67500SRoman Divacky       new llvm::UnreachableInst(getLLVMContext(), UnreachableBlock);
21664ba67500SRoman Divacky     }
21674ba67500SRoman Divacky     return UnreachableBlock;
21684ba67500SRoman Divacky   }
21694ba67500SRoman Divacky 
21704ba67500SRoman Divacky   llvm::BasicBlock *getInvokeDest() {
21719f4dbff6SDimitry Andric     if (!EHStack.requiresLandingPad()) return nullptr;
21724ba67500SRoman Divacky     return getInvokeDestImpl();
21734ba67500SRoman Divacky   }
2174ec2b103cSEd Schouten 
2175e3b55780SDimitry Andric   bool currentFunctionUsesSEHTry() const { return !!CurSEHParent; }
21765e20cdd8SDimitry Andric 
21776a037251SDimitry Andric   const TargetInfo &getTarget() const { return Target; }
2178bca07a45SDimitry Andric   llvm::LLVMContext &getLLVMContext() { return CGM.getLLVMContext(); }
21798746d127SDimitry Andric   const TargetCodeGenInfo &getTargetHooks() const {
21808746d127SDimitry Andric     return CGM.getTargetCodeGenInfo();
21818746d127SDimitry Andric   }
21824c8b2481SRoman Divacky 
2183ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
2184180abc3dSDimitry Andric   //                                  Cleanups
2185180abc3dSDimitry Andric   //===--------------------------------------------------------------------===//
2186180abc3dSDimitry Andric 
218745b53394SDimitry Andric   typedef void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty);
2188180abc3dSDimitry Andric 
2189180abc3dSDimitry Andric   void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
219045b53394SDimitry Andric                                         Address arrayEndPointer,
2191180abc3dSDimitry Andric                                         QualType elementType,
219245b53394SDimitry Andric                                         CharUnits elementAlignment,
2193dbe13110SDimitry Andric                                         Destroyer *destroyer);
2194180abc3dSDimitry Andric   void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin,
2195180abc3dSDimitry Andric                                       llvm::Value *arrayEnd,
2196180abc3dSDimitry Andric                                       QualType elementType,
219745b53394SDimitry Andric                                       CharUnits elementAlignment,
2198dbe13110SDimitry Andric                                       Destroyer *destroyer);
2199180abc3dSDimitry Andric 
2200180abc3dSDimitry Andric   void pushDestroy(QualType::DestructionKind dtorKind,
220145b53394SDimitry Andric                    Address addr, QualType type);
2202809500fcSDimitry Andric   void pushEHDestroy(QualType::DestructionKind dtorKind,
220345b53394SDimitry Andric                      Address addr, QualType type);
220445b53394SDimitry Andric   void pushDestroy(CleanupKind kind, Address addr, QualType type,
2205dbe13110SDimitry Andric                    Destroyer *destroyer, bool useEHCleanupForArray);
2206ac9a064cSDimitry Andric   void pushDestroyAndDeferDeactivation(QualType::DestructionKind dtorKind,
2207ac9a064cSDimitry Andric                                        Address addr, QualType type);
2208ac9a064cSDimitry Andric   void pushDestroyAndDeferDeactivation(CleanupKind cleanupKind, Address addr,
2209ac9a064cSDimitry Andric                                        QualType type, Destroyer *destroyer,
2210ac9a064cSDimitry Andric                                        bool useEHCleanupForArray);
221145b53394SDimitry Andric   void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr,
2212bfef3995SDimitry Andric                                    QualType type, Destroyer *destroyer,
2213bfef3995SDimitry Andric                                    bool useEHCleanupForArray);
221406d4ba38SDimitry Andric   void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete,
221506d4ba38SDimitry Andric                                    llvm::Value *CompletePtr,
221606d4ba38SDimitry Andric                                    QualType ElementType);
221745b53394SDimitry Andric   void pushStackRestore(CleanupKind kind, Address SPMem);
22187fa27ce4SDimitry Andric   void pushKmpcAllocFree(CleanupKind Kind,
22197fa27ce4SDimitry Andric                          std::pair<llvm::Value *, llvm::Value *> AddrSizePair);
222045b53394SDimitry Andric   void emitDestroy(Address addr, QualType type, Destroyer *destroyer,
2221180abc3dSDimitry Andric                    bool useEHCleanupForArray);
222245b53394SDimitry Andric   llvm::Function *generateDestroyHelper(Address addr, QualType type,
2223dbe13110SDimitry Andric                                         Destroyer *destroyer,
2224bfef3995SDimitry Andric                                         bool useEHCleanupForArray,
2225bfef3995SDimitry Andric                                         const VarDecl *VD);
2226180abc3dSDimitry Andric   void emitArrayDestroy(llvm::Value *begin, llvm::Value *end,
222745b53394SDimitry Andric                         QualType elementType, CharUnits elementAlign,
222845b53394SDimitry Andric                         Destroyer *destroyer,
2229180abc3dSDimitry Andric                         bool checkZeroLength, bool useEHCleanup);
2230180abc3dSDimitry Andric 
2231dbe13110SDimitry Andric   Destroyer *getDestroyer(QualType::DestructionKind destructionKind);
2232180abc3dSDimitry Andric 
2233180abc3dSDimitry Andric   /// Determines whether an EH cleanup is required to destroy a type
2234180abc3dSDimitry Andric   /// with the given destruction kind.
2235180abc3dSDimitry Andric   bool needsEHCleanup(QualType::DestructionKind kind) {
2236180abc3dSDimitry Andric     switch (kind) {
2237180abc3dSDimitry Andric     case QualType::DK_none:
2238180abc3dSDimitry Andric       return false;
2239180abc3dSDimitry Andric     case QualType::DK_cxx_destructor:
2240180abc3dSDimitry Andric     case QualType::DK_objc_weak_lifetime:
224148675466SDimitry Andric     case QualType::DK_nontrivial_c_struct:
2242dbe13110SDimitry Andric       return getLangOpts().Exceptions;
2243180abc3dSDimitry Andric     case QualType::DK_objc_strong_lifetime:
2244dbe13110SDimitry Andric       return getLangOpts().Exceptions &&
2245180abc3dSDimitry Andric              CGM.getCodeGenOpts().ObjCAutoRefCountExceptions;
2246180abc3dSDimitry Andric     }
2247180abc3dSDimitry Andric     llvm_unreachable("bad destruction kind");
2248180abc3dSDimitry Andric   }
2249180abc3dSDimitry Andric 
2250180abc3dSDimitry Andric   CleanupKind getCleanupKind(QualType::DestructionKind kind) {
2251180abc3dSDimitry Andric     return (needsEHCleanup(kind) ? NormalAndEHCleanup : NormalCleanup);
2252180abc3dSDimitry Andric   }
2253180abc3dSDimitry Andric 
2254180abc3dSDimitry Andric   //===--------------------------------------------------------------------===//
2255ec2b103cSEd Schouten   //                                  Objective-C
2256ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
2257ec2b103cSEd Schouten 
2258ec2b103cSEd Schouten   void GenerateObjCMethod(const ObjCMethodDecl *OMD);
2259ec2b103cSEd Schouten 
226006d4ba38SDimitry Andric   void StartObjCMethod(const ObjCMethodDecl *MD, const ObjCContainerDecl *CD);
2261ec2b103cSEd Schouten 
2262ec2b103cSEd Schouten   /// GenerateObjCGetter - Synthesize an Objective-C property getter function.
2263ec2b103cSEd Schouten   void GenerateObjCGetter(ObjCImplementationDecl *IMP,
2264ec2b103cSEd Schouten                           const ObjCPropertyImplDecl *PID);
226536981b17SDimitry Andric   void generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
2266dbe13110SDimitry Andric                               const ObjCPropertyImplDecl *propImpl,
226756d91b49SDimitry Andric                               const ObjCMethodDecl *GetterMothodDecl,
2268dbe13110SDimitry Andric                               llvm::Constant *AtomicHelperFn);
2269bca07a45SDimitry Andric 
22700883ccd9SRoman Divacky   void GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
22710883ccd9SRoman Divacky                                   ObjCMethodDecl *MD, bool ctor);
2272ec2b103cSEd Schouten 
2273ec2b103cSEd Schouten   /// GenerateObjCSetter - Synthesize an Objective-C property setter function
2274ec2b103cSEd Schouten   /// for the given property.
2275ec2b103cSEd Schouten   void GenerateObjCSetter(ObjCImplementationDecl *IMP,
2276ec2b103cSEd Schouten                           const ObjCPropertyImplDecl *PID);
227736981b17SDimitry Andric   void generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
2278dbe13110SDimitry Andric                               const ObjCPropertyImplDecl *propImpl,
2279dbe13110SDimitry Andric                               llvm::Constant *AtomicHelperFn);
2280ec2b103cSEd Schouten 
2281ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
2282ec2b103cSEd Schouten   //                                  Block Bits
2283ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
2284ec2b103cSEd Schouten 
2285461a67faSDimitry Andric   /// Emit block literal.
2286461a67faSDimitry Andric   /// \return an LLVM value which is a pointer to a struct which contains
2287461a67faSDimitry Andric   /// information about the block, including the block invoke function, the
2288461a67faSDimitry Andric   /// captured variables, etc.
228948675466SDimitry Andric   llvm::Value *EmitBlockLiteral(const BlockExpr *);
2290ec2b103cSEd Schouten 
22914ba67500SRoman Divacky   llvm::Function *GenerateBlockFunction(GlobalDecl GD,
2292bca07a45SDimitry Andric                                         const CGBlockInfo &Info,
2293dbe13110SDimitry Andric                                         const DeclMapTy &ldm,
2294461a67faSDimitry Andric                                         bool IsLambdaConversionToBlock,
2295461a67faSDimitry Andric                                         bool BuildGlobalBlock);
2296ec2b103cSEd Schouten 
2297676fbe81SDimitry Andric   /// Check if \p T is a C++ class that has a destructor that can throw.
2298676fbe81SDimitry Andric   static bool cxxDestructorCanThrow(QualType T);
2299676fbe81SDimitry Andric 
2300bca07a45SDimitry Andric   llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo);
2301bca07a45SDimitry Andric   llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo);
2302dbe13110SDimitry Andric   llvm::Constant *GenerateObjCAtomicSetterCopyHelperFunction(
2303dbe13110SDimitry Andric                                              const ObjCPropertyImplDecl *PID);
2304dbe13110SDimitry Andric   llvm::Constant *GenerateObjCAtomicGetterCopyHelperFunction(
2305dbe13110SDimitry Andric                                              const ObjCPropertyImplDecl *PID);
2306dbe13110SDimitry Andric   llvm::Value *EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty);
2307bca07a45SDimitry Andric 
2308676fbe81SDimitry Andric   void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags,
2309676fbe81SDimitry Andric                          bool CanThrow);
2310bca07a45SDimitry Andric 
231101af97d3SDimitry Andric   class AutoVarEmission;
231201af97d3SDimitry Andric 
231301af97d3SDimitry Andric   void emitByrefStructureInit(const AutoVarEmission &emission);
231448675466SDimitry Andric 
231548675466SDimitry Andric   /// Enter a cleanup to destroy a __block variable.  Note that this
231648675466SDimitry Andric   /// cleanup should be a no-op if the variable hasn't left the stack
231748675466SDimitry Andric   /// yet; if a cleanup is required for the variable itself, that needs
231848675466SDimitry Andric   /// to be done externally.
231948675466SDimitry Andric   ///
232048675466SDimitry Andric   /// \param Kind Cleanup kind.
232148675466SDimitry Andric   ///
232248675466SDimitry Andric   /// \param Addr When \p LoadBlockVarAddr is false, the address of the __block
232348675466SDimitry Andric   /// structure that will be passed to _Block_object_dispose. When
232448675466SDimitry Andric   /// \p LoadBlockVarAddr is true, the address of the field of the block
232548675466SDimitry Andric   /// structure that holds the address of the __block structure.
232648675466SDimitry Andric   ///
232748675466SDimitry Andric   /// \param Flags The flag that will be passed to _Block_object_dispose.
232848675466SDimitry Andric   ///
232948675466SDimitry Andric   /// \param LoadBlockVarAddr Indicates whether we need to emit a load from
233048675466SDimitry Andric   /// \p Addr to get the address of the __block structure.
233148675466SDimitry Andric   void enterByrefCleanup(CleanupKind Kind, Address Addr, BlockFieldFlags Flags,
2332676fbe81SDimitry Andric                          bool LoadBlockVarAddr, bool CanThrow);
233301af97d3SDimitry Andric 
233445b53394SDimitry Andric   void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum,
233545b53394SDimitry Andric                                 llvm::Value *ptr);
2336ec2b103cSEd Schouten 
233745b53394SDimitry Andric   Address LoadBlockStruct();
2338676fbe81SDimitry Andric   Address GetAddrOfBlockDecl(const VarDecl *var);
233945b53394SDimitry Andric 
234045b53394SDimitry Andric   /// BuildBlockByrefAddress - Computes the location of the
234145b53394SDimitry Andric   /// data in a variable which is declared as __block.
234245b53394SDimitry Andric   Address emitBlockByrefAddress(Address baseAddr, const VarDecl *V,
234345b53394SDimitry Andric                                 bool followForward = true);
234445b53394SDimitry Andric   Address emitBlockByrefAddress(Address baseAddr,
234545b53394SDimitry Andric                                 const BlockByrefInfo &info,
234645b53394SDimitry Andric                                 bool followForward,
234745b53394SDimitry Andric                                 const llvm::Twine &name);
234845b53394SDimitry Andric 
234945b53394SDimitry Andric   const BlockByrefInfo &getBlockByrefInfo(const VarDecl *var);
2350ec2b103cSEd Schouten 
23512b6b257fSDimitry Andric   QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args);
23522b6b257fSDimitry Andric 
235301af97d3SDimitry Andric   void GenerateCode(GlobalDecl GD, llvm::Function *Fn,
235401af97d3SDimitry Andric                     const CGFunctionInfo &FnInfo);
2355676fbe81SDimitry Andric 
2356676fbe81SDimitry Andric   /// Annotate the function with an attribute that disables TSan checking at
2357676fbe81SDimitry Andric   /// runtime.
2358676fbe81SDimitry Andric   void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn);
2359676fbe81SDimitry Andric 
236048675466SDimitry Andric   /// Emit code for the start of a function.
23619f4dbff6SDimitry Andric   /// \param Loc       The location to be associated with the function.
23629f4dbff6SDimitry Andric   /// \param StartLoc  The location of the function body.
23636a037251SDimitry Andric   void StartFunction(GlobalDecl GD,
23646a037251SDimitry Andric                      QualType RetTy,
2365ec2b103cSEd Schouten                      llvm::Function *Fn,
236601af97d3SDimitry Andric                      const CGFunctionInfo &FnInfo,
2367ec2b103cSEd Schouten                      const FunctionArgList &Args,
23689f4dbff6SDimitry Andric                      SourceLocation Loc = SourceLocation(),
23699f4dbff6SDimitry Andric                      SourceLocation StartLoc = SourceLocation());
2370ec2b103cSEd Schouten 
23717442d6faSDimitry Andric   static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor);
23727442d6faSDimitry Andric 
237379ade4e0SRoman Divacky   void EmitConstructorBody(FunctionArgList &Args);
237479ade4e0SRoman Divacky   void EmitDestructorBody(FunctionArgList &Args);
2375809500fcSDimitry Andric   void emitImplicitAssignmentOperatorBody(FunctionArgList &Args);
2376676fbe81SDimitry Andric   void EmitFunctionBody(const Stmt *Body);
23775e20cdd8SDimitry Andric   void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S);
237879ade4e0SRoman Divacky 
2379bfef3995SDimitry Andric   void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator,
2380b1c73532SDimitry Andric                                   CallArgList &CallArgs,
2381b1c73532SDimitry Andric                                   const CGFunctionInfo *CallOpFnInfo = nullptr,
2382b1c73532SDimitry Andric                                   llvm::Constant *CallOpFn = nullptr);
2383dbe13110SDimitry Andric   void EmitLambdaBlockInvokeBody();
2384461a67faSDimitry Andric   void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD);
2385b1c73532SDimitry Andric   void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD,
2386b1c73532SDimitry Andric                                       CallArgList &CallArgs);
2387b1c73532SDimitry Andric   void EmitLambdaInAllocaImplFn(const CXXMethodDecl *CallOp,
2388b1c73532SDimitry Andric                                 const CGFunctionInfo **ImplFnInfo,
2389b1c73532SDimitry Andric                                 llvm::Function **ImplFn);
2390b1c73532SDimitry Andric   void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD);
239122989816SDimitry Andric   void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV) {
239222989816SDimitry Andric     EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
239322989816SDimitry Andric   }
239406d4ba38SDimitry Andric   void EmitAsanPrologueOrEpilogue(bool Prologue);
2395dbe13110SDimitry Andric 
239648675466SDimitry Andric   /// Emit the unified return block, trying to avoid its emission when
23975e20cdd8SDimitry Andric   /// possible.
23985e20cdd8SDimitry Andric   /// \return The debug location of the user written return statement if the
2399e3b55780SDimitry Andric   /// return block is avoided.
240006d4ba38SDimitry Andric   llvm::DebugLoc EmitReturnBlock();
2401ec2b103cSEd Schouten 
2402ec2b103cSEd Schouten   /// FinishFunction - Complete IR generation of the current function. It is
2403ec2b103cSEd Schouten   /// legal to call this function even if there is no current insertion point.
2404ec2b103cSEd Schouten   void FinishFunction(SourceLocation EndLoc=SourceLocation());
2405ec2b103cSEd Schouten 
24065e20cdd8SDimitry Andric   void StartThunk(llvm::Function *Fn, GlobalDecl GD,
240748675466SDimitry Andric                   const CGFunctionInfo &FnInfo, bool IsUnprototyped);
2408bfef3995SDimitry Andric 
240922989816SDimitry Andric   void EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
241022989816SDimitry Andric                                  const ThunkInfo *Thunk, bool IsUnprototyped);
241106d4ba38SDimitry Andric 
241245b53394SDimitry Andric   void FinishThunk();
241345b53394SDimitry Andric 
241406d4ba38SDimitry Andric   /// Emit a musttail call for a thunk with a potentially adjusted this pointer.
2415676fbe81SDimitry Andric   void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr,
241622989816SDimitry Andric                          llvm::FunctionCallee Callee);
2417bfef3995SDimitry Andric 
241851ece4aaSDimitry Andric   /// Generate a thunk for the given method.
241951ece4aaSDimitry Andric   void generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo,
242048675466SDimitry Andric                      GlobalDecl GD, const ThunkInfo &Thunk,
242148675466SDimitry Andric                      bool IsUnprototyped);
24224c8b2481SRoman Divacky 
2423c192b3dcSDimitry Andric   llvm::Function *GenerateVarArgsThunk(llvm::Function *Fn,
2424c192b3dcSDimitry Andric                                        const CGFunctionInfo &FnInfo,
242529cafa66SDimitry Andric                                        GlobalDecl GD, const ThunkInfo &Thunk);
242629cafa66SDimitry Andric 
2427d7279c4cSRoman Divacky   void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type,
2428d7279c4cSRoman Divacky                         FunctionArgList &Args);
24294c8b2481SRoman Divacky 
2430bab175ecSDimitry Andric   void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init);
2431dbe13110SDimitry Andric 
243248675466SDimitry Andric   /// Struct with all information about dynamic [sub]class needed to set vptr.
243345b53394SDimitry Andric   struct VPtr {
243445b53394SDimitry Andric     BaseSubobject Base;
243545b53394SDimitry Andric     const CXXRecordDecl *NearestVBase;
243645b53394SDimitry Andric     CharUnits OffsetFromNearestVBase;
243745b53394SDimitry Andric     const CXXRecordDecl *VTableClass;
243845b53394SDimitry Andric   };
243945b53394SDimitry Andric 
244045b53394SDimitry Andric   /// Initialize the vtable pointer of the given subobject.
244145b53394SDimitry Andric   void InitializeVTablePointer(const VPtr &vptr);
244245b53394SDimitry Andric 
244345b53394SDimitry Andric   typedef llvm::SmallVector<VPtr, 4> VPtrsVector;
244434d02d0bSRoman Divacky 
244511d2b2d2SRoman Divacky   typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
244645b53394SDimitry Andric   VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass);
244745b53394SDimitry Andric 
244845b53394SDimitry Andric   void getVTablePointers(BaseSubobject Base, const CXXRecordDecl *NearestVBase,
244901af97d3SDimitry Andric                          CharUnits OffsetFromNearestVBase,
245011d2b2d2SRoman Divacky                          bool BaseIsNonVirtualPrimaryBase,
245111d2b2d2SRoman Divacky                          const CXXRecordDecl *VTableClass,
245245b53394SDimitry Andric                          VisitedVirtualBasesSetTy &VBases, VPtrsVector &vptrs);
245311d2b2d2SRoman Divacky 
245411d2b2d2SRoman Divacky   void InitializeVTablePointers(const CXXRecordDecl *ClassDecl);
245511d2b2d2SRoman Divacky 
2456ac9a064cSDimitry Andric   // VTableTrapMode - whether we guarantee that loading the
2457ac9a064cSDimitry Andric   // vtable is guaranteed to trap on authentication failure,
2458ac9a064cSDimitry Andric   // even if the resulting vtable pointer is unused.
2459ac9a064cSDimitry Andric   enum class VTableAuthMode {
2460ac9a064cSDimitry Andric     Authenticate,
2461ac9a064cSDimitry Andric     MustTrap,
2462ac9a064cSDimitry Andric     UnsafeUbsanStrip // Should only be used for Vptr UBSan check
2463ac9a064cSDimitry Andric   };
2464bca07a45SDimitry Andric   /// GetVTablePtr - Return the Value of the vtable pointer member pointed
2465bca07a45SDimitry Andric   /// to by This.
2466ac9a064cSDimitry Andric   llvm::Value *
2467ac9a064cSDimitry Andric   GetVTablePtr(Address This, llvm::Type *VTableTy,
2468ac9a064cSDimitry Andric                const CXXRecordDecl *VTableClass,
2469ac9a064cSDimitry Andric                VTableAuthMode AuthMode = VTableAuthMode::Authenticate);
2470abe15e55SRoman Divacky 
24712e645aa5SDimitry Andric   enum CFITypeCheckKind {
24722e645aa5SDimitry Andric     CFITCK_VCall,
24732e645aa5SDimitry Andric     CFITCK_NVCall,
24742e645aa5SDimitry Andric     CFITCK_DerivedCast,
24752e645aa5SDimitry Andric     CFITCK_UnrelatedCast,
24762b6b257fSDimitry Andric     CFITCK_ICall,
247748675466SDimitry Andric     CFITCK_NVMFCall,
247848675466SDimitry Andric     CFITCK_VMFCall,
24792e645aa5SDimitry Andric   };
24802e645aa5SDimitry Andric 
248148675466SDimitry Andric   /// Derived is the presumed address of an object of type T after a
24825e20cdd8SDimitry Andric   /// cast. If T is a polymorphic class type, emit a check that the virtual
24835e20cdd8SDimitry Andric   /// table for Derived belongs to a class derived from T.
2484145449b1SDimitry Andric   void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull,
2485145449b1SDimitry Andric                                  CFITypeCheckKind TCK, SourceLocation Loc);
24865e20cdd8SDimitry Andric 
24875e20cdd8SDimitry Andric   /// EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
24885e20cdd8SDimitry Andric   /// If vptr CFI is enabled, emit a check that VTable is valid.
24892b6b257fSDimitry Andric   void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable,
24902e645aa5SDimitry Andric                                  CFITypeCheckKind TCK, SourceLocation Loc);
24915e20cdd8SDimitry Andric 
24925e20cdd8SDimitry Andric   /// EmitVTablePtrCheck - Emit a check that VTable is a valid virtual table for
24932b6b257fSDimitry Andric   /// RD using llvm.type.test.
24942e645aa5SDimitry Andric   void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable,
24952e645aa5SDimitry Andric                           CFITypeCheckKind TCK, SourceLocation Loc);
2496bfef3995SDimitry Andric 
24972b6b257fSDimitry Andric   /// If whole-program virtual table optimization is enabled, emit an assumption
24982b6b257fSDimitry Andric   /// that VTable is a member of RD's type identifier. Or, if vptr CFI is
24992b6b257fSDimitry Andric   /// enabled, emit a check that VTable is a member of RD's type identifier.
25002b6b257fSDimitry Andric   void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD,
25012b6b257fSDimitry Andric                                     llvm::Value *VTable, SourceLocation Loc);
25022b6b257fSDimitry Andric 
25032b6b257fSDimitry Andric   /// Returns whether we should perform a type checked load when loading a
25042b6b257fSDimitry Andric   /// virtual function for virtual calls to members of RD. This is generally
25052b6b257fSDimitry Andric   /// true when both vcall CFI and whole-program-vtables are enabled.
25062b6b257fSDimitry Andric   bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD);
25072b6b257fSDimitry Andric 
25082b6b257fSDimitry Andric   /// Emit a type checked load from the given vtable.
2509145449b1SDimitry Andric   llvm::Value *EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD,
2510145449b1SDimitry Andric                                          llvm::Value *VTable,
2511145449b1SDimitry Andric                                          llvm::Type *VTableTy,
25122b6b257fSDimitry Andric                                          uint64_t VTableByteOffset);
25132b6b257fSDimitry Andric 
25143d1dcd9bSDimitry Andric   /// EnterDtorCleanups - Enter the cleanups necessary to complete the
25153d1dcd9bSDimitry Andric   /// given phase of destruction for a destructor.  The end result
25163d1dcd9bSDimitry Andric   /// should call destructors on members and base classes in reverse
25173d1dcd9bSDimitry Andric   /// order of their construction.
25183d1dcd9bSDimitry Andric   void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type);
25194c8b2481SRoman Divacky 
25204ba67500SRoman Divacky   /// ShouldInstrumentFunction - Return true if the current function should be
25214ba67500SRoman Divacky   /// instrumented with __cyg_profile_func_* calls
25224ba67500SRoman Divacky   bool ShouldInstrumentFunction();
25234ba67500SRoman Divacky 
2524c0981da4SDimitry Andric   /// ShouldSkipSanitizerInstrumentation - Return true if the current function
2525c0981da4SDimitry Andric   /// should not be instrumented with sanitizers.
2526c0981da4SDimitry Andric   bool ShouldSkipSanitizerInstrumentation();
2527c0981da4SDimitry Andric 
25282b6b257fSDimitry Andric   /// ShouldXRayInstrument - Return true if the current function should be
25292b6b257fSDimitry Andric   /// instrumented with XRay nop sleds.
25302b6b257fSDimitry Andric   bool ShouldXRayInstrumentFunction() const;
25312b6b257fSDimitry Andric 
2532461a67faSDimitry Andric   /// AlwaysEmitXRayCustomEvents - Return true if we must unconditionally emit
2533461a67faSDimitry Andric   /// XRay custom event handling calls.
2534461a67faSDimitry Andric   bool AlwaysEmitXRayCustomEvents() const;
25354ba67500SRoman Divacky 
253648675466SDimitry Andric   /// AlwaysEmitXRayTypedEvents - Return true if clang must unconditionally emit
253748675466SDimitry Andric   /// XRay typed event handling calls.
253848675466SDimitry Andric   bool AlwaysEmitXRayTypedEvents() const;
253948675466SDimitry Andric 
25407fa27ce4SDimitry Andric   /// Return a type hash constant for a function instrumented by
25417fa27ce4SDimitry Andric   /// -fsanitize=function.
25427fa27ce4SDimitry Andric   llvm::ConstantInt *getUBSanFunctionTypeHash(QualType T) const;
2543bca07a45SDimitry Andric 
2544ec2b103cSEd Schouten   /// EmitFunctionProlog - Emit the target specific LLVM code to load the
2545ec2b103cSEd Schouten   /// arguments for the given function. This is also responsible for naming the
2546ec2b103cSEd Schouten   /// LLVM function arguments.
2547ec2b103cSEd Schouten   void EmitFunctionProlog(const CGFunctionInfo &FI,
2548ec2b103cSEd Schouten                           llvm::Function *Fn,
2549ec2b103cSEd Schouten                           const FunctionArgList &Args);
2550ec2b103cSEd Schouten 
2551ec2b103cSEd Schouten   /// EmitFunctionEpilog - Emit the target specific LLVM code to return the
2552ec2b103cSEd Schouten   /// given temporary.
2553bfef3995SDimitry Andric   void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc,
2554bfef3995SDimitry Andric                           SourceLocation EndLoc);
2555ec2b103cSEd Schouten 
25567442d6faSDimitry Andric   /// Emit a test that checks if the return value \p RV is nonnull.
2557ef915aabSDimitry Andric   void EmitReturnValueCheck(llvm::Value *RV);
25587442d6faSDimitry Andric 
255934d02d0bSRoman Divacky   /// EmitStartEHSpec - Emit the start of the exception spec.
256034d02d0bSRoman Divacky   void EmitStartEHSpec(const Decl *D);
256134d02d0bSRoman Divacky 
256234d02d0bSRoman Divacky   /// EmitEndEHSpec - Emit the end of the exception spec.
256334d02d0bSRoman Divacky   void EmitEndEHSpec(const Decl *D);
256434d02d0bSRoman Divacky 
25654ba67500SRoman Divacky   /// getTerminateLandingPad - Return a landing pad that just calls terminate.
25664ba67500SRoman Divacky   llvm::BasicBlock *getTerminateLandingPad();
25674ba67500SRoman Divacky 
256848675466SDimitry Andric   /// getTerminateLandingPad - Return a cleanup funclet that just calls
256948675466SDimitry Andric   /// terminate.
257048675466SDimitry Andric   llvm::BasicBlock *getTerminateFunclet();
257148675466SDimitry Andric 
25724ba67500SRoman Divacky   /// getTerminateHandler - Return a handler (not a landing pad, just
25734ba67500SRoman Divacky   /// a catch handler) that just calls terminate.  This is used when
25744ba67500SRoman Divacky   /// a terminate scope encloses a try.
257534d02d0bSRoman Divacky   llvm::BasicBlock *getTerminateHandler();
257634d02d0bSRoman Divacky 
2577180abc3dSDimitry Andric   llvm::Type *ConvertTypeForMem(QualType T);
2578180abc3dSDimitry Andric   llvm::Type *ConvertType(QualType T);
2579ac9a064cSDimitry Andric   llvm::Type *convertTypeForLoadStore(QualType ASTTy,
2580ac9a064cSDimitry Andric                                       llvm::Type *LLVMTy = nullptr);
2581180abc3dSDimitry Andric   llvm::Type *ConvertType(const TypeDecl *T) {
2582ecb7e5c8SRoman Divacky     return ConvertType(getContext().getTypeDeclType(T));
2583ecb7e5c8SRoman Divacky   }
2584ec2b103cSEd Schouten 
2585ec2b103cSEd Schouten   /// LoadObjCSelf - Load the value of self. This function is only valid while
2586ec2b103cSEd Schouten   /// generating code for an Objective-C method.
2587ec2b103cSEd Schouten   llvm::Value *LoadObjCSelf();
2588ec2b103cSEd Schouten 
2589ec2b103cSEd Schouten   /// TypeOfSelfObject - Return type of object that this self represents.
2590ec2b103cSEd Schouten   QualType TypeOfSelfObject();
2591ec2b103cSEd Schouten 
2592461a67faSDimitry Andric   /// getEvaluationKind - Return the TypeEvaluationKind of QualType \c T.
2593809500fcSDimitry Andric   static TypeEvaluationKind getEvaluationKind(QualType T);
2594809500fcSDimitry Andric 
2595809500fcSDimitry Andric   static bool hasScalarEvaluationKind(QualType T) {
2596809500fcSDimitry Andric     return getEvaluationKind(T) == TEK_Scalar;
2597809500fcSDimitry Andric   }
2598809500fcSDimitry Andric 
2599809500fcSDimitry Andric   static bool hasAggregateEvaluationKind(QualType T) {
2600809500fcSDimitry Andric     return getEvaluationKind(T) == TEK_Aggregate;
2601809500fcSDimitry Andric   }
2602ec2b103cSEd Schouten 
2603ec2b103cSEd Schouten   /// createBasicBlock - Create an LLVM basic block.
260413cc256eSDimitry Andric   llvm::BasicBlock *createBasicBlock(const Twine &name = "",
26059f4dbff6SDimitry Andric                                      llvm::Function *parent = nullptr,
26069f4dbff6SDimitry Andric                                      llvm::BasicBlock *before = nullptr) {
2607bca07a45SDimitry Andric     return llvm::BasicBlock::Create(getLLVMContext(), name, parent, before);
2608ec2b103cSEd Schouten   }
2609ec2b103cSEd Schouten 
2610ec2b103cSEd Schouten   /// getBasicBlockForLabel - Return the LLVM basicblock that the specified
2611ec2b103cSEd Schouten   /// label maps to.
2612bca07a45SDimitry Andric   JumpDest getJumpDestForLabel(const LabelDecl *S);
2613ec2b103cSEd Schouten 
26141569ce68SRoman Divacky   /// SimplifyForwardingBlocks - If the given basic block is only a branch to
26151569ce68SRoman Divacky   /// another basic block, simplify it. This assumes that no other code could
26161569ce68SRoman Divacky   /// potentially reference the basic block.
2617ec2b103cSEd Schouten   void SimplifyForwardingBlocks(llvm::BasicBlock *BB);
2618ec2b103cSEd Schouten 
2619ec2b103cSEd Schouten   /// EmitBlock - Emit the given block \arg BB and set it as the insert point,
2620ec2b103cSEd Schouten   /// adding a fall-through branch from the current insert block if
2621ec2b103cSEd Schouten   /// necessary. It is legal to call this function even if there is no current
2622ec2b103cSEd Schouten   /// insertion point.
2623ec2b103cSEd Schouten   ///
2624ec2b103cSEd Schouten   /// IsFinished - If true, indicates that the caller has finished emitting
2625ec2b103cSEd Schouten   /// branches to the given block and does not expect to emit code into it. This
2626ec2b103cSEd Schouten   /// means the block can be ignored if it is unreachable.
2627ec2b103cSEd Schouten   void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false);
2628ec2b103cSEd Schouten 
262936981b17SDimitry Andric   /// EmitBlockAfterUses - Emit the given block somewhere hopefully
263036981b17SDimitry Andric   /// near its uses, and leave the insertion point in it.
263136981b17SDimitry Andric   void EmitBlockAfterUses(llvm::BasicBlock *BB);
263236981b17SDimitry Andric 
2633ec2b103cSEd Schouten   /// EmitBranch - Emit a branch to the specified basic block from the current
2634ec2b103cSEd Schouten   /// insert block, taking care to avoid creation of branches from dummy
2635ec2b103cSEd Schouten   /// blocks. It is legal to call this function even if there is no current
2636ec2b103cSEd Schouten   /// insertion point.
2637ec2b103cSEd Schouten   ///
2638ec2b103cSEd Schouten   /// This function clears the current insertion point. The caller should follow
2639ec2b103cSEd Schouten   /// calls to this function with calls to Emit*Block prior to generation new
2640ec2b103cSEd Schouten   /// code.
2641ec2b103cSEd Schouten   void EmitBranch(llvm::BasicBlock *Block);
2642ec2b103cSEd Schouten 
2643ec2b103cSEd Schouten   /// HaveInsertPoint - True if an insertion point is defined. If not, this
2644ec2b103cSEd Schouten   /// indicates that the current code being emitted is unreachable.
2645ec2b103cSEd Schouten   bool HaveInsertPoint() const {
26469f4dbff6SDimitry Andric     return Builder.GetInsertBlock() != nullptr;
2647ec2b103cSEd Schouten   }
2648ec2b103cSEd Schouten 
2649ec2b103cSEd Schouten   /// EnsureInsertPoint - Ensure that an insertion point is defined so that
2650ec2b103cSEd Schouten   /// emitted IR has a place to go. Note that by definition, if this function
2651ec2b103cSEd Schouten   /// creates a block then that block is unreachable; callers may do better to
2652ec2b103cSEd Schouten   /// detect when no insertion point is defined and simply skip IR generation.
2653ec2b103cSEd Schouten   void EnsureInsertPoint() {
2654ec2b103cSEd Schouten     if (!HaveInsertPoint())
2655ec2b103cSEd Schouten       EmitBlock(createBasicBlock());
2656ec2b103cSEd Schouten   }
2657ec2b103cSEd Schouten 
2658ec2b103cSEd Schouten   /// ErrorUnsupported - Print out an error that codegen doesn't support the
2659ec2b103cSEd Schouten   /// specified stmt yet.
2660bfef3995SDimitry Andric   void ErrorUnsupported(const Stmt *S, const char *Type);
2661ec2b103cSEd Schouten 
2662ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
2663ec2b103cSEd Schouten   //                                  Helpers
2664ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
2665ec2b103cSEd Schouten 
2666ac9a064cSDimitry Andric   Address mergeAddressesInConditionalExpr(Address LHS, Address RHS,
2667ac9a064cSDimitry Andric                                           llvm::BasicBlock *LHSBlock,
2668ac9a064cSDimitry Andric                                           llvm::BasicBlock *RHSBlock,
2669ac9a064cSDimitry Andric                                           llvm::BasicBlock *MergeBlock,
2670ac9a064cSDimitry Andric                                           QualType MergedType) {
2671ac9a064cSDimitry Andric     Builder.SetInsertPoint(MergeBlock);
2672ac9a064cSDimitry Andric     llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond");
2673ac9a064cSDimitry Andric     PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock);
2674ac9a064cSDimitry Andric     PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock);
2675ac9a064cSDimitry Andric     LHS.replaceBasePointer(PtrPhi);
2676ac9a064cSDimitry Andric     LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment()));
2677ac9a064cSDimitry Andric     return LHS;
2678ac9a064cSDimitry Andric   }
2679ac9a064cSDimitry Andric 
2680ac9a064cSDimitry Andric   /// Construct an address with the natural alignment of T. If a pointer to T
2681ac9a064cSDimitry Andric   /// is expected to be signed, the pointer passed to this function must have
2682ac9a064cSDimitry Andric   /// been signed, and the returned Address will have the pointer authentication
2683ac9a064cSDimitry Andric   /// information needed to authenticate the signed pointer.
2684ac9a064cSDimitry Andric   Address makeNaturalAddressForPointer(
2685ac9a064cSDimitry Andric       llvm::Value *Ptr, QualType T, CharUnits Alignment = CharUnits::Zero(),
2686ac9a064cSDimitry Andric       bool ForPointeeType = false, LValueBaseInfo *BaseInfo = nullptr,
2687ac9a064cSDimitry Andric       TBAAAccessInfo *TBAAInfo = nullptr,
2688ac9a064cSDimitry Andric       KnownNonNull_t IsKnownNonNull = NotKnownNonNull) {
2689ac9a064cSDimitry Andric     if (Alignment.isZero())
2690ac9a064cSDimitry Andric       Alignment =
2691ac9a064cSDimitry Andric           CGM.getNaturalTypeAlignment(T, BaseInfo, TBAAInfo, ForPointeeType);
2692ac9a064cSDimitry Andric     return Address(Ptr, ConvertTypeForMem(T), Alignment,
2693ac9a064cSDimitry Andric                    CGM.getPointerAuthInfoForPointeeType(T), /*Offset=*/nullptr,
2694ac9a064cSDimitry Andric                    IsKnownNonNull);
2695ac9a064cSDimitry Andric   }
2696ac9a064cSDimitry Andric 
269745b53394SDimitry Andric   LValue MakeAddrLValue(Address Addr, QualType T,
2698461a67faSDimitry Andric                         AlignmentSource Source = AlignmentSource::Type) {
2699ac9a064cSDimitry Andric     return MakeAddrLValue(Addr, T, LValueBaseInfo(Source),
2700461a67faSDimitry Andric                           CGM.getTBAAAccessInfo(T));
2701461a67faSDimitry Andric   }
2702461a67faSDimitry Andric 
2703461a67faSDimitry Andric   LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo,
2704461a67faSDimitry Andric                         TBAAAccessInfo TBAAInfo) {
2705461a67faSDimitry Andric     return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, TBAAInfo);
2706dbe13110SDimitry Andric   }
270756d91b49SDimitry Andric 
270845b53394SDimitry Andric   LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment,
2709461a67faSDimitry Andric                         AlignmentSource Source = AlignmentSource::Type) {
2710ac9a064cSDimitry Andric     return MakeAddrLValue(makeNaturalAddressForPointer(V, T, Alignment), T,
2711ac9a064cSDimitry Andric                           LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T));
2712ac9a064cSDimitry Andric   }
2713ac9a064cSDimitry Andric 
2714ac9a064cSDimitry Andric   /// Same as MakeAddrLValue above except that the pointer is known to be
2715ac9a064cSDimitry Andric   /// unsigned.
2716ac9a064cSDimitry Andric   LValue MakeRawAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment,
2717ac9a064cSDimitry Andric                            AlignmentSource Source = AlignmentSource::Type) {
271877fc4c14SDimitry Andric     Address Addr(V, ConvertTypeForMem(T), Alignment);
271977fc4c14SDimitry Andric     return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source),
272077fc4c14SDimitry Andric                             CGM.getTBAAAccessInfo(T));
2721461a67faSDimitry Andric   }
2722461a67faSDimitry Andric 
272377fc4c14SDimitry Andric   LValue
272477fc4c14SDimitry Andric   MakeAddrLValueWithoutTBAA(Address Addr, QualType T,
272577fc4c14SDimitry Andric                             AlignmentSource Source = AlignmentSource::Type) {
272677fc4c14SDimitry Andric     return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source),
272777fc4c14SDimitry Andric                             TBAAAccessInfo());
272845b53394SDimitry Andric   }
272945b53394SDimitry Andric 
2730ac9a064cSDimitry Andric   /// Given a value of type T* that may not be to a complete object, construct
2731ac9a064cSDimitry Andric   /// an l-value with the natural pointee alignment of T.
273245b53394SDimitry Andric   LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T);
2733ac9a064cSDimitry Andric 
2734ac9a064cSDimitry Andric   LValue
2735ac9a064cSDimitry Andric   MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T,
2736ac9a064cSDimitry Andric                              KnownNonNull_t IsKnownNonNull = NotKnownNonNull);
2737ac9a064cSDimitry Andric 
2738ac9a064cSDimitry Andric   /// Same as MakeNaturalAlignPointeeAddrLValue except that the pointer is known
2739ac9a064cSDimitry Andric   /// to be unsigned.
2740ac9a064cSDimitry Andric   LValue MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, QualType T);
2741ac9a064cSDimitry Andric 
2742ac9a064cSDimitry Andric   LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T);
274345b53394SDimitry Andric 
2744461a67faSDimitry Andric   Address EmitLoadOfReference(LValue RefLVal,
2745461a67faSDimitry Andric                               LValueBaseInfo *PointeeBaseInfo = nullptr,
2746461a67faSDimitry Andric                               TBAAAccessInfo *PointeeTBAAInfo = nullptr);
2747461a67faSDimitry Andric   LValue EmitLoadOfReferenceLValue(LValue RefLVal);
2748461a67faSDimitry Andric   LValue EmitLoadOfReferenceLValue(Address RefAddr, QualType RefTy,
2749461a67faSDimitry Andric                                    AlignmentSource Source =
2750461a67faSDimitry Andric                                        AlignmentSource::Type) {
2751461a67faSDimitry Andric     LValue RefLVal = MakeAddrLValue(RefAddr, RefTy, LValueBaseInfo(Source),
2752461a67faSDimitry Andric                                     CGM.getTBAAAccessInfo(RefTy));
2753461a67faSDimitry Andric     return EmitLoadOfReferenceLValue(RefLVal);
2754461a67faSDimitry Andric   }
27554c8b2481SRoman Divacky 
2756145449b1SDimitry Andric   /// Load a pointer with type \p PtrTy stored at address \p Ptr.
2757145449b1SDimitry Andric   /// Note that \p PtrTy is the type of the loaded pointer, not the addresses
2758145449b1SDimitry Andric   /// it is loaded from.
27592b6b257fSDimitry Andric   Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy,
2760461a67faSDimitry Andric                             LValueBaseInfo *BaseInfo = nullptr,
2761461a67faSDimitry Andric                             TBAAAccessInfo *TBAAInfo = nullptr);
27622b6b257fSDimitry Andric   LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy);
27632b6b257fSDimitry Andric 
2764ac9a064cSDimitry Andric private:
2765ac9a064cSDimitry Andric   struct AllocaTracker {
2766ac9a064cSDimitry Andric     void Add(llvm::AllocaInst *I) { Allocas.push_back(I); }
2767ac9a064cSDimitry Andric     llvm::SmallVector<llvm::AllocaInst *> Take() { return std::move(Allocas); }
2768ac9a064cSDimitry Andric 
2769ac9a064cSDimitry Andric   private:
2770ac9a064cSDimitry Andric     llvm::SmallVector<llvm::AllocaInst *> Allocas;
2771ac9a064cSDimitry Andric   };
2772ac9a064cSDimitry Andric   AllocaTracker *Allocas = nullptr;
2773ac9a064cSDimitry Andric 
2774ac9a064cSDimitry Andric public:
2775ac9a064cSDimitry Andric   // Captures all the allocas created during the scope of its RAII object.
2776ac9a064cSDimitry Andric   struct AllocaTrackerRAII {
2777ac9a064cSDimitry Andric     AllocaTrackerRAII(CodeGenFunction &CGF)
2778ac9a064cSDimitry Andric         : CGF(CGF), OldTracker(CGF.Allocas) {
2779ac9a064cSDimitry Andric       CGF.Allocas = &Tracker;
2780ac9a064cSDimitry Andric     }
2781ac9a064cSDimitry Andric     ~AllocaTrackerRAII() { CGF.Allocas = OldTracker; }
2782ac9a064cSDimitry Andric 
2783ac9a064cSDimitry Andric     llvm::SmallVector<llvm::AllocaInst *> Take() { return Tracker.Take(); }
2784ac9a064cSDimitry Andric 
2785ac9a064cSDimitry Andric   private:
2786ac9a064cSDimitry Andric     CodeGenFunction &CGF;
2787ac9a064cSDimitry Andric     AllocaTracker *OldTracker;
2788ac9a064cSDimitry Andric     AllocaTracker Tracker;
2789ac9a064cSDimitry Andric   };
2790ac9a064cSDimitry Andric 
2791ef915aabSDimitry Andric   /// CreateTempAlloca - This creates an alloca and inserts it into the entry
2792ef915aabSDimitry Andric   /// block if \p ArraySize is nullptr, otherwise inserts it at the current
2793ef915aabSDimitry Andric   /// insertion point of the builder. The caller is responsible for setting an
2794ef915aabSDimitry Andric   /// appropriate alignment on
2795ecb7e5c8SRoman Divacky   /// the alloca.
2796ef915aabSDimitry Andric   ///
2797ef915aabSDimitry Andric   /// \p ArraySize is the number of array elements to be allocated if it
2798ef915aabSDimitry Andric   ///    is not nullptr.
2799ef915aabSDimitry Andric   ///
2800ef915aabSDimitry Andric   /// LangAS::Default is the address space of pointers to local variables and
2801ef915aabSDimitry Andric   /// temporaries, as exposed in the source language. In certain
2802ef915aabSDimitry Andric   /// configurations, this is not the same as the alloca address space, and a
2803ef915aabSDimitry Andric   /// cast is needed to lift the pointer from the alloca AS into
2804ef915aabSDimitry Andric   /// LangAS::Default. This can happen when the target uses a restricted
2805ef915aabSDimitry Andric   /// address space for the stack but the source language requires
2806ef915aabSDimitry Andric   /// LangAS::Default to be a generic address space. The latter condition is
2807ef915aabSDimitry Andric   /// common for most programming languages; OpenCL is an exception in that
2808ef915aabSDimitry Andric   /// LangAS::Default is the private address space, which naturally maps
2809ef915aabSDimitry Andric   /// to the stack.
2810ef915aabSDimitry Andric   ///
2811ef915aabSDimitry Andric   /// Because the address of a temporary is often exposed to the program in
281248675466SDimitry Andric   /// various ways, this function will perform the cast. The original alloca
281348675466SDimitry Andric   /// instruction is returned through \p Alloca if it is not nullptr.
281448675466SDimitry Andric   ///
281548675466SDimitry Andric   /// The cast is not performaed in CreateTempAllocaWithoutCast. This is
2816ef915aabSDimitry Andric   /// more efficient if the caller knows that the address will not be exposed.
2817ef915aabSDimitry Andric   llvm::AllocaInst *CreateTempAlloca(llvm::Type *Ty, const Twine &Name = "tmp",
2818ef915aabSDimitry Andric                                      llvm::Value *ArraySize = nullptr);
2819ac9a064cSDimitry Andric   RawAddress CreateTempAlloca(llvm::Type *Ty, CharUnits align,
2820ef915aabSDimitry Andric                               const Twine &Name = "tmp",
2821ef915aabSDimitry Andric                               llvm::Value *ArraySize = nullptr,
2822ac9a064cSDimitry Andric                               RawAddress *Alloca = nullptr);
2823ac9a064cSDimitry Andric   RawAddress CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align,
282448675466SDimitry Andric                                          const Twine &Name = "tmp",
282548675466SDimitry Andric                                          llvm::Value *ArraySize = nullptr);
2826ec2b103cSEd Schouten 
282745b53394SDimitry Andric   /// CreateDefaultAlignedTempAlloca - This creates an alloca with the
282845b53394SDimitry Andric   /// default ABI alignment of the given LLVM type.
282945b53394SDimitry Andric   ///
283045b53394SDimitry Andric   /// IMPORTANT NOTE: This is *not* generally the right alignment for
283145b53394SDimitry Andric   /// any given AST type that happens to have been lowered to the
283245b53394SDimitry Andric   /// given IR type.  This should only ever be used for function-local,
283345b53394SDimitry Andric   /// IR-driven manipulations like saving and restoring a value.  Do
283445b53394SDimitry Andric   /// not hand this address off to arbitrary IRGen routines, and especially
283545b53394SDimitry Andric   /// do not pass it as an argument to a function that might expect a
283645b53394SDimitry Andric   /// properly ABI-aligned value.
2837ac9a064cSDimitry Andric   RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty,
283845b53394SDimitry Andric                                           const Twine &Name = "tmp");
283945b53394SDimitry Andric 
284079ade4e0SRoman Divacky   /// CreateIRTemp - Create a temporary IR object of the given type, with
284179ade4e0SRoman Divacky   /// appropriate alignment. This routine should only be used when an temporary
284279ade4e0SRoman Divacky   /// value needs to be stored into an alloca (for example, to avoid explicit
284379ade4e0SRoman Divacky   /// PHI construction), but the type is the IR type, not the type appropriate
284479ade4e0SRoman Divacky   /// for storing in memory.
284545b53394SDimitry Andric   ///
284645b53394SDimitry Andric   /// That is, this is exactly equivalent to CreateMemTemp, but calling
284745b53394SDimitry Andric   /// ConvertType instead of ConvertTypeForMem.
2848ac9a064cSDimitry Andric   RawAddress CreateIRTemp(QualType T, const Twine &Name = "tmp");
284979ade4e0SRoman Divacky 
2850ecb7e5c8SRoman Divacky   /// CreateMemTemp - Create a temporary memory object of the given type, with
285148675466SDimitry Andric   /// appropriate alignmen and cast it to the default address space. Returns
285248675466SDimitry Andric   /// the original alloca instruction by \p Alloca if it is not nullptr.
2853ac9a064cSDimitry Andric   RawAddress CreateMemTemp(QualType T, const Twine &Name = "tmp",
2854ac9a064cSDimitry Andric                            RawAddress *Alloca = nullptr);
2855ac9a064cSDimitry Andric   RawAddress CreateMemTemp(QualType T, CharUnits Align,
2856ac9a064cSDimitry Andric                            const Twine &Name = "tmp",
2857ac9a064cSDimitry Andric                            RawAddress *Alloca = nullptr);
285848675466SDimitry Andric 
285948675466SDimitry Andric   /// CreateMemTemp - Create a temporary memory object of the given type, with
286048675466SDimitry Andric   /// appropriate alignmen without casting it to the default address space.
2861ac9a064cSDimitry Andric   RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name = "tmp");
2862ac9a064cSDimitry Andric   RawAddress CreateMemTempWithoutCast(QualType T, CharUnits Align,
286348675466SDimitry Andric                                       const Twine &Name = "tmp");
2864ecb7e5c8SRoman Divacky 
2865bca07a45SDimitry Andric   /// CreateAggTemp - Create a temporary memory object for the given
2866bca07a45SDimitry Andric   /// aggregate type.
2867cfca06d7SDimitry Andric   AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp",
2868ac9a064cSDimitry Andric                              RawAddress *Alloca = nullptr) {
2869ac9a064cSDimitry Andric     return AggValueSlot::forAddr(
2870ac9a064cSDimitry Andric         CreateMemTemp(T, Name, Alloca), T.getQualifiers(),
2871ac9a064cSDimitry Andric         AggValueSlot::IsNotDestructed, AggValueSlot::DoesNotNeedGCBarriers,
2872ac9a064cSDimitry Andric         AggValueSlot::IsNotAliased, AggValueSlot::DoesNotOverlap);
2873bca07a45SDimitry Andric   }
2874bca07a45SDimitry Andric 
2875ec2b103cSEd Schouten   /// EvaluateExprAsBool - Perform the usual unary conversions on the specified
2876ec2b103cSEd Schouten   /// expression and compare the result against zero, returning an Int1Ty value.
2877ec2b103cSEd Schouten   llvm::Value *EvaluateExprAsBool(const Expr *E);
2878ec2b103cSEd Schouten 
2879ac9a064cSDimitry Andric   /// Retrieve the implicit cast expression of the rhs in a binary operator
2880ac9a064cSDimitry Andric   /// expression by passing pointers to Value and QualType
2881ac9a064cSDimitry Andric   /// This is used for implicit bitfield conversion checks, which
2882ac9a064cSDimitry Andric   /// must compare with the value before potential truncation.
2883ac9a064cSDimitry Andric   llvm::Value *EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator *E,
2884ac9a064cSDimitry Andric                                                      llvm::Value **Previous,
2885ac9a064cSDimitry Andric                                                      QualType *SrcType);
2886ac9a064cSDimitry Andric 
2887ac9a064cSDimitry Andric   /// Emit a check that an [implicit] conversion of a bitfield. It is not UB,
2888ac9a064cSDimitry Andric   /// so we use the value after conversion.
2889ac9a064cSDimitry Andric   void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType,
2890ac9a064cSDimitry Andric                                    llvm::Value *Dst, QualType DstType,
2891ac9a064cSDimitry Andric                                    const CGBitFieldInfo &Info,
2892ac9a064cSDimitry Andric                                    SourceLocation Loc);
2893ac9a064cSDimitry Andric 
2894bca07a45SDimitry Andric   /// EmitIgnoredExpr - Emit an expression in a context which ignores the result.
2895bca07a45SDimitry Andric   void EmitIgnoredExpr(const Expr *E);
2896bca07a45SDimitry Andric 
2897ec2b103cSEd Schouten   /// EmitAnyExpr - Emit code to compute the specified expression which can have
2898ec2b103cSEd Schouten   /// any type.  The result is returned as an RValue struct.  If this is an
2899ec2b103cSEd Schouten   /// aggregate expression, the aggloc/agglocvolatile arguments indicate where
2900ec2b103cSEd Schouten   /// the result should be returned.
2901ec2b103cSEd Schouten   ///
290213cc256eSDimitry Andric   /// \param ignoreResult True if the resulting value isn't used.
2903bca07a45SDimitry Andric   RValue EmitAnyExpr(const Expr *E,
290456d91b49SDimitry Andric                      AggValueSlot aggSlot = AggValueSlot::ignored(),
290556d91b49SDimitry Andric                      bool ignoreResult = false);
2906ec2b103cSEd Schouten 
2907ec2b103cSEd Schouten   // EmitVAListRef - Emit a "reference" to a va_list; this is either the address
2908ec2b103cSEd Schouten   // or the value of the expression, depending on how va_list is defined.
290945b53394SDimitry Andric   Address EmitVAListRef(const Expr *E);
291045b53394SDimitry Andric 
291145b53394SDimitry Andric   /// Emit a "reference" to a __builtin_ms_va_list; this is
291245b53394SDimitry Andric   /// always the value of the expression, because a __builtin_ms_va_list is a
291345b53394SDimitry Andric   /// pointer to a char.
291445b53394SDimitry Andric   Address EmitMSVAListRef(const Expr *E);
2915ec2b103cSEd Schouten 
29167442d6faSDimitry Andric   /// EmitAnyExprToTemp - Similarly to EmitAnyExpr(), however, the result will
2917ec2b103cSEd Schouten   /// always be accessible even if no aggregate location is provided.
2918bca07a45SDimitry Andric   RValue EmitAnyExprToTemp(const Expr *E);
2919ec2b103cSEd Schouten 
292001af97d3SDimitry Andric   /// EmitAnyExprToMem - Emits the code necessary to evaluate an
29210883ccd9SRoman Divacky   /// arbitrary expression into the given memory location.
292245b53394SDimitry Andric   void EmitAnyExprToMem(const Expr *E, Address Location,
2923180abc3dSDimitry Andric                         Qualifiers Quals, bool IsInitializer);
29240883ccd9SRoman Divacky 
292545b53394SDimitry Andric   void EmitAnyExprToExn(const Expr *E, Address Addr);
29265e20cdd8SDimitry Andric 
292701af97d3SDimitry Andric   /// EmitExprAsInit - Emits the code necessary to initialize a
292801af97d3SDimitry Andric   /// location in memory with the given initializer.
292906d4ba38SDimitry Andric   void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue,
293006d4ba38SDimitry Andric                       bool capturedByInit);
293101af97d3SDimitry Andric 
2932809500fcSDimitry Andric   /// hasVolatileMember - returns true if aggregate type has a volatile
2933809500fcSDimitry Andric   /// member.
2934809500fcSDimitry Andric   bool hasVolatileMember(QualType T) {
2935809500fcSDimitry Andric     if (const RecordType *RT = T->getAs<RecordType>()) {
2936809500fcSDimitry Andric       const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
2937809500fcSDimitry Andric       return RD->hasVolatileMember();
2938809500fcSDimitry Andric     }
2939809500fcSDimitry Andric     return false;
2940809500fcSDimitry Andric   }
294148675466SDimitry Andric 
294248675466SDimitry Andric   /// Determine whether a return value slot may overlap some other object.
294322989816SDimitry Andric   AggValueSlot::Overlap_t getOverlapForReturnValue() {
294448675466SDimitry Andric     // FIXME: Assuming no overlap here breaks guaranteed copy elision for base
294548675466SDimitry Andric     // class subobjects. These cases may need to be revisited depending on the
294648675466SDimitry Andric     // resolution of the relevant core issue.
294748675466SDimitry Andric     return AggValueSlot::DoesNotOverlap;
294813cc256eSDimitry Andric   }
294913cc256eSDimitry Andric 
295048675466SDimitry Andric   /// Determine whether a field initialization may overlap some other object.
295122989816SDimitry Andric   AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD);
295248675466SDimitry Andric 
295348675466SDimitry Andric   /// Determine whether a base class initialization may overlap some other
295448675466SDimitry Andric   /// object.
295522989816SDimitry Andric   AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *RD,
295648675466SDimitry Andric                                                 const CXXRecordDecl *BaseRD,
295748675466SDimitry Andric                                                 bool IsVirtual);
295848675466SDimitry Andric 
295948675466SDimitry Andric   /// Emit an aggregate assignment.
296048675466SDimitry Andric   void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy) {
296148675466SDimitry Andric     bool IsVolatile = hasVolatileMember(EltTy);
296248675466SDimitry Andric     EmitAggregateCopy(Dest, Src, EltTy, AggValueSlot::MayOverlap, IsVolatile);
296348675466SDimitry Andric   }
296448675466SDimitry Andric 
296548675466SDimitry Andric   void EmitAggregateCopyCtor(LValue Dest, LValue Src,
296648675466SDimitry Andric                              AggValueSlot::Overlap_t MayOverlap) {
296748675466SDimitry Andric     EmitAggregateCopy(Dest, Src, Src.getType(), MayOverlap);
29685e20cdd8SDimitry Andric   }
29695e20cdd8SDimitry Andric 
2970809500fcSDimitry Andric   /// EmitAggregateCopy - Emit an aggregate copy.
2971ec2b103cSEd Schouten   ///
297248675466SDimitry Andric   /// \param isVolatile \c true iff either the source or the destination is
2973ec2b103cSEd Schouten   ///        volatile.
297448675466SDimitry Andric   /// \param MayOverlap Whether the tail padding of the destination might be
297548675466SDimitry Andric   ///        occupied by some other object. More efficient code can often be
297648675466SDimitry Andric   ///        generated if not.
297748675466SDimitry Andric   void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy,
297848675466SDimitry Andric                          AggValueSlot::Overlap_t MayOverlap,
297948675466SDimitry Andric                          bool isVolatile = false);
2980ec2b103cSEd Schouten 
2981ec2b103cSEd Schouten   /// GetAddrOfLocalVar - Return the address of a local variable.
298245b53394SDimitry Andric   Address GetAddrOfLocalVar(const VarDecl *VD) {
298345b53394SDimitry Andric     auto it = LocalDeclMap.find(VD);
298445b53394SDimitry Andric     assert(it != LocalDeclMap.end() &&
298545b53394SDimitry Andric            "Invalid argument to GetAddrOfLocalVar(), no decl!");
298645b53394SDimitry Andric     return it->second;
29873d1dcd9bSDimitry Andric   }
2988ec2b103cSEd Schouten 
298948675466SDimitry Andric   /// Given an opaque value expression, return its LValue mapping if it exists,
299048675466SDimitry Andric   /// otherwise create one.
299148675466SDimitry Andric   LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e);
2992bca07a45SDimitry Andric 
299348675466SDimitry Andric   /// Given an opaque value expression, return its RValue mapping if it exists,
299448675466SDimitry Andric   /// otherwise create one.
299548675466SDimitry Andric   RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e);
2996bca07a45SDimitry Andric 
2997bab175ecSDimitry Andric   /// Get the index of the current ArrayInitLoopExpr, if any.
2998bab175ecSDimitry Andric   llvm::Value *getArrayInitIndex() { return ArrayInitIndex; }
2999bab175ecSDimitry Andric 
3000ec2b103cSEd Schouten   /// getAccessedFieldNo - Given an encoded value and a result number, return
3001ec2b103cSEd Schouten   /// the input field number being accessed.
3002ec2b103cSEd Schouten   static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts);
3003ec2b103cSEd Schouten 
3004bca07a45SDimitry Andric   llvm::BlockAddress *GetAddrOfLabel(const LabelDecl *L);
30054c8b2481SRoman Divacky   llvm::BasicBlock *GetIndirectGotoBlock();
3006ec2b103cSEd Schouten 
30077442d6faSDimitry Andric   /// Check if \p E is a C++ "this" pointer wrapped in value-preserving casts.
30087442d6faSDimitry Andric   static bool IsWrappedCXXThis(const Expr *E);
30097442d6faSDimitry Andric 
3010d7279c4cSRoman Divacky   /// EmitNullInitialization - Generate code to set a value of the given type to
3011d7279c4cSRoman Divacky   /// null, If the type contains data member pointers, they will be initialized
3012d7279c4cSRoman Divacky   /// to -1 in accordance with the Itanium C++ ABI.
301345b53394SDimitry Andric   void EmitNullInitialization(Address DestPtr, QualType Ty);
3014ec2b103cSEd Schouten 
301545b53394SDimitry Andric   /// Emits a call to an LLVM variable-argument intrinsic, either
301645b53394SDimitry Andric   /// \c llvm.va_start or \c llvm.va_end.
301745b53394SDimitry Andric   /// \param ArgValue A reference to the \c va_list as emitted by either
301845b53394SDimitry Andric   /// \c EmitVAListRef or \c EmitMSVAListRef.
301945b53394SDimitry Andric   /// \param IsStart If \c true, emits a call to \c llvm.va_start; otherwise,
302045b53394SDimitry Andric   /// calls \c llvm.va_end.
302145b53394SDimitry Andric   llvm::Value *EmitVAStartEnd(llvm::Value *ArgValue, bool IsStart);
302245b53394SDimitry Andric 
302345b53394SDimitry Andric   /// Generate code to get an argument from the passed in pointer
302445b53394SDimitry Andric   /// and update it accordingly.
302545b53394SDimitry Andric   /// \param VE The \c VAArgExpr for which to generate code.
302645b53394SDimitry Andric   /// \param VAListAddr Receives a reference to the \c va_list as emitted by
302745b53394SDimitry Andric   /// either \c EmitVAListRef or \c EmitMSVAListRef.
302845b53394SDimitry Andric   /// \returns A pointer to the argument.
3029ec2b103cSEd Schouten   // FIXME: We should be able to get rid of this method and use the va_arg
3030ec2b103cSEd Schouten   // instruction in LLVM instead once it works well enough.
3031ac9a064cSDimitry Andric   RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr,
3032ac9a064cSDimitry Andric                    AggValueSlot Slot = AggValueSlot::ignored());
3033ec2b103cSEd Schouten 
3034180abc3dSDimitry Andric   /// emitArrayLength - Compute the length of an array, even if it's a
3035180abc3dSDimitry Andric   /// VLA, and drill down to the base element type.
3036180abc3dSDimitry Andric   llvm::Value *emitArrayLength(const ArrayType *arrayType,
3037180abc3dSDimitry Andric                                QualType &baseType,
303845b53394SDimitry Andric                                Address &addr);
3039180abc3dSDimitry Andric 
3040180abc3dSDimitry Andric   /// EmitVLASize - Capture all the sizes for the VLA expressions in
3041180abc3dSDimitry Andric   /// the given variably-modified type and store them in the VLASizeMap.
30424c8b2481SRoman Divacky   ///
30434c8b2481SRoman Divacky   /// This function can be called with a null (unreachable) insert point.
3044180abc3dSDimitry Andric   void EmitVariablyModifiedType(QualType Ty);
3045ec2b103cSEd Schouten 
304648675466SDimitry Andric   struct VlaSizePair {
304748675466SDimitry Andric     llvm::Value *NumElts;
304848675466SDimitry Andric     QualType Type;
304948675466SDimitry Andric 
305048675466SDimitry Andric     VlaSizePair(llvm::Value *NE, QualType T) : NumElts(NE), Type(T) {}
305148675466SDimitry Andric   };
305248675466SDimitry Andric 
305348675466SDimitry Andric   /// Return the number of elements for a single dimension
305448675466SDimitry Andric   /// for the given array type.
305548675466SDimitry Andric   VlaSizePair getVLAElements1D(const VariableArrayType *vla);
305648675466SDimitry Andric   VlaSizePair getVLAElements1D(QualType vla);
305748675466SDimitry Andric 
305848675466SDimitry Andric   /// Returns an LLVM value that corresponds to the size,
3059180abc3dSDimitry Andric   /// in non-variably-sized elements, of a variable length array type,
3060180abc3dSDimitry Andric   /// plus that largest non-variably-sized element type.  Assumes that
3061180abc3dSDimitry Andric   /// the type has already been emitted with EmitVariablyModifiedType.
306248675466SDimitry Andric   VlaSizePair getVLASize(const VariableArrayType *vla);
306348675466SDimitry Andric   VlaSizePair getVLASize(QualType vla);
3064ec2b103cSEd Schouten 
3065ec2b103cSEd Schouten   /// LoadCXXThis - Load the value of 'this'. This function is only valid while
3066ec2b103cSEd Schouten   /// generating code for an C++ member function.
306779ade4e0SRoman Divacky   llvm::Value *LoadCXXThis() {
306879ade4e0SRoman Divacky     assert(CXXThisValue && "no 'this' value for this function");
306979ade4e0SRoman Divacky     return CXXThisValue;
307079ade4e0SRoman Divacky   }
307145b53394SDimitry Andric   Address LoadCXXThisAddress();
3072ec2b103cSEd Schouten 
3073ee791ddeSRoman Divacky   /// LoadCXXVTT - Load the VTT parameter to base constructors/destructors have
3074ee791ddeSRoman Divacky   /// virtual bases.
3075809500fcSDimitry Andric   // FIXME: Every place that calls LoadCXXVTT is something
3076809500fcSDimitry Andric   // that needs to be abstracted properly.
307779ade4e0SRoman Divacky   llvm::Value *LoadCXXVTT() {
3078809500fcSDimitry Andric     assert(CXXStructorImplicitParamValue && "no VTT value for this function");
3079809500fcSDimitry Andric     return CXXStructorImplicitParamValue;
3080809500fcSDimitry Andric   }
3081809500fcSDimitry Andric 
3082ecb7e5c8SRoman Divacky   /// GetAddressOfBaseOfCompleteClass - Convert the given pointer to a
30830883ccd9SRoman Divacky   /// complete class to the given direct base.
308445b53394SDimitry Andric   Address
308545b53394SDimitry Andric   GetAddressOfDirectBaseInCompleteClass(Address Value,
3086ecb7e5c8SRoman Divacky                                         const CXXRecordDecl *Derived,
30870883ccd9SRoman Divacky                                         const CXXRecordDecl *Base,
30880883ccd9SRoman Divacky                                         bool BaseIsVirtual);
3089ecb7e5c8SRoman Divacky 
309045b53394SDimitry Andric   static bool ShouldNullCheckClassCastValue(const CastExpr *Cast);
309145b53394SDimitry Andric 
30921569ce68SRoman Divacky   /// GetAddressOfBaseClass - This function will add the necessary delta to the
30931569ce68SRoman Divacky   /// load of 'this' and returns address of the base class.
309445b53394SDimitry Andric   Address GetAddressOfBaseClass(Address Value,
30950883ccd9SRoman Divacky                                 const CXXRecordDecl *Derived,
30963d1dcd9bSDimitry Andric                                 CastExpr::path_const_iterator PathBegin,
30973d1dcd9bSDimitry Andric                                 CastExpr::path_const_iterator PathEnd,
309806d4ba38SDimitry Andric                                 bool NullCheckValue, SourceLocation Loc);
30994c8b2481SRoman Divacky 
310045b53394SDimitry Andric   Address GetAddressOfDerivedClass(Address Value,
31010883ccd9SRoman Divacky                                    const CXXRecordDecl *Derived,
31023d1dcd9bSDimitry Andric                                    CastExpr::path_const_iterator PathBegin,
31033d1dcd9bSDimitry Andric                                    CastExpr::path_const_iterator PathEnd,
31041569ce68SRoman Divacky                                    bool NullCheckValue);
31051569ce68SRoman Divacky 
3106809500fcSDimitry Andric   /// GetVTTParameter - Return the VTT parameter that should be passed to a
3107809500fcSDimitry Andric   /// base constructor/destructor with virtual bases.
3108809500fcSDimitry Andric   /// FIXME: VTTs are Itanium ABI-specific, so the definition should move
3109809500fcSDimitry Andric   /// to ItaniumCXXABI.cpp together with all the references to VTT.
3110809500fcSDimitry Andric   llvm::Value *GetVTTParameter(GlobalDecl GD, bool ForVirtualBase,
3111809500fcSDimitry Andric                                bool Delegating);
3112809500fcSDimitry Andric 
311379ade4e0SRoman Divacky   void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
311479ade4e0SRoman Divacky                                       CXXCtorType CtorType,
3115bfef3995SDimitry Andric                                       const FunctionArgList &Args,
3116bfef3995SDimitry Andric                                       SourceLocation Loc);
311701af97d3SDimitry Andric   // It's important not to confuse this and the previous function. Delegating
311801af97d3SDimitry Andric   // constructors are the C++0x feature. The constructor delegate optimization
311901af97d3SDimitry Andric   // is used to reduce duplication in the base and complete consturctors where
312001af97d3SDimitry Andric   // they are substantially the same.
312101af97d3SDimitry Andric   void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor,
312201af97d3SDimitry Andric                                         const FunctionArgList &Args);
312345b53394SDimitry Andric 
31242b6b257fSDimitry Andric   /// Emit a call to an inheriting constructor (that is, one that invokes a
31252b6b257fSDimitry Andric   /// constructor inherited from a base class) by inlining its definition. This
31262b6b257fSDimitry Andric   /// is necessary if the ABI does not support forwarding the arguments to the
31272b6b257fSDimitry Andric   /// base class constructor (because they're variadic or similar).
31282b6b257fSDimitry Andric   void EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor,
31292b6b257fSDimitry Andric                                                CXXCtorType CtorType,
31302b6b257fSDimitry Andric                                                bool ForVirtualBase,
31312b6b257fSDimitry Andric                                                bool Delegating,
31322b6b257fSDimitry Andric                                                CallArgList &Args);
31332b6b257fSDimitry Andric 
31342b6b257fSDimitry Andric   /// Emit a call to a constructor inherited from a base class, passing the
31352b6b257fSDimitry Andric   /// current constructor's arguments along unmodified (without even making
31362b6b257fSDimitry Andric   /// a copy).
31372b6b257fSDimitry Andric   void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D,
31382b6b257fSDimitry Andric                                        bool ForVirtualBase, Address This,
31392b6b257fSDimitry Andric                                        bool InheritedFromVBase,
31402b6b257fSDimitry Andric                                        const CXXInheritedCtorInitExpr *E);
31412b6b257fSDimitry Andric 
3142ec2b103cSEd Schouten   void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
3143809500fcSDimitry Andric                               bool ForVirtualBase, bool Delegating,
314422989816SDimitry Andric                               AggValueSlot ThisAVS, const CXXConstructExpr *E);
314545b53394SDimitry Andric 
31462b6b257fSDimitry Andric   void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
31472b6b257fSDimitry Andric                               bool ForVirtualBase, bool Delegating,
314848675466SDimitry Andric                               Address This, CallArgList &Args,
314948675466SDimitry Andric                               AggValueSlot::Overlap_t Overlap,
315022989816SDimitry Andric                               SourceLocation Loc, bool NewPointerIsChecked);
31512b6b257fSDimitry Andric 
3152e3b55780SDimitry Andric   /// Emit assumption load for all bases. Requires to be called only on
315345b53394SDimitry Andric   /// most-derived class and not under construction of the object.
315445b53394SDimitry Andric   void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This);
315545b53394SDimitry Andric 
315645b53394SDimitry Andric   /// Emit assumption that vptr load == global vtable.
315745b53394SDimitry Andric   void EmitVTableAssumptionLoad(const VPtr &vptr, Address This);
3158ec2b103cSEd Schouten 
3159bca07a45SDimitry Andric   void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
316045b53394SDimitry Andric                                       Address This, Address Src,
316106d4ba38SDimitry Andric                                       const CXXConstructExpr *E);
3162bca07a45SDimitry Andric 
31634c8b2481SRoman Divacky   void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
31642b6b257fSDimitry Andric                                   const ArrayType *ArrayTy,
316545b53394SDimitry Andric                                   Address ArrayPtr,
316606d4ba38SDimitry Andric                                   const CXXConstructExpr *E,
3167c7e70c43SDimitry Andric                                   bool NewPointerIsChecked,
31683d1dcd9bSDimitry Andric                                   bool ZeroInitialization = false);
31691569ce68SRoman Divacky 
31704c8b2481SRoman Divacky   void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
31714c8b2481SRoman Divacky                                   llvm::Value *NumElements,
317245b53394SDimitry Andric                                   Address ArrayPtr,
317306d4ba38SDimitry Andric                                   const CXXConstructExpr *E,
3174c7e70c43SDimitry Andric                                   bool NewPointerIsChecked,
31753d1dcd9bSDimitry Andric                                   bool ZeroInitialization = false);
31764c8b2481SRoman Divacky 
3177180abc3dSDimitry Andric   static Destroyer destroyCXXObject;
3178b3d5a323SRoman Divacky 
3179ec2b103cSEd Schouten   void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type,
318022989816SDimitry Andric                              bool ForVirtualBase, bool Delegating, Address This,
318122989816SDimitry Andric                              QualType ThisTy);
3182ec2b103cSEd Schouten 
318336981b17SDimitry Andric   void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType,
318445b53394SDimitry Andric                                llvm::Type *ElementTy, Address NewPtr,
31855e20cdd8SDimitry Andric                                llvm::Value *NumElements,
31869f4dbff6SDimitry Andric                                llvm::Value *AllocSizeWithoutCookie);
31874ba67500SRoman Divacky 
3188dbe13110SDimitry Andric   void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType,
318945b53394SDimitry Andric                         Address Ptr);
3190ec2b103cSEd Schouten 
3191344a3780SDimitry Andric   void EmitSehCppScopeBegin();
3192344a3780SDimitry Andric   void EmitSehCppScopeEnd();
3193344a3780SDimitry Andric   void EmitSehTryScopeBegin();
3194344a3780SDimitry Andric   void EmitSehTryScopeEnd();
3195344a3780SDimitry Andric 
3196344a3780SDimitry Andric   llvm::Value *EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr);
31975e20cdd8SDimitry Andric   void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr);
31985e20cdd8SDimitry Andric 
3199ec2b103cSEd Schouten   llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E);
32004c8b2481SRoman Divacky   void EmitCXXDeleteExpr(const CXXDeleteExpr *E);
3201ec2b103cSEd Schouten 
3202b3d5a323SRoman Divacky   void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr,
3203bab175ecSDimitry Andric                       QualType DeleteTy, llvm::Value *NumElements = nullptr,
3204bab175ecSDimitry Andric                       CharUnits CookieSize = CharUnits());
3205b3d5a323SRoman Divacky 
32069f4dbff6SDimitry Andric   RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type,
320748675466SDimitry Andric                                   const CallExpr *TheCallExpr, bool IsDelete);
32089f4dbff6SDimitry Andric 
3209b3d5a323SRoman Divacky   llvm::Value *EmitCXXTypeidExpr(const CXXTypeidExpr *E);
321045b53394SDimitry Andric   llvm::Value *EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE);
321145b53394SDimitry Andric   Address EmitCXXUuidofExpr(const CXXUuidofExpr *E);
3212b3d5a323SRoman Divacky 
321348675466SDimitry Andric   /// Situations in which we might emit a check for the suitability of a
3214cfca06d7SDimitry Andric   /// pointer or glvalue. Needs to be kept in sync with ubsan_handlers.cpp in
3215cfca06d7SDimitry Andric   /// compiler-rt.
321613cc256eSDimitry Andric   enum TypeCheckKind {
321713cc256eSDimitry Andric     /// Checking the operand of a load. Must be suitably sized and aligned.
321813cc256eSDimitry Andric     TCK_Load,
321913cc256eSDimitry Andric     /// Checking the destination of a store. Must be suitably sized and aligned.
322013cc256eSDimitry Andric     TCK_Store,
322113cc256eSDimitry Andric     /// Checking the bound value in a reference binding. Must be suitably sized
322213cc256eSDimitry Andric     /// and aligned, but is not required to refer to an object (until the
322313cc256eSDimitry Andric     /// reference is used), per core issue 453.
322413cc256eSDimitry Andric     TCK_ReferenceBinding,
322513cc256eSDimitry Andric     /// Checking the object expression in a non-static data member access. Must
322613cc256eSDimitry Andric     /// be an object within its lifetime.
322713cc256eSDimitry Andric     TCK_MemberAccess,
322813cc256eSDimitry Andric     /// Checking the 'this' pointer for a call to a non-static member function.
322913cc256eSDimitry Andric     /// Must be an object within its lifetime.
323013cc256eSDimitry Andric     TCK_MemberCall,
323113cc256eSDimitry Andric     /// Checking the 'this' pointer for a constructor call.
3232809500fcSDimitry Andric     TCK_ConstructorCall,
3233809500fcSDimitry Andric     /// Checking the operand of a static_cast to a derived pointer type. Must be
3234809500fcSDimitry Andric     /// null or an object within its lifetime.
3235809500fcSDimitry Andric     TCK_DowncastPointer,
3236809500fcSDimitry Andric     /// Checking the operand of a static_cast to a derived reference type. Must
3237809500fcSDimitry Andric     /// be an object within its lifetime.
323806d4ba38SDimitry Andric     TCK_DowncastReference,
323906d4ba38SDimitry Andric     /// Checking the operand of a cast to a base object. Must be suitably sized
324006d4ba38SDimitry Andric     /// and aligned.
324106d4ba38SDimitry Andric     TCK_Upcast,
324206d4ba38SDimitry Andric     /// Checking the operand of a cast to a virtual base object. Must be an
324306d4ba38SDimitry Andric     /// object within its lifetime.
32447442d6faSDimitry Andric     TCK_UpcastToVirtualBase,
32457442d6faSDimitry Andric     /// Checking the value assigned to a _Nonnull pointer. Must not be null.
324655e6d896SDimitry Andric     TCK_NonnullAssign,
324755e6d896SDimitry Andric     /// Checking the operand of a dynamic_cast or a typeid expression.  Must be
324855e6d896SDimitry Andric     /// null or an object within its lifetime.
324955e6d896SDimitry Andric     TCK_DynamicOperation
325013cc256eSDimitry Andric   };
325113cc256eSDimitry Andric 
3252461a67faSDimitry Andric   /// Determine whether the pointer type check \p TCK permits null pointers.
3253461a67faSDimitry Andric   static bool isNullPointerAllowed(TypeCheckKind TCK);
3254461a67faSDimitry Andric 
3255461a67faSDimitry Andric   /// Determine whether the pointer type check \p TCK requires a vptr check.
3256461a67faSDimitry Andric   static bool isVptrCheckRequired(TypeCheckKind TCK, QualType Ty);
3257461a67faSDimitry Andric 
325848675466SDimitry Andric   /// Whether any type-checking sanitizers are enabled. If \c false,
32599f4dbff6SDimitry Andric   /// calls to EmitTypeCheck can be skipped.
32609f4dbff6SDimitry Andric   bool sanitizePerformTypeCheck() const;
32619f4dbff6SDimitry Andric 
3262ac9a064cSDimitry Andric   void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV,
3263ac9a064cSDimitry Andric                      QualType Type, SanitizerSet SkippedChecks = SanitizerSet(),
3264ac9a064cSDimitry Andric                      llvm::Value *ArraySize = nullptr) {
3265ac9a064cSDimitry Andric     if (!sanitizePerformTypeCheck())
3266ac9a064cSDimitry Andric       return;
3267ac9a064cSDimitry Andric     EmitTypeCheck(TCK, Loc, LV.emitRawPointer(*this), Type, LV.getAlignment(),
3268ac9a064cSDimitry Andric                   SkippedChecks, ArraySize);
3269ac9a064cSDimitry Andric   }
3270ac9a064cSDimitry Andric 
3271ac9a064cSDimitry Andric   void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, Address Addr,
3272ac9a064cSDimitry Andric                      QualType Type, CharUnits Alignment = CharUnits::Zero(),
3273ac9a064cSDimitry Andric                      SanitizerSet SkippedChecks = SanitizerSet(),
3274ac9a064cSDimitry Andric                      llvm::Value *ArraySize = nullptr) {
3275ac9a064cSDimitry Andric     if (!sanitizePerformTypeCheck())
3276ac9a064cSDimitry Andric       return;
3277ac9a064cSDimitry Andric     EmitTypeCheck(TCK, Loc, Addr.emitRawPointer(*this), Type, Alignment,
3278ac9a064cSDimitry Andric                   SkippedChecks, ArraySize);
3279ac9a064cSDimitry Andric   }
3280ac9a064cSDimitry Andric 
328148675466SDimitry Andric   /// Emit a check that \p V is the address of storage of the
328222989816SDimitry Andric   /// appropriate size and alignment for an object of type \p Type
328322989816SDimitry Andric   /// (or if ArraySize is provided, for an array of that bound).
328413cc256eSDimitry Andric   void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V,
328506d4ba38SDimitry Andric                      QualType Type, CharUnits Alignment = CharUnits::Zero(),
328622989816SDimitry Andric                      SanitizerSet SkippedChecks = SanitizerSet(),
328722989816SDimitry Andric                      llvm::Value *ArraySize = nullptr);
3288abe15e55SRoman Divacky 
328948675466SDimitry Andric   /// Emit a check that \p Base points into an array object, which
3290809500fcSDimitry Andric   /// we can access at index \p Index. \p Accessed should be \c false if we
3291809500fcSDimitry Andric   /// this expression is used as an lvalue, for instance in "&Arr[Idx]".
3292809500fcSDimitry Andric   void EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index,
3293809500fcSDimitry Andric                        QualType IndexType, bool Accessed);
3294950076cdSDimitry Andric   void EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
3295950076cdSDimitry Andric                            llvm::Value *Index, QualType IndexType,
3296950076cdSDimitry Andric                            QualType IndexedType, bool Accessed);
3297950076cdSDimitry Andric 
3298ac9a064cSDimitry Andric   // Find a struct's flexible array member and get its offset. It may be
3299ac9a064cSDimitry Andric   // embedded inside multiple sub-structs, but must still be the last field.
3300ac9a064cSDimitry Andric   const FieldDecl *
3301ac9a064cSDimitry Andric   FindFlexibleArrayMemberFieldAndOffset(ASTContext &Ctx, const RecordDecl *RD,
3302ac9a064cSDimitry Andric                                         const FieldDecl *FAMDecl,
3303950076cdSDimitry Andric                                         uint64_t &Offset);
3304950076cdSDimitry Andric 
3305950076cdSDimitry Andric   /// Find the FieldDecl specified in a FAM's "counted_by" attribute. Returns
3306950076cdSDimitry Andric   /// \p nullptr if either the attribute or the field doesn't exist.
3307950076cdSDimitry Andric   const FieldDecl *FindCountedByField(const FieldDecl *FD);
3308950076cdSDimitry Andric 
3309950076cdSDimitry Andric   /// Build an expression accessing the "counted_by" field.
3310950076cdSDimitry Andric   llvm::Value *EmitCountedByFieldExpr(const Expr *Base,
3311950076cdSDimitry Andric                                       const FieldDecl *FAMDecl,
3312950076cdSDimitry Andric                                       const FieldDecl *CountDecl);
3313809500fcSDimitry Andric 
3314ee791ddeSRoman Divacky   llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
3315ee791ddeSRoman Divacky                                        bool isInc, bool isPre);
3316ee791ddeSRoman Divacky   ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
3317ee791ddeSRoman Divacky                                          bool isInc, bool isPre);
331806d4ba38SDimitry Andric 
3319bab175ecSDimitry Andric   /// Converts Location to a DebugLoc, if debug information is enabled.
3320bab175ecSDimitry Andric   llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location);
3321bab175ecSDimitry Andric 
332222989816SDimitry Andric   /// Get the record field index as represented in debug info.
332322989816SDimitry Andric   unsigned getDebugInfoFIndex(const RecordDecl *Rec, unsigned FieldIndex);
332422989816SDimitry Andric 
3325bab175ecSDimitry Andric 
3326ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
3327ec2b103cSEd Schouten   //                            Declaration Emission
3328ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
3329ec2b103cSEd Schouten 
33304c8b2481SRoman Divacky   /// EmitDecl - Emit a declaration.
33314c8b2481SRoman Divacky   ///
33324c8b2481SRoman Divacky   /// This function can be called with a null (unreachable) insert point.
3333ec2b103cSEd Schouten   void EmitDecl(const Decl &D);
33344c8b2481SRoman Divacky 
3335bca07a45SDimitry Andric   /// EmitVarDecl - Emit a local variable declaration.
33364c8b2481SRoman Divacky   ///
33374c8b2481SRoman Divacky   /// This function can be called with a null (unreachable) insert point.
3338bca07a45SDimitry Andric   void EmitVarDecl(const VarDecl &D);
33394c8b2481SRoman Divacky 
334006d4ba38SDimitry Andric   void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue,
334106d4ba38SDimitry Andric                       bool capturedByInit);
3342180abc3dSDimitry Andric 
33434ba67500SRoman Divacky   typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D,
33444ba67500SRoman Divacky                              llvm::Value *Address);
33454ba67500SRoman Divacky 
334648675466SDimitry Andric   /// Determine whether the given initializer is trivial in the sense
334706d4ba38SDimitry Andric   /// that it requires no code to be generated.
334806d4ba38SDimitry Andric   bool isTrivialInitializer(const Expr *Init);
334906d4ba38SDimitry Andric 
3350bca07a45SDimitry Andric   /// EmitAutoVarDecl - Emit an auto variable declaration.
33514c8b2481SRoman Divacky   ///
33524c8b2481SRoman Divacky   /// This function can be called with a null (unreachable) insert point.
3353c3b054d2SDimitry Andric   void EmitAutoVarDecl(const VarDecl &D);
3354c3b054d2SDimitry Andric 
3355c3b054d2SDimitry Andric   class AutoVarEmission {
3356c3b054d2SDimitry Andric     friend class CodeGenFunction;
3357c3b054d2SDimitry Andric 
3358c3b054d2SDimitry Andric     const VarDecl *Variable;
3359c3b054d2SDimitry Andric 
336048675466SDimitry Andric     /// The address of the alloca for languages with explicit address space
336148675466SDimitry Andric     /// (e.g. OpenCL) or alloca casted to generic pointer for address space
336248675466SDimitry Andric     /// agnostic languages (e.g. C++). Invalid if the variable was emitted
3363c3b054d2SDimitry Andric     /// as a global constant.
336445b53394SDimitry Andric     Address Addr;
3365c3b054d2SDimitry Andric 
3366c3b054d2SDimitry Andric     llvm::Value *NRVOFlag;
3367c3b054d2SDimitry Andric 
3368676fbe81SDimitry Andric     /// True if the variable is a __block variable that is captured by an
3369676fbe81SDimitry Andric     /// escaping block.
3370676fbe81SDimitry Andric     bool IsEscapingByRef;
3371c3b054d2SDimitry Andric 
3372c3b054d2SDimitry Andric     /// True if the variable is of aggregate type and has a constant
3373c3b054d2SDimitry Andric     /// initializer.
3374c3b054d2SDimitry Andric     bool IsConstantAggregate;
3375c3b054d2SDimitry Andric 
3376809500fcSDimitry Andric     /// Non-null if we should use lifetime annotations.
3377809500fcSDimitry Andric     llvm::Value *SizeForLifetimeMarkers;
3378809500fcSDimitry Andric 
337948675466SDimitry Andric     /// Address with original alloca instruction. Invalid if the variable was
338048675466SDimitry Andric     /// emitted as a global constant.
3381ac9a064cSDimitry Andric     RawAddress AllocaAddr;
338248675466SDimitry Andric 
3383c3b054d2SDimitry Andric     struct Invalid {};
338448675466SDimitry Andric     AutoVarEmission(Invalid)
338548675466SDimitry Andric         : Variable(nullptr), Addr(Address::invalid()),
3386ac9a064cSDimitry Andric           AllocaAddr(RawAddress::invalid()) {}
3387c3b054d2SDimitry Andric 
3388c3b054d2SDimitry Andric     AutoVarEmission(const VarDecl &variable)
338945b53394SDimitry Andric         : Variable(&variable), Addr(Address::invalid()), NRVOFlag(nullptr),
3390676fbe81SDimitry Andric           IsEscapingByRef(false), IsConstantAggregate(false),
3391ac9a064cSDimitry Andric           SizeForLifetimeMarkers(nullptr), AllocaAddr(RawAddress::invalid()) {}
3392c3b054d2SDimitry Andric 
339345b53394SDimitry Andric     bool wasEmittedAsGlobal() const { return !Addr.isValid(); }
3394c3b054d2SDimitry Andric 
3395c3b054d2SDimitry Andric   public:
3396c3b054d2SDimitry Andric     static AutoVarEmission invalid() { return AutoVarEmission(Invalid()); }
3397c3b054d2SDimitry Andric 
33989f4dbff6SDimitry Andric     bool useLifetimeMarkers() const {
33999f4dbff6SDimitry Andric       return SizeForLifetimeMarkers != nullptr;
34009f4dbff6SDimitry Andric     }
3401809500fcSDimitry Andric     llvm::Value *getSizeForLifetimeMarkers() const {
3402809500fcSDimitry Andric       assert(useLifetimeMarkers());
3403809500fcSDimitry Andric       return SizeForLifetimeMarkers;
3404809500fcSDimitry Andric     }
3405809500fcSDimitry Andric 
3406809500fcSDimitry Andric     /// Returns the raw, allocated address, which is not necessarily
340748675466SDimitry Andric     /// the address of the object itself. It is casted to default
340848675466SDimitry Andric     /// address space for address space agnostic languages.
340945b53394SDimitry Andric     Address getAllocatedAddress() const {
341045b53394SDimitry Andric       return Addr;
3411809500fcSDimitry Andric     }
3412809500fcSDimitry Andric 
341348675466SDimitry Andric     /// Returns the address for the original alloca instruction.
3414ac9a064cSDimitry Andric     RawAddress getOriginalAllocatedAddress() const { return AllocaAddr; }
341548675466SDimitry Andric 
3416c3b054d2SDimitry Andric     /// Returns the address of the object within this declaration.
3417c3b054d2SDimitry Andric     /// Note that this does not chase the forwarding pointer for
3418c3b054d2SDimitry Andric     /// __block decls.
341945b53394SDimitry Andric     Address getObjectAddress(CodeGenFunction &CGF) const {
3420676fbe81SDimitry Andric       if (!IsEscapingByRef) return Addr;
3421c3b054d2SDimitry Andric 
342245b53394SDimitry Andric       return CGF.emitBlockByrefAddress(Addr, Variable, /*forward*/ false);
3423c3b054d2SDimitry Andric     }
3424c3b054d2SDimitry Andric   };
3425c3b054d2SDimitry Andric   AutoVarEmission EmitAutoVarAlloca(const VarDecl &var);
3426c3b054d2SDimitry Andric   void EmitAutoVarInit(const AutoVarEmission &emission);
3427c3b054d2SDimitry Andric   void EmitAutoVarCleanups(const AutoVarEmission &emission);
3428180abc3dSDimitry Andric   void emitAutoVarTypeCleanup(const AutoVarEmission &emission,
3429180abc3dSDimitry Andric                               QualType::DestructionKind dtorKind);
34304c8b2481SRoman Divacky 
343148675466SDimitry Andric   /// Emits the alloca and debug information for the size expressions for each
343248675466SDimitry Andric   /// dimension of an array. It registers the association of its (1-dimensional)
343348675466SDimitry Andric   /// QualTypes and size expression's debug node, so that CGDebugInfo can
343448675466SDimitry Andric   /// reference this node when creating the DISubrange object to describe the
343548675466SDimitry Andric   /// array types.
343648675466SDimitry Andric   void EmitAndRegisterVariableArrayDimensions(CGDebugInfo *DI,
343748675466SDimitry Andric                                               const VarDecl &D,
343848675466SDimitry Andric                                               bool EmitDebugInfo);
343948675466SDimitry Andric 
3440bca07a45SDimitry Andric   void EmitStaticVarDecl(const VarDecl &D,
3441ecb7e5c8SRoman Divacky                          llvm::GlobalValue::LinkageTypes Linkage);
3442ec2b103cSEd Schouten 
344345b53394SDimitry Andric   class ParamValue {
3444ac9a064cSDimitry Andric     union {
3445ac9a064cSDimitry Andric       Address Addr;
344645b53394SDimitry Andric       llvm::Value *Value;
3447ac9a064cSDimitry Andric     };
3448ac9a064cSDimitry Andric 
3449ac9a064cSDimitry Andric     bool IsIndirect;
3450ac9a064cSDimitry Andric 
3451ac9a064cSDimitry Andric     ParamValue(llvm::Value *V) : Value(V), IsIndirect(false) {}
3452ac9a064cSDimitry Andric     ParamValue(Address A) : Addr(A), IsIndirect(true) {}
3453ac9a064cSDimitry Andric 
345445b53394SDimitry Andric   public:
345545b53394SDimitry Andric     static ParamValue forDirect(llvm::Value *value) {
3456ac9a064cSDimitry Andric       return ParamValue(value);
345745b53394SDimitry Andric     }
345845b53394SDimitry Andric     static ParamValue forIndirect(Address addr) {
345945b53394SDimitry Andric       assert(!addr.getAlignment().isZero());
3460ac9a064cSDimitry Andric       return ParamValue(addr);
346145b53394SDimitry Andric     }
346245b53394SDimitry Andric 
3463ac9a064cSDimitry Andric     bool isIndirect() const { return IsIndirect; }
3464ac9a064cSDimitry Andric     llvm::Value *getAnyValue() const {
3465ac9a064cSDimitry Andric       if (!isIndirect())
3466ac9a064cSDimitry Andric         return Value;
3467ac9a064cSDimitry Andric       assert(!Addr.hasOffset() && "unexpected offset");
3468ac9a064cSDimitry Andric       return Addr.getBasePointer();
3469ac9a064cSDimitry Andric     }
347045b53394SDimitry Andric 
347145b53394SDimitry Andric     llvm::Value *getDirectValue() const {
347245b53394SDimitry Andric       assert(!isIndirect());
347345b53394SDimitry Andric       return Value;
347445b53394SDimitry Andric     }
347545b53394SDimitry Andric 
347645b53394SDimitry Andric     Address getIndirectAddress() const {
347745b53394SDimitry Andric       assert(isIndirect());
3478ac9a064cSDimitry Andric       return Addr;
347945b53394SDimitry Andric     }
348045b53394SDimitry Andric   };
348145b53394SDimitry Andric 
3482ec2b103cSEd Schouten   /// EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
348345b53394SDimitry Andric   void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo);
3484ec2b103cSEd Schouten 
3485bca07a45SDimitry Andric   /// protectFromPeepholes - Protect a value that we're intending to
3486bca07a45SDimitry Andric   /// store to the side, but which will probably be used later, from
3487bca07a45SDimitry Andric   /// aggressive peepholing optimizations that might delete it.
3488bca07a45SDimitry Andric   ///
3489bca07a45SDimitry Andric   /// Pass the result to unprotectFromPeepholes to declare that
3490bca07a45SDimitry Andric   /// protection is no longer required.
3491bca07a45SDimitry Andric   ///
3492bca07a45SDimitry Andric   /// There's no particular reason why this shouldn't apply to
3493bca07a45SDimitry Andric   /// l-values, it's just that no existing peepholes work on pointers.
3494bca07a45SDimitry Andric   PeepholeProtection protectFromPeepholes(RValue rvalue);
3495bca07a45SDimitry Andric   void unprotectFromPeepholes(PeepholeProtection protection);
3496bca07a45SDimitry Andric 
3497cfca06d7SDimitry Andric   void emitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType Ty,
3498676fbe81SDimitry Andric                                     SourceLocation Loc,
3499676fbe81SDimitry Andric                                     SourceLocation AssumptionLoc,
3500676fbe81SDimitry Andric                                     llvm::Value *Alignment,
3501676fbe81SDimitry Andric                                     llvm::Value *OffsetValue,
3502676fbe81SDimitry Andric                                     llvm::Value *TheCheck,
3503676fbe81SDimitry Andric                                     llvm::Instruction *Assumption);
3504676fbe81SDimitry Andric 
3505cfca06d7SDimitry Andric   void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty,
3506676fbe81SDimitry Andric                                SourceLocation Loc, SourceLocation AssumptionLoc,
3507676fbe81SDimitry Andric                                llvm::Value *Alignment,
3508676fbe81SDimitry Andric                                llvm::Value *OffsetValue = nullptr);
3509676fbe81SDimitry Andric 
3510cfca06d7SDimitry Andric   void emitAlignmentAssumption(llvm::Value *PtrValue, const Expr *E,
3511cfca06d7SDimitry Andric                                SourceLocation AssumptionLoc,
3512cfca06d7SDimitry Andric                                llvm::Value *Alignment,
3513676fbe81SDimitry Andric                                llvm::Value *OffsetValue = nullptr);
35147442d6faSDimitry Andric 
3515ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
3516ec2b103cSEd Schouten   //                             Statement Emission
3517ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
3518ec2b103cSEd Schouten 
3519ec2b103cSEd Schouten   /// EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
3520ec2b103cSEd Schouten   void EmitStopPoint(const Stmt *S);
3521ec2b103cSEd Schouten 
3522ec2b103cSEd Schouten   /// EmitStmt - Emit the code for the statement \arg S. It is legal to call
3523ec2b103cSEd Schouten   /// this function even if there is no current insertion point.
3524ec2b103cSEd Schouten   ///
3525ec2b103cSEd Schouten   /// This function may clear the current insertion point; callers should use
3526ec2b103cSEd Schouten   /// EnsureInsertPoint if they wish to subsequently generate code without first
3527ec2b103cSEd Schouten   /// calling EmitBlock, EmitBranch, or EmitStmt.
3528e3b55780SDimitry Andric   void EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs = std::nullopt);
3529ec2b103cSEd Schouten 
3530ec2b103cSEd Schouten   /// EmitSimpleStmt - Try to emit a "simple" statement which does not
3531ec2b103cSEd Schouten   /// necessarily require an insertion point or debug information; typically
3532ec2b103cSEd Schouten   /// because the statement amounts to a jump or a container of other
3533ec2b103cSEd Schouten   /// statements.
3534ec2b103cSEd Schouten   ///
3535ec2b103cSEd Schouten   /// \return True if the statement was handled.
3536b60736ecSDimitry Andric   bool EmitSimpleStmt(const Stmt *S, ArrayRef<const Attr *> Attrs);
3537ec2b103cSEd Schouten 
353845b53394SDimitry Andric   Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false,
3539bca07a45SDimitry Andric                            AggValueSlot AVS = AggValueSlot::ignored());
354045b53394SDimitry Andric   Address EmitCompoundStmtWithoutScope(const CompoundStmt &S,
3541bfef3995SDimitry Andric                                        bool GetLast = false,
3542bfef3995SDimitry Andric                                        AggValueSlot AVS =
3543809500fcSDimitry Andric                                                 AggValueSlot::ignored());
3544ec2b103cSEd Schouten 
3545ec2b103cSEd Schouten   /// EmitLabel - Emit the block for the given label. It is legal to call this
3546ec2b103cSEd Schouten   /// function even if there is no current insertion point.
3547bca07a45SDimitry Andric   void EmitLabel(const LabelDecl *D); // helper for EmitLabelStmt.
3548ec2b103cSEd Schouten 
3549ec2b103cSEd Schouten   void EmitLabelStmt(const LabelStmt &S);
35506b9a6e39SDimitry Andric   void EmitAttributedStmt(const AttributedStmt &S);
3551ec2b103cSEd Schouten   void EmitGotoStmt(const GotoStmt &S);
3552ec2b103cSEd Schouten   void EmitIndirectGotoStmt(const IndirectGotoStmt &S);
3553ec2b103cSEd Schouten   void EmitIfStmt(const IfStmt &S);
35549f4dbff6SDimitry Andric 
35559f4dbff6SDimitry Andric   void EmitWhileStmt(const WhileStmt &S,
3556e3b55780SDimitry Andric                      ArrayRef<const Attr *> Attrs = std::nullopt);
3557e3b55780SDimitry Andric   void EmitDoStmt(const DoStmt &S, ArrayRef<const Attr *> Attrs = std::nullopt);
35589f4dbff6SDimitry Andric   void EmitForStmt(const ForStmt &S,
3559e3b55780SDimitry Andric                    ArrayRef<const Attr *> Attrs = std::nullopt);
3560ec2b103cSEd Schouten   void EmitReturnStmt(const ReturnStmt &S);
3561ec2b103cSEd Schouten   void EmitDeclStmt(const DeclStmt &S);
3562ec2b103cSEd Schouten   void EmitBreakStmt(const BreakStmt &S);
3563ec2b103cSEd Schouten   void EmitContinueStmt(const ContinueStmt &S);
3564ec2b103cSEd Schouten   void EmitSwitchStmt(const SwitchStmt &S);
3565b60736ecSDimitry Andric   void EmitDefaultStmt(const DefaultStmt &S, ArrayRef<const Attr *> Attrs);
3566b60736ecSDimitry Andric   void EmitCaseStmt(const CaseStmt &S, ArrayRef<const Attr *> Attrs);
3567b60736ecSDimitry Andric   void EmitCaseStmtRange(const CaseStmt &S, ArrayRef<const Attr *> Attrs);
3568ec2b103cSEd Schouten   void EmitAsmStmt(const AsmStmt &S);
3569ec2b103cSEd Schouten 
3570ec2b103cSEd Schouten   void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S);
3571ec2b103cSEd Schouten   void EmitObjCAtTryStmt(const ObjCAtTryStmt &S);
3572ec2b103cSEd Schouten   void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S);
3573ec2b103cSEd Schouten   void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S);
3574180abc3dSDimitry Andric   void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S);
3575ec2b103cSEd Schouten 
3576bab175ecSDimitry Andric   void EmitCoroutineBody(const CoroutineBodyStmt &S);
35777442d6faSDimitry Andric   void EmitCoreturnStmt(const CoreturnStmt &S);
35787442d6faSDimitry Andric   RValue EmitCoawaitExpr(const CoawaitExpr &E,
35797442d6faSDimitry Andric                          AggValueSlot aggSlot = AggValueSlot::ignored(),
35807442d6faSDimitry Andric                          bool ignoreResult = false);
3581325377b5SDimitry Andric   LValue EmitCoawaitLValue(const CoawaitExpr *E);
35827442d6faSDimitry Andric   RValue EmitCoyieldExpr(const CoyieldExpr &E,
35837442d6faSDimitry Andric                          AggValueSlot aggSlot = AggValueSlot::ignored(),
35847442d6faSDimitry Andric                          bool ignoreResult = false);
3585325377b5SDimitry Andric   LValue EmitCoyieldLValue(const CoyieldExpr *E);
3586bab175ecSDimitry Andric   RValue EmitCoroutineIntrinsic(const CallExpr *E, unsigned int IID);
3587bab175ecSDimitry Andric 
35884ba67500SRoman Divacky   void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
35894ba67500SRoman Divacky   void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
359079ade4e0SRoman Divacky 
35914c8b2481SRoman Divacky   void EmitCXXTryStmt(const CXXTryStmt &S);
3592bfef3995SDimitry Andric   void EmitSEHTryStmt(const SEHTryStmt &S);
35939f4dbff6SDimitry Andric   void EmitSEHLeaveStmt(const SEHLeaveStmt &S);
35945e20cdd8SDimitry Andric   void EnterSEHTryStmt(const SEHTryStmt &S);
35955e20cdd8SDimitry Andric   void ExitSEHTryStmt(const SEHTryStmt &S);
3596344a3780SDimitry Andric   void VolatilizeTryBlocks(llvm::BasicBlock *BB,
3597344a3780SDimitry Andric                            llvm::SmallPtrSet<llvm::BasicBlock *, 10> &V);
35985e20cdd8SDimitry Andric 
3599676fbe81SDimitry Andric   void pushSEHCleanup(CleanupKind kind,
3600676fbe81SDimitry Andric                       llvm::Function *FinallyFunc);
360151ece4aaSDimitry Andric   void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter,
36025e20cdd8SDimitry Andric                               const Stmt *OutlinedStmt);
36035e20cdd8SDimitry Andric 
36045e20cdd8SDimitry Andric   llvm::Function *GenerateSEHFilterFunction(CodeGenFunction &ParentCGF,
36055e20cdd8SDimitry Andric                                             const SEHExceptStmt &Except);
36065e20cdd8SDimitry Andric 
36075e20cdd8SDimitry Andric   llvm::Function *GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF,
36085e20cdd8SDimitry Andric                                              const SEHFinallyStmt &Finally);
36095e20cdd8SDimitry Andric 
361051ece4aaSDimitry Andric   void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF,
361151ece4aaSDimitry Andric                                 llvm::Value *ParentFP,
361251ece4aaSDimitry Andric                                 llvm::Value *EntryEBP);
36135e20cdd8SDimitry Andric   llvm::Value *EmitSEHExceptionCode();
36145e20cdd8SDimitry Andric   llvm::Value *EmitSEHExceptionInfo();
36155e20cdd8SDimitry Andric   llvm::Value *EmitSEHAbnormalTermination();
36165e20cdd8SDimitry Andric 
361748675466SDimitry Andric   /// Emit simple code for OpenMP directives in Simd-only mode.
361848675466SDimitry Andric   void EmitSimpleOMPExecutableDirective(const OMPExecutableDirective &D);
361948675466SDimitry Andric 
36205e20cdd8SDimitry Andric   /// Scan the outlined statement for captures from the parent function. For
36215e20cdd8SDimitry Andric   /// each capture, mark the capture as escaped and emit a call to
362251ece4aaSDimitry Andric   /// llvm.localrecover. Insert the localrecover result into the LocalDeclMap.
36235e20cdd8SDimitry Andric   void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt,
362451ece4aaSDimitry Andric                           bool IsFilter);
362551ece4aaSDimitry Andric 
362651ece4aaSDimitry Andric   /// Recovers the address of a local in a parent function. ParentVar is the
362751ece4aaSDimitry Andric   /// address of the variable used in the immediate parent function. It can
362851ece4aaSDimitry Andric   /// either be an alloca or a call to llvm.localrecover if there are nested
362951ece4aaSDimitry Andric   /// outlined functions. ParentFP is the frame pointer of the outermost parent
363051ece4aaSDimitry Andric   /// frame.
363145b53394SDimitry Andric   Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,
363245b53394SDimitry Andric                                     Address ParentVar,
36335e20cdd8SDimitry Andric                                     llvm::Value *ParentFP);
36345e20cdd8SDimitry Andric 
36359f4dbff6SDimitry Andric   void EmitCXXForRangeStmt(const CXXForRangeStmt &S,
3636e3b55780SDimitry Andric                            ArrayRef<const Attr *> Attrs = std::nullopt);
36374c8b2481SRoman Divacky 
3638461a67faSDimitry Andric   /// Controls insertion of cancellation exit blocks in worksharing constructs.
3639461a67faSDimitry Andric   class OMPCancelStackRAII {
3640461a67faSDimitry Andric     CodeGenFunction &CGF;
3641461a67faSDimitry Andric 
3642461a67faSDimitry Andric   public:
3643461a67faSDimitry Andric     OMPCancelStackRAII(CodeGenFunction &CGF, OpenMPDirectiveKind Kind,
3644461a67faSDimitry Andric                        bool HasCancel)
3645461a67faSDimitry Andric         : CGF(CGF) {
3646461a67faSDimitry Andric       CGF.OMPCancelStack.enter(CGF, Kind, HasCancel);
3647461a67faSDimitry Andric     }
3648461a67faSDimitry Andric     ~OMPCancelStackRAII() { CGF.OMPCancelStack.exit(CGF); }
3649461a67faSDimitry Andric   };
3650461a67faSDimitry Andric 
36512b6b257fSDimitry Andric   /// Returns calculated size of the specified type.
36522b6b257fSDimitry Andric   llvm::Value *getTypeSize(QualType Ty);
365306d4ba38SDimitry Andric   LValue InitCapturedStruct(const CapturedStmt &S);
3654bfef3995SDimitry Andric   llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K);
36559f4dbff6SDimitry Andric   llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S);
365645b53394SDimitry Andric   Address GenerateCapturedStmtArgument(const CapturedStmt &S);
3657cfca06d7SDimitry Andric   llvm::Function *GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
3658cfca06d7SDimitry Andric                                                      SourceLocation Loc);
365945b53394SDimitry Andric   void GenerateOpenMPCapturedVars(const CapturedStmt &S,
366045b53394SDimitry Andric                                   SmallVectorImpl<llvm::Value *> &CapturedVars);
3661790462ccSDimitry Andric   void emitOMPSimpleStore(LValue LVal, RValue RVal, QualType RValTy,
3662790462ccSDimitry Andric                           SourceLocation Loc);
366348675466SDimitry Andric   /// Perform element by element copying of arrays with type \a
36645e20cdd8SDimitry Andric   /// OriginalType from \a SrcAddr to \a DestAddr using copying procedure
36655e20cdd8SDimitry Andric   /// generated by \a CopyGen.
36665e20cdd8SDimitry Andric   ///
36675e20cdd8SDimitry Andric   /// \param DestAddr Address of the destination array.
36685e20cdd8SDimitry Andric   /// \param SrcAddr Address of the source array.
36695e20cdd8SDimitry Andric   /// \param OriginalType Type of destination and source arrays.
36705e20cdd8SDimitry Andric   /// \param CopyGen Copying procedure that copies value of single array element
36715e20cdd8SDimitry Andric   /// to another single array element.
36725e20cdd8SDimitry Andric   void EmitOMPAggregateAssign(
367345b53394SDimitry Andric       Address DestAddr, Address SrcAddr, QualType OriginalType,
367448675466SDimitry Andric       const llvm::function_ref<void(Address, Address)> CopyGen);
367548675466SDimitry Andric   /// Emit proper copying of data from one variable to another.
36765e20cdd8SDimitry Andric   ///
36775e20cdd8SDimitry Andric   /// \param OriginalType Original type of the copied variables.
36785e20cdd8SDimitry Andric   /// \param DestAddr Destination address.
36795e20cdd8SDimitry Andric   /// \param SrcAddr Source address.
36805e20cdd8SDimitry Andric   /// \param DestVD Destination variable used in \a CopyExpr (for arrays, has
36815e20cdd8SDimitry Andric   /// type of the base array element).
36825e20cdd8SDimitry Andric   /// \param SrcVD Source variable used in \a CopyExpr (for arrays, has type of
36835e20cdd8SDimitry Andric   /// the base array element).
36845e20cdd8SDimitry Andric   /// \param Copy Actual copygin expression for copying data from \a SrcVD to \a
36855e20cdd8SDimitry Andric   /// DestVD.
368645b53394SDimitry Andric   void EmitOMPCopy(QualType OriginalType,
368745b53394SDimitry Andric                    Address DestAddr, Address SrcAddr,
36885e20cdd8SDimitry Andric                    const VarDecl *DestVD, const VarDecl *SrcVD,
36895e20cdd8SDimitry Andric                    const Expr *Copy);
369048675466SDimitry Andric   /// Emit atomic update code for constructs: \a X = \a X \a BO \a E or
36915e20cdd8SDimitry Andric   /// \a X = \a E \a BO \a E.
36925e20cdd8SDimitry Andric   ///
36935e20cdd8SDimitry Andric   /// \param X Value to be updated.
36945e20cdd8SDimitry Andric   /// \param E Update value.
36955e20cdd8SDimitry Andric   /// \param BO Binary operation for update operation.
36965e20cdd8SDimitry Andric   /// \param IsXLHSInRHSPart true if \a X is LHS in RHS part of the update
36975e20cdd8SDimitry Andric   /// expression, false otherwise.
36985e20cdd8SDimitry Andric   /// \param AO Atomic ordering of the generated atomic instructions.
36995e20cdd8SDimitry Andric   /// \param CommonGen Code generator for complex expressions that cannot be
37005e20cdd8SDimitry Andric   /// expressed through atomicrmw instruction.
37015e20cdd8SDimitry Andric   /// \returns <true, OldAtomicValue> if simple 'atomicrmw' instruction was
37025e20cdd8SDimitry Andric   /// generated, <false, RValue::get(nullptr)> otherwise.
37035e20cdd8SDimitry Andric   std::pair<bool, RValue> EmitOMPAtomicSimpleUpdateExpr(
37045e20cdd8SDimitry Andric       LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart,
37055e20cdd8SDimitry Andric       llvm::AtomicOrdering AO, SourceLocation Loc,
370648675466SDimitry Andric       const llvm::function_ref<RValue(RValue)> CommonGen);
37075e20cdd8SDimitry Andric   bool EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
370806d4ba38SDimitry Andric                                  OMPPrivateScope &PrivateScope);
370906d4ba38SDimitry Andric   void EmitOMPPrivateClause(const OMPExecutableDirective &D,
371006d4ba38SDimitry Andric                             OMPPrivateScope &PrivateScope);
3711bab175ecSDimitry Andric   void EmitOMPUseDevicePtrClause(
3712cfca06d7SDimitry Andric       const OMPUseDevicePtrClause &C, OMPPrivateScope &PrivateScope,
37137fa27ce4SDimitry Andric       const llvm::DenseMap<const ValueDecl *, llvm::Value *>
37147fa27ce4SDimitry Andric           CaptureDeviceAddrMap);
3715cfca06d7SDimitry Andric   void EmitOMPUseDeviceAddrClause(
3716cfca06d7SDimitry Andric       const OMPUseDeviceAddrClause &C, OMPPrivateScope &PrivateScope,
37177fa27ce4SDimitry Andric       const llvm::DenseMap<const ValueDecl *, llvm::Value *>
37187fa27ce4SDimitry Andric           CaptureDeviceAddrMap);
371948675466SDimitry Andric   /// Emit code for copyin clause in \a D directive. The next code is
37205e20cdd8SDimitry Andric   /// generated at the start of outlined functions for directives:
37215e20cdd8SDimitry Andric   /// \code
37225e20cdd8SDimitry Andric   /// threadprivate_var1 = master_threadprivate_var1;
37235e20cdd8SDimitry Andric   /// operator=(threadprivate_var2, master_threadprivate_var2);
37245e20cdd8SDimitry Andric   /// ...
37255e20cdd8SDimitry Andric   /// __kmpc_barrier(&loc, global_tid);
37265e20cdd8SDimitry Andric   /// \endcode
37275e20cdd8SDimitry Andric   ///
37285e20cdd8SDimitry Andric   /// \param D OpenMP directive possibly with 'copyin' clause(s).
37295e20cdd8SDimitry Andric   /// \returns true if at least one copyin variable is found, false otherwise.
37305e20cdd8SDimitry Andric   bool EmitOMPCopyinClause(const OMPExecutableDirective &D);
373148675466SDimitry Andric   /// Emit initial code for lastprivate variables. If some variable is
37325e20cdd8SDimitry Andric   /// not also firstprivate, then the default initialization is used. Otherwise
37335e20cdd8SDimitry Andric   /// initialization of this variable is performed by EmitOMPFirstprivateClause
37345e20cdd8SDimitry Andric   /// method.
37355e20cdd8SDimitry Andric   ///
37365e20cdd8SDimitry Andric   /// \param D Directive that may have 'lastprivate' directives.
37375e20cdd8SDimitry Andric   /// \param PrivateScope Private scope for capturing lastprivate variables for
37385e20cdd8SDimitry Andric   /// proper codegen in internal captured statement.
37395e20cdd8SDimitry Andric   ///
37405e20cdd8SDimitry Andric   /// \returns true if there is at least one lastprivate variable, false
37415e20cdd8SDimitry Andric   /// otherwise.
37425e20cdd8SDimitry Andric   bool EmitOMPLastprivateClauseInit(const OMPExecutableDirective &D,
37435e20cdd8SDimitry Andric                                     OMPPrivateScope &PrivateScope);
374448675466SDimitry Andric   /// Emit final copying of lastprivate values to original variables at
37455e20cdd8SDimitry Andric   /// the end of the worksharing or simd directive.
37465e20cdd8SDimitry Andric   ///
37475e20cdd8SDimitry Andric   /// \param D Directive that has at least one 'lastprivate' directives.
37485e20cdd8SDimitry Andric   /// \param IsLastIterCond Boolean condition that must be set to 'i1 true' if
37495e20cdd8SDimitry Andric   /// it is the last iteration of the loop code in associated directive, or to
37502e645aa5SDimitry Andric   /// 'i1 false' otherwise. If this item is nullptr, no final check is required.
37515e20cdd8SDimitry Andric   void EmitOMPLastprivateClauseFinal(const OMPExecutableDirective &D,
37522b6b257fSDimitry Andric                                      bool NoFinals,
37532e645aa5SDimitry Andric                                      llvm::Value *IsLastIterCond = nullptr);
37542b6b257fSDimitry Andric   /// Emit initial code for linear clauses.
37552b6b257fSDimitry Andric   void EmitOMPLinearClause(const OMPLoopDirective &D,
37562b6b257fSDimitry Andric                            CodeGenFunction::OMPPrivateScope &PrivateScope);
37572b6b257fSDimitry Andric   /// Emit final code for linear clauses.
37582b6b257fSDimitry Andric   /// \param CondGen Optional conditional code for final part of codegen for
37592b6b257fSDimitry Andric   /// linear clause.
37602b6b257fSDimitry Andric   void EmitOMPLinearClauseFinal(
37612b6b257fSDimitry Andric       const OMPLoopDirective &D,
376248675466SDimitry Andric       const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen);
376348675466SDimitry Andric   /// Emit initial code for reduction variables. Creates reduction copies
37645e20cdd8SDimitry Andric   /// and initializes them with the values according to OpenMP standard.
37655e20cdd8SDimitry Andric   ///
37665e20cdd8SDimitry Andric   /// \param D Directive (possibly) with the 'reduction' clause.
37675e20cdd8SDimitry Andric   /// \param PrivateScope Private scope for capturing reduction variables for
37685e20cdd8SDimitry Andric   /// proper codegen in internal captured statement.
37695e20cdd8SDimitry Andric   ///
37705e20cdd8SDimitry Andric   void EmitOMPReductionClauseInit(const OMPExecutableDirective &D,
3771cfca06d7SDimitry Andric                                   OMPPrivateScope &PrivateScope,
3772cfca06d7SDimitry Andric                                   bool ForInscan = false);
377348675466SDimitry Andric   /// Emit final update of reduction values to original variables at
37745e20cdd8SDimitry Andric   /// the end of the directive.
37755e20cdd8SDimitry Andric   ///
37765e20cdd8SDimitry Andric   /// \param D Directive that has at least one 'reduction' directives.
37777442d6faSDimitry Andric   /// \param ReductionKind The kind of reduction to perform.
37787442d6faSDimitry Andric   void EmitOMPReductionClauseFinal(const OMPExecutableDirective &D,
37797442d6faSDimitry Andric                                    const OpenMPDirectiveKind ReductionKind);
378048675466SDimitry Andric   /// Emit initial code for linear variables. Creates private copies
37812e645aa5SDimitry Andric   /// and initializes them with the values according to OpenMP standard.
37822e645aa5SDimitry Andric   ///
37832e645aa5SDimitry Andric   /// \param D Directive (possibly) with the 'linear' clause.
3784b5ea630dSDimitry Andric   /// \return true if at least one linear variable is found that should be
3785b5ea630dSDimitry Andric   /// initialized with the value of the original variable, false otherwise.
3786b5ea630dSDimitry Andric   bool EmitOMPLinearClauseInit(const OMPLoopDirective &D);
37879f4dbff6SDimitry Andric 
37882b6b257fSDimitry Andric   typedef const llvm::function_ref<void(CodeGenFunction & /*CGF*/,
378922989816SDimitry Andric                                         llvm::Function * /*OutlinedFn*/,
37902b6b257fSDimitry Andric                                         const OMPTaskDataTy & /*Data*/)>
37912b6b257fSDimitry Andric       TaskGenTy;
37922b6b257fSDimitry Andric   void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S,
379348675466SDimitry Andric                                  const OpenMPDirectiveKind CapturedRegion,
37942b6b257fSDimitry Andric                                  const RegionCodeGenTy &BodyGen,
37952b6b257fSDimitry Andric                                  const TaskGenTy &TaskGen, OMPTaskDataTy &Data);
379655e6d896SDimitry Andric   struct OMPTargetDataInfo {
379755e6d896SDimitry Andric     Address BasePointersArray = Address::invalid();
379855e6d896SDimitry Andric     Address PointersArray = Address::invalid();
379955e6d896SDimitry Andric     Address SizesArray = Address::invalid();
3800b60736ecSDimitry Andric     Address MappersArray = Address::invalid();
380155e6d896SDimitry Andric     unsigned NumberOfTargetItems = 0;
380255e6d896SDimitry Andric     explicit OMPTargetDataInfo() = default;
380355e6d896SDimitry Andric     OMPTargetDataInfo(Address BasePointersArray, Address PointersArray,
3804b60736ecSDimitry Andric                       Address SizesArray, Address MappersArray,
3805b60736ecSDimitry Andric                       unsigned NumberOfTargetItems)
380655e6d896SDimitry Andric         : BasePointersArray(BasePointersArray), PointersArray(PointersArray),
3807b60736ecSDimitry Andric           SizesArray(SizesArray), MappersArray(MappersArray),
3808b60736ecSDimitry Andric           NumberOfTargetItems(NumberOfTargetItems) {}
380955e6d896SDimitry Andric   };
381055e6d896SDimitry Andric   void EmitOMPTargetTaskBasedDirective(const OMPExecutableDirective &S,
381155e6d896SDimitry Andric                                        const RegionCodeGenTy &BodyGen,
381255e6d896SDimitry Andric                                        OMPTargetDataInfo &InputInfo);
3813145449b1SDimitry Andric   void processInReduction(const OMPExecutableDirective &S,
3814145449b1SDimitry Andric                           OMPTaskDataTy &Data,
3815145449b1SDimitry Andric                           CodeGenFunction &CGF,
3816145449b1SDimitry Andric                           const CapturedStmt *CS,
3817145449b1SDimitry Andric                           OMPPrivateScope &Scope);
3818c0981da4SDimitry Andric   void EmitOMPMetaDirective(const OMPMetaDirective &S);
38199f4dbff6SDimitry Andric   void EmitOMPParallelDirective(const OMPParallelDirective &S);
38209f4dbff6SDimitry Andric   void EmitOMPSimdDirective(const OMPSimdDirective &S);
3821344a3780SDimitry Andric   void EmitOMPTileDirective(const OMPTileDirective &S);
3822344a3780SDimitry Andric   void EmitOMPUnrollDirective(const OMPUnrollDirective &S);
3823ac9a064cSDimitry Andric   void EmitOMPReverseDirective(const OMPReverseDirective &S);
3824ac9a064cSDimitry Andric   void EmitOMPInterchangeDirective(const OMPInterchangeDirective &S);
38259f4dbff6SDimitry Andric   void EmitOMPForDirective(const OMPForDirective &S);
382606d4ba38SDimitry Andric   void EmitOMPForSimdDirective(const OMPForSimdDirective &S);
38279f4dbff6SDimitry Andric   void EmitOMPSectionsDirective(const OMPSectionsDirective &S);
38289f4dbff6SDimitry Andric   void EmitOMPSectionDirective(const OMPSectionDirective &S);
38299f4dbff6SDimitry Andric   void EmitOMPSingleDirective(const OMPSingleDirective &S);
38309f4dbff6SDimitry Andric   void EmitOMPMasterDirective(const OMPMasterDirective &S);
3831344a3780SDimitry Andric   void EmitOMPMaskedDirective(const OMPMaskedDirective &S);
38329f4dbff6SDimitry Andric   void EmitOMPCriticalDirective(const OMPCriticalDirective &S);
38339f4dbff6SDimitry Andric   void EmitOMPParallelForDirective(const OMPParallelForDirective &S);
383406d4ba38SDimitry Andric   void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S);
38359f4dbff6SDimitry Andric   void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S);
3836706b4fc4SDimitry Andric   void EmitOMPParallelMasterDirective(const OMPParallelMasterDirective &S);
38379f4dbff6SDimitry Andric   void EmitOMPTaskDirective(const OMPTaskDirective &S);
38389f4dbff6SDimitry Andric   void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S);
3839e3b55780SDimitry Andric   void EmitOMPErrorDirective(const OMPErrorDirective &S);
38409f4dbff6SDimitry Andric   void EmitOMPBarrierDirective(const OMPBarrierDirective &S);
38419f4dbff6SDimitry Andric   void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S);
38422e645aa5SDimitry Andric   void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S);
38439f4dbff6SDimitry Andric   void EmitOMPFlushDirective(const OMPFlushDirective &S);
3844cfca06d7SDimitry Andric   void EmitOMPDepobjDirective(const OMPDepobjDirective &S);
3845cfca06d7SDimitry Andric   void EmitOMPScanDirective(const OMPScanDirective &S);
384606d4ba38SDimitry Andric   void EmitOMPOrderedDirective(const OMPOrderedDirective &S);
384706d4ba38SDimitry Andric   void EmitOMPAtomicDirective(const OMPAtomicDirective &S);
384806d4ba38SDimitry Andric   void EmitOMPTargetDirective(const OMPTargetDirective &S);
384945b53394SDimitry Andric   void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S);
38502b6b257fSDimitry Andric   void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S);
38512b6b257fSDimitry Andric   void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S);
38522b6b257fSDimitry Andric   void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S);
38532b6b257fSDimitry Andric   void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S);
38542b6b257fSDimitry Andric   void
38552b6b257fSDimitry Andric   EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S);
385606d4ba38SDimitry Andric   void EmitOMPTeamsDirective(const OMPTeamsDirective &S);
3857c192b3dcSDimitry Andric   void
3858c192b3dcSDimitry Andric   EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S);
3859c192b3dcSDimitry Andric   void EmitOMPCancelDirective(const OMPCancelDirective &S);
38602b6b257fSDimitry Andric   void EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S);
386145b53394SDimitry Andric   void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S);
386245b53394SDimitry Andric   void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S);
3863519fc96cSDimitry Andric   void EmitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &S);
3864519fc96cSDimitry Andric   void
3865519fc96cSDimitry Andric   EmitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective &S);
3866519fc96cSDimitry Andric   void EmitOMPParallelMasterTaskLoopDirective(
3867519fc96cSDimitry Andric       const OMPParallelMasterTaskLoopDirective &S);
3868706b4fc4SDimitry Andric   void EmitOMPParallelMasterTaskLoopSimdDirective(
3869706b4fc4SDimitry Andric       const OMPParallelMasterTaskLoopSimdDirective &S);
387045b53394SDimitry Andric   void EmitOMPDistributeDirective(const OMPDistributeDirective &S);
38712b6b257fSDimitry Andric   void EmitOMPDistributeParallelForDirective(
38722b6b257fSDimitry Andric       const OMPDistributeParallelForDirective &S);
38732b6b257fSDimitry Andric   void EmitOMPDistributeParallelForSimdDirective(
38742b6b257fSDimitry Andric       const OMPDistributeParallelForSimdDirective &S);
38752b6b257fSDimitry Andric   void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S);
38762b6b257fSDimitry Andric   void EmitOMPTargetParallelForSimdDirective(
38772b6b257fSDimitry Andric       const OMPTargetParallelForSimdDirective &S);
3878bab175ecSDimitry Andric   void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S);
3879bab175ecSDimitry Andric   void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S);
3880bab175ecSDimitry Andric   void
3881bab175ecSDimitry Andric   EmitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &S);
3882bab175ecSDimitry Andric   void EmitOMPTeamsDistributeParallelForSimdDirective(
3883bab175ecSDimitry Andric       const OMPTeamsDistributeParallelForSimdDirective &S);
3884bab175ecSDimitry Andric   void EmitOMPTeamsDistributeParallelForDirective(
3885bab175ecSDimitry Andric       const OMPTeamsDistributeParallelForDirective &S);
3886bab175ecSDimitry Andric   void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S);
3887bab175ecSDimitry Andric   void EmitOMPTargetTeamsDistributeDirective(
3888bab175ecSDimitry Andric       const OMPTargetTeamsDistributeDirective &S);
3889bab175ecSDimitry Andric   void EmitOMPTargetTeamsDistributeParallelForDirective(
3890bab175ecSDimitry Andric       const OMPTargetTeamsDistributeParallelForDirective &S);
38910c75eea8SDimitry Andric   void EmitOMPTargetTeamsDistributeParallelForSimdDirective(
38920c75eea8SDimitry Andric       const OMPTargetTeamsDistributeParallelForSimdDirective &S);
3893d2e0a8ddSDimitry Andric   void EmitOMPTargetTeamsDistributeSimdDirective(
3894d2e0a8ddSDimitry Andric       const OMPTargetTeamsDistributeSimdDirective &S);
3895c0981da4SDimitry Andric   void EmitOMPGenericLoopDirective(const OMPGenericLoopDirective &S);
38967fa27ce4SDimitry Andric   void EmitOMPParallelGenericLoopDirective(const OMPLoopDirective &S);
38977fa27ce4SDimitry Andric   void EmitOMPTargetParallelGenericLoopDirective(
38987fa27ce4SDimitry Andric       const OMPTargetParallelGenericLoopDirective &S);
38997fa27ce4SDimitry Andric   void EmitOMPTargetTeamsGenericLoopDirective(
39007fa27ce4SDimitry Andric       const OMPTargetTeamsGenericLoopDirective &S);
39017fa27ce4SDimitry Andric   void EmitOMPTeamsGenericLoopDirective(const OMPTeamsGenericLoopDirective &S);
3902ecbca9f5SDimitry Andric   void EmitOMPInteropDirective(const OMPInteropDirective &S);
39037fa27ce4SDimitry Andric   void EmitOMPParallelMaskedDirective(const OMPParallelMaskedDirective &S);
390406d4ba38SDimitry Andric 
39057442d6faSDimitry Andric   /// Emit device code for the target directive.
39067442d6faSDimitry Andric   static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
39072b6b257fSDimitry Andric                                           StringRef ParentName,
39087442d6faSDimitry Andric                                           const OMPTargetDirective &S);
39097442d6faSDimitry Andric   static void
39107442d6faSDimitry Andric   EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName,
39117442d6faSDimitry Andric                                       const OMPTargetParallelDirective &S);
3912461a67faSDimitry Andric   /// Emit device code for the target parallel for directive.
3913461a67faSDimitry Andric   static void EmitOMPTargetParallelForDeviceFunction(
3914461a67faSDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
3915461a67faSDimitry Andric       const OMPTargetParallelForDirective &S);
3916461a67faSDimitry Andric   /// Emit device code for the target parallel for simd directive.
3917461a67faSDimitry Andric   static void EmitOMPTargetParallelForSimdDeviceFunction(
3918461a67faSDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
3919461a67faSDimitry Andric       const OMPTargetParallelForSimdDirective &S);
3920461a67faSDimitry Andric   /// Emit device code for the target teams directive.
39217442d6faSDimitry Andric   static void
39227442d6faSDimitry Andric   EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName,
39237442d6faSDimitry Andric                                    const OMPTargetTeamsDirective &S);
3924461a67faSDimitry Andric   /// Emit device code for the target teams distribute directive.
3925461a67faSDimitry Andric   static void EmitOMPTargetTeamsDistributeDeviceFunction(
3926461a67faSDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
3927461a67faSDimitry Andric       const OMPTargetTeamsDistributeDirective &S);
3928461a67faSDimitry Andric   /// Emit device code for the target teams distribute simd directive.
3929461a67faSDimitry Andric   static void EmitOMPTargetTeamsDistributeSimdDeviceFunction(
3930461a67faSDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
3931461a67faSDimitry Andric       const OMPTargetTeamsDistributeSimdDirective &S);
3932461a67faSDimitry Andric   /// Emit device code for the target simd directive.
3933461a67faSDimitry Andric   static void EmitOMPTargetSimdDeviceFunction(CodeGenModule &CGM,
3934461a67faSDimitry Andric                                               StringRef ParentName,
3935461a67faSDimitry Andric                                               const OMPTargetSimdDirective &S);
393648675466SDimitry Andric   /// Emit device code for the target teams distribute parallel for simd
393748675466SDimitry Andric   /// directive.
393848675466SDimitry Andric   static void EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(
393948675466SDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
394048675466SDimitry Andric       const OMPTargetTeamsDistributeParallelForSimdDirective &S);
394148675466SDimitry Andric 
39427fa27ce4SDimitry Andric   /// Emit device code for the target teams loop directive.
39437fa27ce4SDimitry Andric   static void EmitOMPTargetTeamsGenericLoopDeviceFunction(
39447fa27ce4SDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
39457fa27ce4SDimitry Andric       const OMPTargetTeamsGenericLoopDirective &S);
39467fa27ce4SDimitry Andric 
39477fa27ce4SDimitry Andric   /// Emit device code for the target parallel loop directive.
39487fa27ce4SDimitry Andric   static void EmitOMPTargetParallelGenericLoopDeviceFunction(
39497fa27ce4SDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
39507fa27ce4SDimitry Andric       const OMPTargetParallelGenericLoopDirective &S);
39517fa27ce4SDimitry Andric 
395248675466SDimitry Andric   static void EmitOMPTargetTeamsDistributeParallelForDeviceFunction(
395348675466SDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
395448675466SDimitry Andric       const OMPTargetTeamsDistributeParallelForDirective &S);
3955344a3780SDimitry Andric 
3956344a3780SDimitry Andric   /// Emit the Stmt \p S and return its topmost canonical loop, if any.
3957344a3780SDimitry Andric   /// TODO: The \p Depth paramter is not yet implemented and must be 1. In the
3958344a3780SDimitry Andric   /// future it is meant to be the number of loops expected in the loop nests
3959344a3780SDimitry Andric   /// (usually specified by the "collapse" clause) that are collapsed to a
3960344a3780SDimitry Andric   /// single loop by this function.
3961344a3780SDimitry Andric   llvm::CanonicalLoopInfo *EmitOMPCollapsedCanonicalLoopNest(const Stmt *S,
3962344a3780SDimitry Andric                                                              int Depth);
3963344a3780SDimitry Andric 
3964344a3780SDimitry Andric   /// Emit an OMPCanonicalLoop using the OpenMPIRBuilder.
3965344a3780SDimitry Andric   void EmitOMPCanonicalLoop(const OMPCanonicalLoop *S);
3966344a3780SDimitry Andric 
396748675466SDimitry Andric   /// Emit inner loop of the worksharing/simd construct.
39685e20cdd8SDimitry Andric   ///
39695e20cdd8SDimitry Andric   /// \param S Directive, for which the inner loop must be emitted.
39705e20cdd8SDimitry Andric   /// \param RequiresCleanup true, if directive has some associated private
39715e20cdd8SDimitry Andric   /// variables.
39725e20cdd8SDimitry Andric   /// \param LoopCond Bollean condition for loop continuation.
39735e20cdd8SDimitry Andric   /// \param IncExpr Increment expression for loop control variable.
39745e20cdd8SDimitry Andric   /// \param BodyGen Generator for the inner body of the inner loop.
39755e20cdd8SDimitry Andric   /// \param PostIncGen Genrator for post-increment code (required for ordered
39765e20cdd8SDimitry Andric   /// loop directvies).
39775e20cdd8SDimitry Andric   void EmitOMPInnerLoop(
3978cfca06d7SDimitry Andric       const OMPExecutableDirective &S, bool RequiresCleanup,
3979cfca06d7SDimitry Andric       const Expr *LoopCond, const Expr *IncExpr,
398048675466SDimitry Andric       const llvm::function_ref<void(CodeGenFunction &)> BodyGen,
398148675466SDimitry Andric       const llvm::function_ref<void(CodeGenFunction &)> PostIncGen);
39825e20cdd8SDimitry Andric 
3983c192b3dcSDimitry Andric   JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind);
39842b6b257fSDimitry Andric   /// Emit initial code for loop counters of loop-based directives.
39852b6b257fSDimitry Andric   void EmitOMPPrivateLoopCounters(const OMPLoopDirective &S,
39862b6b257fSDimitry Andric                                   OMPPrivateScope &LoopScope);
3987c192b3dcSDimitry Andric 
3988f0c55418SDimitry Andric   /// Helper for the OpenMP loop directives.
3989f0c55418SDimitry Andric   void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit);
3990f0c55418SDimitry Andric 
399148675466SDimitry Andric   /// Emit code for the worksharing loop-based directive.
3992f0c55418SDimitry Andric   /// \return true, if this construct has any lastprivate clause, false -
3993f0c55418SDimitry Andric   /// otherwise.
3994f0c55418SDimitry Andric   bool EmitOMPWorksharingLoop(const OMPLoopDirective &S, Expr *EUB,
3995f0c55418SDimitry Andric                               const CodeGenLoopBoundsTy &CodeGenLoopBounds,
3996f0c55418SDimitry Andric                               const CodeGenDispatchBoundsTy &CGDispatchBounds);
3997f0c55418SDimitry Andric 
3998461a67faSDimitry Andric   /// Emit code for the distribute loop-based directive.
3999461a67faSDimitry Andric   void EmitOMPDistributeLoop(const OMPLoopDirective &S,
4000461a67faSDimitry Andric                              const CodeGenLoopTy &CodeGenLoop, Expr *IncExpr);
4001bab175ecSDimitry Andric 
400206d4ba38SDimitry Andric   /// Helpers for the OpenMP loop directives.
4003344a3780SDimitry Andric   void EmitOMPSimdInit(const OMPLoopDirective &D);
40042b6b257fSDimitry Andric   void EmitOMPSimdFinal(
40052b6b257fSDimitry Andric       const OMPLoopDirective &D,
400648675466SDimitry Andric       const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen);
4007f0c55418SDimitry Andric 
4008461a67faSDimitry Andric   /// Emits the lvalue for the expression with possibly captured variable.
4009461a67faSDimitry Andric   LValue EmitOMPSharedLValue(const Expr *E);
4010461a67faSDimitry Andric 
4011461a67faSDimitry Andric private:
401248675466SDimitry Andric   /// Helpers for blocks.
401348675466SDimitry Andric   llvm::Value *EmitBlockLiteral(const CGBlockInfo &Info);
4014f0c55418SDimitry Andric 
4015f0c55418SDimitry Andric   /// struct with the values to be passed to the OpenMP loop-related functions
4016f0c55418SDimitry Andric   struct OMPLoopArguments {
4017f0c55418SDimitry Andric     /// loop lower bound
4018f0c55418SDimitry Andric     Address LB = Address::invalid();
4019f0c55418SDimitry Andric     /// loop upper bound
4020f0c55418SDimitry Andric     Address UB = Address::invalid();
4021f0c55418SDimitry Andric     /// loop stride
4022f0c55418SDimitry Andric     Address ST = Address::invalid();
4023f0c55418SDimitry Andric     /// isLastIteration argument for runtime functions
4024f0c55418SDimitry Andric     Address IL = Address::invalid();
4025f0c55418SDimitry Andric     /// Chunk value generated by sema
4026f0c55418SDimitry Andric     llvm::Value *Chunk = nullptr;
4027f0c55418SDimitry Andric     /// EnsureUpperBound
4028f0c55418SDimitry Andric     Expr *EUB = nullptr;
4029f0c55418SDimitry Andric     /// IncrementExpression
4030f0c55418SDimitry Andric     Expr *IncExpr = nullptr;
4031f0c55418SDimitry Andric     /// Loop initialization
4032f0c55418SDimitry Andric     Expr *Init = nullptr;
4033f0c55418SDimitry Andric     /// Loop exit condition
4034f0c55418SDimitry Andric     Expr *Cond = nullptr;
4035f0c55418SDimitry Andric     /// Update of LB after a whole chunk has been executed
4036f0c55418SDimitry Andric     Expr *NextLB = nullptr;
4037f0c55418SDimitry Andric     /// Update of UB after a whole chunk has been executed
4038f0c55418SDimitry Andric     Expr *NextUB = nullptr;
4039ac9a064cSDimitry Andric     /// Distinguish between the for distribute and sections
4040ac9a064cSDimitry Andric     OpenMPDirectiveKind DKind = llvm::omp::OMPD_unknown;
4041f0c55418SDimitry Andric     OMPLoopArguments() = default;
4042f0c55418SDimitry Andric     OMPLoopArguments(Address LB, Address UB, Address ST, Address IL,
4043f0c55418SDimitry Andric                      llvm::Value *Chunk = nullptr, Expr *EUB = nullptr,
4044f0c55418SDimitry Andric                      Expr *IncExpr = nullptr, Expr *Init = nullptr,
4045f0c55418SDimitry Andric                      Expr *Cond = nullptr, Expr *NextLB = nullptr,
4046f0c55418SDimitry Andric                      Expr *NextUB = nullptr)
4047f0c55418SDimitry Andric         : LB(LB), UB(UB), ST(ST), IL(IL), Chunk(Chunk), EUB(EUB),
4048f0c55418SDimitry Andric           IncExpr(IncExpr), Init(Init), Cond(Cond), NextLB(NextLB),
4049f0c55418SDimitry Andric           NextUB(NextUB) {}
4050f0c55418SDimitry Andric   };
4051f0c55418SDimitry Andric   void EmitOMPOuterLoop(bool DynamicOrOrdered, bool IsMonotonic,
4052f0c55418SDimitry Andric                         const OMPLoopDirective &S, OMPPrivateScope &LoopScope,
4053f0c55418SDimitry Andric                         const OMPLoopArguments &LoopArgs,
4054f0c55418SDimitry Andric                         const CodeGenLoopTy &CodeGenLoop,
4055f0c55418SDimitry Andric                         const CodeGenOrderedTy &CodeGenOrdered);
40562b6b257fSDimitry Andric   void EmitOMPForOuterLoop(const OpenMPScheduleTy &ScheduleKind,
405797b17066SDimitry Andric                            bool IsMonotonic, const OMPLoopDirective &S,
4058f0c55418SDimitry Andric                            OMPPrivateScope &LoopScope, bool Ordered,
4059f0c55418SDimitry Andric                            const OMPLoopArguments &LoopArgs,
4060f0c55418SDimitry Andric                            const CodeGenDispatchBoundsTy &CGDispatchBounds);
4061f0c55418SDimitry Andric   void EmitOMPDistributeOuterLoop(OpenMPDistScheduleClauseKind ScheduleKind,
4062f0c55418SDimitry Andric                                   const OMPLoopDirective &S,
4063f0c55418SDimitry Andric                                   OMPPrivateScope &LoopScope,
4064f0c55418SDimitry Andric                                   const OMPLoopArguments &LoopArgs,
4065f0c55418SDimitry Andric                                   const CodeGenLoopTy &CodeGenLoopContent);
406648675466SDimitry Andric   /// Emit code for sections directive.
40672b6b257fSDimitry Andric   void EmitSections(const OMPExecutableDirective &S);
406806d4ba38SDimitry Andric 
406906d4ba38SDimitry Andric public:
4070ac9a064cSDimitry Andric   //===--------------------------------------------------------------------===//
4071ac9a064cSDimitry Andric   //                         OpenACC Emission
4072ac9a064cSDimitry Andric   //===--------------------------------------------------------------------===//
4073ac9a064cSDimitry Andric   void EmitOpenACCComputeConstruct(const OpenACCComputeConstruct &S) {
4074ac9a064cSDimitry Andric     // TODO OpenACC: Implement this.  It is currently implemented as a 'no-op',
4075ac9a064cSDimitry Andric     // simply emitting its structured block, but in the future we will implement
4076ac9a064cSDimitry Andric     // some sort of IR.
4077ac9a064cSDimitry Andric     EmitStmt(S.getStructuredBlock());
4078ac9a064cSDimitry Andric   }
4079ac9a064cSDimitry Andric 
4080ac9a064cSDimitry Andric   void EmitOpenACCLoopConstruct(const OpenACCLoopConstruct &S) {
4081ac9a064cSDimitry Andric     // TODO OpenACC: Implement this.  It is currently implemented as a 'no-op',
4082ac9a064cSDimitry Andric     // simply emitting its loop, but in the future we will implement
4083ac9a064cSDimitry Andric     // some sort of IR.
4084ac9a064cSDimitry Andric     EmitStmt(S.getLoop());
4085ac9a064cSDimitry Andric   }
4086bfef3995SDimitry Andric 
4087ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
4088ec2b103cSEd Schouten   //                         LValue Expression Emission
4089ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
4090ec2b103cSEd Schouten 
4091b60736ecSDimitry Andric   /// Create a check that a scalar RValue is non-null.
4092b60736ecSDimitry Andric   llvm::Value *EmitNonNullRValueCheck(RValue RV, QualType T);
4093b60736ecSDimitry Andric 
4094ec2b103cSEd Schouten   /// GetUndefRValue - Get an appropriate 'undef' rvalue for the given type.
4095ec2b103cSEd Schouten   RValue GetUndefRValue(QualType Ty);
4096ec2b103cSEd Schouten 
4097ec2b103cSEd Schouten   /// EmitUnsupportedRValue - Emit a dummy r-value using the type of E
4098ec2b103cSEd Schouten   /// and issue an ErrorUnsupported style diagnostic (using the
4099ec2b103cSEd Schouten   /// provided Name).
4100ec2b103cSEd Schouten   RValue EmitUnsupportedRValue(const Expr *E,
4101ec2b103cSEd Schouten                                const char *Name);
4102ec2b103cSEd Schouten 
4103ec2b103cSEd Schouten   /// EmitUnsupportedLValue - Emit a dummy l-value using the type of E and issue
4104ec2b103cSEd Schouten   /// an ErrorUnsupported style diagnostic (using the provided Name).
4105ec2b103cSEd Schouten   LValue EmitUnsupportedLValue(const Expr *E,
4106ec2b103cSEd Schouten                                const char *Name);
4107ec2b103cSEd Schouten 
4108ec2b103cSEd Schouten   /// EmitLValue - Emit code to compute a designator that specifies the location
4109ec2b103cSEd Schouten   /// of the expression.
4110ec2b103cSEd Schouten   ///
4111ec2b103cSEd Schouten   /// This can return one of two things: a simple address or a bitfield
4112ec2b103cSEd Schouten   /// reference.  In either case, the LLVM Value* in the LValue structure is
4113ec2b103cSEd Schouten   /// guaranteed to be an LLVM pointer type.
4114ec2b103cSEd Schouten   ///
4115ec2b103cSEd Schouten   /// If this returns a bitfield reference, nothing about the pointee type of
4116ec2b103cSEd Schouten   /// the LLVM value is known: For example, it may not be a pointer to an
4117ec2b103cSEd Schouten   /// integer.
4118ec2b103cSEd Schouten   ///
4119ec2b103cSEd Schouten   /// If this returns a normal address, and if the lvalue's C type is fixed
4120ec2b103cSEd Schouten   /// size, this method guarantees that the returned pointer type will point to
4121ec2b103cSEd Schouten   /// an LLVM type of the same size of the lvalue's type.  If the lvalue has a
4122ec2b103cSEd Schouten   /// variable length type, this is not possible.
4123ec2b103cSEd Schouten   ///
41247fa27ce4SDimitry Andric   LValue EmitLValue(const Expr *E,
41257fa27ce4SDimitry Andric                     KnownNonNull_t IsKnownNonNull = NotKnownNonNull);
4126ec2b103cSEd Schouten 
41277fa27ce4SDimitry Andric private:
41287fa27ce4SDimitry Andric   LValue EmitLValueHelper(const Expr *E, KnownNonNull_t IsKnownNonNull);
41297fa27ce4SDimitry Andric 
41307fa27ce4SDimitry Andric public:
413148675466SDimitry Andric   /// Same as EmitLValue but additionally we generate checking code to
413213cc256eSDimitry Andric   /// guard against undefined behavior.  This is only suitable when we know
413313cc256eSDimitry Andric   /// that the address will be used to access the object.
413413cc256eSDimitry Andric   LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK);
4135abe15e55SRoman Divacky 
413645b53394SDimitry Andric   RValue convertTempToRValue(Address addr, QualType type,
4137bfef3995SDimitry Andric                              SourceLocation Loc);
4138809500fcSDimitry Andric 
4139809500fcSDimitry Andric   void EmitAtomicInit(Expr *E, LValue lvalue);
4140809500fcSDimitry Andric 
41415e20cdd8SDimitry Andric   bool LValueIsSuitableForInlineAtomic(LValue Src);
41425e20cdd8SDimitry Andric 
41435e20cdd8SDimitry Andric   RValue EmitAtomicLoad(LValue LV, SourceLocation SL,
41445e20cdd8SDimitry Andric                         AggValueSlot Slot = AggValueSlot::ignored());
41455e20cdd8SDimitry Andric 
4146bfef3995SDimitry Andric   RValue EmitAtomicLoad(LValue lvalue, SourceLocation loc,
41475e20cdd8SDimitry Andric                         llvm::AtomicOrdering AO, bool IsVolatile = false,
4148809500fcSDimitry Andric                         AggValueSlot slot = AggValueSlot::ignored());
4149809500fcSDimitry Andric 
4150809500fcSDimitry Andric   void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit);
4151809500fcSDimitry Andric 
41525e20cdd8SDimitry Andric   void EmitAtomicStore(RValue rvalue, LValue lvalue, llvm::AtomicOrdering AO,
41535e20cdd8SDimitry Andric                        bool IsVolatile, bool isInit);
41545e20cdd8SDimitry Andric 
41555e20cdd8SDimitry Andric   std::pair<RValue, llvm::Value *> EmitAtomicCompareExchange(
415606d4ba38SDimitry Andric       LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc,
41572b6b257fSDimitry Andric       llvm::AtomicOrdering Success =
41582b6b257fSDimitry Andric           llvm::AtomicOrdering::SequentiallyConsistent,
41592b6b257fSDimitry Andric       llvm::AtomicOrdering Failure =
41602b6b257fSDimitry Andric           llvm::AtomicOrdering::SequentiallyConsistent,
416106d4ba38SDimitry Andric       bool IsWeak = false, AggValueSlot Slot = AggValueSlot::ignored());
416206d4ba38SDimitry Andric 
41635e20cdd8SDimitry Andric   void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO,
41645e20cdd8SDimitry Andric                         const llvm::function_ref<RValue(RValue)> &UpdateOp,
41655e20cdd8SDimitry Andric                         bool IsVolatile);
41665e20cdd8SDimitry Andric 
4167bca07a45SDimitry Andric   /// EmitToMemory - Change a scalar value from its value
4168bca07a45SDimitry Andric   /// representation to its in-memory representation.
4169bca07a45SDimitry Andric   llvm::Value *EmitToMemory(llvm::Value *Value, QualType Ty);
4170bca07a45SDimitry Andric 
4171bca07a45SDimitry Andric   /// EmitFromMemory - Change a scalar value from its memory
4172bca07a45SDimitry Andric   /// representation to its value representation.
4173bca07a45SDimitry Andric   llvm::Value *EmitFromMemory(llvm::Value *Value, QualType Ty);
4174bca07a45SDimitry Andric 
41757442d6faSDimitry Andric   /// Check if the scalar \p Value is within the valid range for the given
41767442d6faSDimitry Andric   /// type \p Ty.
41777442d6faSDimitry Andric   ///
41787442d6faSDimitry Andric   /// Returns true if a check is needed (even if the range is unknown).
41797442d6faSDimitry Andric   bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
41807442d6faSDimitry Andric                             SourceLocation Loc);
41817442d6faSDimitry Andric 
4182ec2b103cSEd Schouten   /// EmitLoadOfScalar - Load a scalar value from an address, taking
4183ec2b103cSEd Schouten   /// care to appropriately convert from the memory representation to
4184ec2b103cSEd Schouten   /// the LLVM value representation.
418545b53394SDimitry Andric   llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty,
4186bfef3995SDimitry Andric                                 SourceLocation Loc,
4187461a67faSDimitry Andric                                 AlignmentSource Source = AlignmentSource::Type,
4188461a67faSDimitry Andric                                 bool isNontemporal = false) {
4189461a67faSDimitry Andric     return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, LValueBaseInfo(Source),
4190461a67faSDimitry Andric                             CGM.getTBAAAccessInfo(Ty), isNontemporal);
4191461a67faSDimitry Andric   }
4192461a67faSDimitry Andric 
4193461a67faSDimitry Andric   llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty,
4194461a67faSDimitry Andric                                 SourceLocation Loc, LValueBaseInfo BaseInfo,
4195461a67faSDimitry Andric                                 TBAAAccessInfo TBAAInfo,
419645b53394SDimitry Andric                                 bool isNontemporal = false);
4197ec2b103cSEd Schouten 
4198180abc3dSDimitry Andric   /// EmitLoadOfScalar - Load a scalar value from an address, taking
4199180abc3dSDimitry Andric   /// care to appropriately convert from the memory representation to
4200180abc3dSDimitry Andric   /// the LLVM value representation.  The l-value must be a simple
4201180abc3dSDimitry Andric   /// l-value.
4202bfef3995SDimitry Andric   llvm::Value *EmitLoadOfScalar(LValue lvalue, SourceLocation Loc);
4203180abc3dSDimitry Andric 
4204ec2b103cSEd Schouten   /// EmitStoreOfScalar - Store a scalar value to an address, taking
4205ec2b103cSEd Schouten   /// care to appropriately convert from the memory representation to
4206ec2b103cSEd Schouten   /// the LLVM value representation.
420745b53394SDimitry Andric   void EmitStoreOfScalar(llvm::Value *Value, Address Addr,
420845b53394SDimitry Andric                          bool Volatile, QualType Ty,
4209461a67faSDimitry Andric                          AlignmentSource Source = AlignmentSource::Type,
4210461a67faSDimitry Andric                          bool isInit = false, bool isNontemporal = false) {
4211461a67faSDimitry Andric     EmitStoreOfScalar(Value, Addr, Volatile, Ty, LValueBaseInfo(Source),
4212461a67faSDimitry Andric                       CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal);
4213461a67faSDimitry Andric   }
4214461a67faSDimitry Andric 
4215461a67faSDimitry Andric   void EmitStoreOfScalar(llvm::Value *Value, Address Addr,
4216461a67faSDimitry Andric                          bool Volatile, QualType Ty,
4217461a67faSDimitry Andric                          LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo,
4218461a67faSDimitry Andric                          bool isInit = false, bool isNontemporal = false);
4219ec2b103cSEd Schouten 
4220180abc3dSDimitry Andric   /// EmitStoreOfScalar - Store a scalar value to an address, taking
4221180abc3dSDimitry Andric   /// care to appropriately convert from the memory representation to
4222180abc3dSDimitry Andric   /// the LLVM value representation.  The l-value must be a simple
4223dbe13110SDimitry Andric   /// l-value.  The isInit flag indicates whether this is an initialization.
4224dbe13110SDimitry Andric   /// If so, atomic qualifiers are ignored and the store is always non-atomic.
4225dbe13110SDimitry Andric   void EmitStoreOfScalar(llvm::Value *value, LValue lvalue, bool isInit=false);
4226180abc3dSDimitry Andric 
4227ec2b103cSEd Schouten   /// EmitLoadOfLValue - Given an expression that represents a value lvalue,
4228ec2b103cSEd Schouten   /// this method emits the address of the lvalue, then loads the result as an
4229ec2b103cSEd Schouten   /// rvalue, returning the rvalue.
4230bfef3995SDimitry Andric   RValue EmitLoadOfLValue(LValue V, SourceLocation Loc);
4231180abc3dSDimitry Andric   RValue EmitLoadOfExtVectorElementLValue(LValue V);
42327442d6faSDimitry Andric   RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc);
42339f4dbff6SDimitry Andric   RValue EmitLoadOfGlobalRegLValue(LValue LV);
4234ec2b103cSEd Schouten 
4235ac9a064cSDimitry Andric   /// Like EmitLoadOfLValue but also handles complex and aggregate types.
4236ac9a064cSDimitry Andric   RValue EmitLoadOfAnyValue(LValue V,
4237ac9a064cSDimitry Andric                             AggValueSlot Slot = AggValueSlot::ignored(),
4238ac9a064cSDimitry Andric                             SourceLocation Loc = {});
4239ac9a064cSDimitry Andric 
4240ec2b103cSEd Schouten   /// EmitStoreThroughLValue - Store the specified rvalue into the specified
4241ec2b103cSEd Schouten   /// lvalue, where both are guaranteed to the have the same type, and that type
4242ec2b103cSEd Schouten   /// is 'Ty'.
4243dbe13110SDimitry Andric   void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit = false);
4244180abc3dSDimitry Andric   void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst);
42459f4dbff6SDimitry Andric   void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst);
4246ec2b103cSEd Schouten 
4247bfef3995SDimitry Andric   /// EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints
4248bfef3995SDimitry Andric   /// as EmitStoreThroughLValue.
4249ec2b103cSEd Schouten   ///
4250ec2b103cSEd Schouten   /// \param Result [out] - If non-null, this will be set to a Value* for the
4251ec2b103cSEd Schouten   /// bit-field contents after the store, appropriate for use as the result of
4252ec2b103cSEd Schouten   /// an assignment to the bit-field.
4253180abc3dSDimitry Andric   void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
42549f4dbff6SDimitry Andric                                       llvm::Value **Result=nullptr);
4255ec2b103cSEd Schouten 
4256bca07a45SDimitry Andric   /// Emit an l-value for an assignment (simple or compound) of complex type.
4257bca07a45SDimitry Andric   LValue EmitComplexAssignmentLValue(const BinaryOperator *E);
4258bca07a45SDimitry Andric   LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E);
42595e20cdd8SDimitry Andric   LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E,
4260bfef3995SDimitry Andric                                              llvm::Value *&Result);
4261bca07a45SDimitry Andric 
426201af97d3SDimitry Andric   // Note: only available for agg return types
4263ec2b103cSEd Schouten   LValue EmitBinaryOperatorLValue(const BinaryOperator *E);
4264bca07a45SDimitry Andric   LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E);
4265ec2b103cSEd Schouten   // Note: only available for agg return types
4266ec2b103cSEd Schouten   LValue EmitCallExprLValue(const CallExpr *E);
4267ec2b103cSEd Schouten   // Note: only available for agg return types
4268ec2b103cSEd Schouten   LValue EmitVAArgExprLValue(const VAArgExpr *E);
4269ec2b103cSEd Schouten   LValue EmitDeclRefLValue(const DeclRefExpr *E);
4270ec2b103cSEd Schouten   LValue EmitStringLiteralLValue(const StringLiteral *E);
4271ec2b103cSEd Schouten   LValue EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E);
4272ec2b103cSEd Schouten   LValue EmitPredefinedLValue(const PredefinedExpr *E);
4273ec2b103cSEd Schouten   LValue EmitUnaryOpLValue(const UnaryOperator *E);
4274809500fcSDimitry Andric   LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
4275809500fcSDimitry Andric                                 bool Accessed = false);
4276cfca06d7SDimitry Andric   LValue EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E);
4277ac9a064cSDimitry Andric   LValue EmitArraySectionExpr(const ArraySectionExpr *E,
427845b53394SDimitry Andric                               bool IsLowerBound = true);
4279ec2b103cSEd Schouten   LValue EmitExtVectorElementExpr(const ExtVectorElementExpr *E);
4280ec2b103cSEd Schouten   LValue EmitMemberExpr(const MemberExpr *E);
428134d02d0bSRoman Divacky   LValue EmitObjCIsaExpr(const ObjCIsaExpr *E);
4282ec2b103cSEd Schouten   LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E);
428356d91b49SDimitry Andric   LValue EmitInitListLValue(const InitListExpr *E);
4284145449b1SDimitry Andric   void EmitIgnoredConditionalOperator(const AbstractConditionalOperator *E);
4285bca07a45SDimitry Andric   LValue EmitConditionalOperatorLValue(const AbstractConditionalOperator *E);
4286ec2b103cSEd Schouten   LValue EmitCastLValue(const CastExpr *E);
4287180abc3dSDimitry Andric   LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
4288bca07a45SDimitry Andric   LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e);
4289b3d5a323SRoman Divacky 
429045b53394SDimitry Andric   Address EmitExtVectorElementLValue(LValue V);
429106d4ba38SDimitry Andric 
4292bfef3995SDimitry Andric   RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc);
42936b9a6e39SDimitry Andric 
429445b53394SDimitry Andric   Address EmitArrayToPointerDecay(const Expr *Array,
4295461a67faSDimitry Andric                                   LValueBaseInfo *BaseInfo = nullptr,
4296461a67faSDimitry Andric                                   TBAAAccessInfo *TBAAInfo = nullptr);
429745b53394SDimitry Andric 
4298dbe13110SDimitry Andric   class ConstantEmission {
4299dbe13110SDimitry Andric     llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference;
4300dbe13110SDimitry Andric     ConstantEmission(llvm::Constant *C, bool isReference)
4301dbe13110SDimitry Andric       : ValueAndIsReference(C, isReference) {}
4302dbe13110SDimitry Andric   public:
4303dbe13110SDimitry Andric     ConstantEmission() {}
4304dbe13110SDimitry Andric     static ConstantEmission forReference(llvm::Constant *C) {
4305dbe13110SDimitry Andric       return ConstantEmission(C, true);
4306dbe13110SDimitry Andric     }
4307dbe13110SDimitry Andric     static ConstantEmission forValue(llvm::Constant *C) {
4308dbe13110SDimitry Andric       return ConstantEmission(C, false);
4309dbe13110SDimitry Andric     }
4310dbe13110SDimitry Andric 
43115e20cdd8SDimitry Andric     explicit operator bool() const {
43129f4dbff6SDimitry Andric       return ValueAndIsReference.getOpaqueValue() != nullptr;
43139f4dbff6SDimitry Andric     }
4314dbe13110SDimitry Andric 
4315dbe13110SDimitry Andric     bool isReference() const { return ValueAndIsReference.getInt(); }
4316dbe13110SDimitry Andric     LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const {
4317dbe13110SDimitry Andric       assert(isReference());
4318dbe13110SDimitry Andric       return CGF.MakeNaturalAlignAddrLValue(ValueAndIsReference.getPointer(),
4319dbe13110SDimitry Andric                                             refExpr->getType());
4320dbe13110SDimitry Andric     }
4321dbe13110SDimitry Andric 
4322dbe13110SDimitry Andric     llvm::Constant *getValue() const {
4323dbe13110SDimitry Andric       assert(!isReference());
4324dbe13110SDimitry Andric       return ValueAndIsReference.getPointer();
4325dbe13110SDimitry Andric     }
4326dbe13110SDimitry Andric   };
4327dbe13110SDimitry Andric 
4328dbe13110SDimitry Andric   ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr);
4329461a67faSDimitry Andric   ConstantEmission tryEmitAsConstant(const MemberExpr *ME);
4330676fbe81SDimitry Andric   llvm::Value *emitScalarConstant(const ConstantEmission &Constant, Expr *E);
4331dbe13110SDimitry Andric 
4332dbe13110SDimitry Andric   RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e,
4333dbe13110SDimitry Andric                                 AggValueSlot slot = AggValueSlot::ignored());
4334dbe13110SDimitry Andric   LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e);
4335dbe13110SDimitry Andric 
4336ec2b103cSEd Schouten   llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
4337ec2b103cSEd Schouten                               const ObjCIvarDecl *Ivar);
4338e3b55780SDimitry Andric   llvm::Value *EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface,
4339e3b55780SDimitry Andric                                            const ObjCIvarDecl *Ivar);
43406b9a6e39SDimitry Andric   LValue EmitLValueForField(LValue Base, const FieldDecl* Field);
43416a037251SDimitry Andric   LValue EmitLValueForLambdaField(const FieldDecl *Field);
4342b1c73532SDimitry Andric   LValue EmitLValueForLambdaField(const FieldDecl *Field,
4343b1c73532SDimitry Andric                                   llvm::Value *ThisValue);
4344ecb7e5c8SRoman Divacky 
4345ecb7e5c8SRoman Divacky   /// EmitLValueForFieldInitialization - Like EmitLValueForField, except that
4346ecb7e5c8SRoman Divacky   /// if the Field is a reference, this will return the address of the reference
4347ecb7e5c8SRoman Divacky   /// and not the address of the value stored in the reference.
43486b9a6e39SDimitry Andric   LValue EmitLValueForFieldInitialization(LValue Base,
43496b9a6e39SDimitry Andric                                           const FieldDecl* Field);
4350ecb7e5c8SRoman Divacky 
4351ec2b103cSEd Schouten   LValue EmitLValueForIvar(QualType ObjectTy,
4352ec2b103cSEd Schouten                            llvm::Value* Base, const ObjCIvarDecl *Ivar,
4353ec2b103cSEd Schouten                            unsigned CVRQualifiers);
4354ec2b103cSEd Schouten 
4355ec2b103cSEd Schouten   LValue EmitCXXConstructLValue(const CXXConstructExpr *E);
4356ec2b103cSEd Schouten   LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E);
4357b3d5a323SRoman Divacky   LValue EmitCXXTypeidLValue(const CXXTypeidExpr *E);
435813cc256eSDimitry Andric   LValue EmitCXXUuidofLValue(const CXXUuidofExpr *E);
4359ec2b103cSEd Schouten 
4360ec2b103cSEd Schouten   LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E);
4361ec2b103cSEd Schouten   LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E);
4362ec2b103cSEd Schouten   LValue EmitStmtExprLValue(const StmtExpr *E);
436373490b89SRoman Divacky   LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E);
43644ba67500SRoman Divacky   LValue EmitObjCSelectorLValue(const ObjCSelectorExpr *E);
4365bab175ecSDimitry Andric   void   EmitDeclRefExprDbgValue(const DeclRefExpr *E, const APValue &Init);
4366bca07a45SDimitry Andric 
4367ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
4368ec2b103cSEd Schouten   //                         Scalar Expression Emission
4369ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
4370ec2b103cSEd Schouten 
4371ec2b103cSEd Schouten   /// EmitCall - Generate a call of the given function, expecting the given
4372ec2b103cSEd Schouten   /// result type, and using the given argument list which specifies both the
4373ec2b103cSEd Schouten   /// LLVM arguments and the types they were derived from.
4374bab175ecSDimitry Andric   RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee,
437545b53394SDimitry Andric                   ReturnValueSlot ReturnValue, const CallArgList &Args,
4376344a3780SDimitry Andric                   llvm::CallBase **callOrInvoke, bool IsMustTail,
4377ac9a064cSDimitry Andric                   SourceLocation Loc,
4378ac9a064cSDimitry Andric                   bool IsVirtualFunctionPointerThunk = false);
43796252156dSDimitry Andric   RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee,
43806252156dSDimitry Andric                   ReturnValueSlot ReturnValue, const CallArgList &Args,
4381344a3780SDimitry Andric                   llvm::CallBase **callOrInvoke = nullptr,
4382344a3780SDimitry Andric                   bool IsMustTail = false) {
43836252156dSDimitry Andric     return EmitCall(CallInfo, Callee, ReturnValue, Args, callOrInvoke,
4384344a3780SDimitry Andric                     IsMustTail, SourceLocation());
43856252156dSDimitry Andric   }
4386bab175ecSDimitry Andric   RValue EmitCall(QualType FnType, const CGCallee &Callee, const CallExpr *E,
43876252156dSDimitry Andric                   ReturnValueSlot ReturnValue, llvm::Value *Chain = nullptr);
4388abe15e55SRoman Divacky   RValue EmitCallExpr(const CallExpr *E,
4389abe15e55SRoman Divacky                       ReturnValueSlot ReturnValue = ReturnValueSlot());
4390bab175ecSDimitry Andric   RValue EmitSimpleCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue);
4391bab175ecSDimitry Andric   CGCallee EmitCallee(const Expr *E);
4392ec2b103cSEd Schouten 
439345b53394SDimitry Andric   void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl);
439422989816SDimitry Andric   void checkTargetFeatures(SourceLocation Loc, const FunctionDecl *TargetDecl);
439545b53394SDimitry Andric 
439622989816SDimitry Andric   llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee,
4397809500fcSDimitry Andric                                   const Twine &name = "");
439822989816SDimitry Andric   llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee,
4399809500fcSDimitry Andric                                   ArrayRef<llvm::Value *> args,
4400809500fcSDimitry Andric                                   const Twine &name = "");
440122989816SDimitry Andric   llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
4402809500fcSDimitry Andric                                           const Twine &name = "");
440322989816SDimitry Andric   llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
4404ac9a064cSDimitry Andric                                           ArrayRef<Address> args,
4405ac9a064cSDimitry Andric                                           const Twine &name = "");
4406ac9a064cSDimitry Andric   llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
4407809500fcSDimitry Andric                                           ArrayRef<llvm::Value *> args,
4408809500fcSDimitry Andric                                           const Twine &name = "");
4409809500fcSDimitry Andric 
441048675466SDimitry Andric   SmallVector<llvm::OperandBundleDef, 1>
441148675466SDimitry Andric   getBundlesForFunclet(llvm::Value *Callee);
441248675466SDimitry Andric 
441322989816SDimitry Andric   llvm::CallBase *EmitCallOrInvoke(llvm::FunctionCallee Callee,
441436981b17SDimitry Andric                                    ArrayRef<llvm::Value *> Args,
441536981b17SDimitry Andric                                    const Twine &Name = "");
441622989816SDimitry Andric   llvm::CallBase *EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
4417809500fcSDimitry Andric                                           ArrayRef<llvm::Value *> args,
4418809500fcSDimitry Andric                                           const Twine &name = "");
441922989816SDimitry Andric   llvm::CallBase *EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
4420809500fcSDimitry Andric                                           const Twine &name = "");
442122989816SDimitry Andric   void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee,
4422809500fcSDimitry Andric                                        ArrayRef<llvm::Value *> args);
44234ba67500SRoman Divacky 
4424bab175ecSDimitry Andric   CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
4425bca07a45SDimitry Andric                                      NestedNameSpecifier *Qual,
442636981b17SDimitry Andric                                      llvm::Type *Ty);
4427bca07a45SDimitry Andric 
4428bab175ecSDimitry Andric   CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD,
4429bca07a45SDimitry Andric                                                CXXDtorType Type,
4430bca07a45SDimitry Andric                                                const CXXRecordDecl *RD);
4431b3d5a323SRoman Divacky 
4432ac9a064cSDimitry Andric   bool isPointerKnownNonNull(const Expr *E);
4433ac9a064cSDimitry Andric 
4434ac9a064cSDimitry Andric   /// Create the discriminator from the storage address and the entity hash.
4435ac9a064cSDimitry Andric   llvm::Value *EmitPointerAuthBlendDiscriminator(llvm::Value *StorageAddress,
4436ac9a064cSDimitry Andric                                                  llvm::Value *Discriminator);
4437ac9a064cSDimitry Andric   CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema,
4438ac9a064cSDimitry Andric                                         llvm::Value *StorageAddress,
4439ac9a064cSDimitry Andric                                         GlobalDecl SchemaDecl,
4440ac9a064cSDimitry Andric                                         QualType SchemaType);
4441ac9a064cSDimitry Andric 
4442ac9a064cSDimitry Andric   llvm::Value *EmitPointerAuthSign(const CGPointerAuthInfo &Info,
4443ac9a064cSDimitry Andric                                    llvm::Value *Pointer);
4444ac9a064cSDimitry Andric 
4445ac9a064cSDimitry Andric   llvm::Value *EmitPointerAuthAuth(const CGPointerAuthInfo &Info,
4446ac9a064cSDimitry Andric                                    llvm::Value *Pointer);
4447ac9a064cSDimitry Andric 
4448ac9a064cSDimitry Andric   llvm::Value *emitPointerAuthResign(llvm::Value *Pointer, QualType PointerType,
4449ac9a064cSDimitry Andric                                      const CGPointerAuthInfo &CurAuthInfo,
4450ac9a064cSDimitry Andric                                      const CGPointerAuthInfo &NewAuthInfo,
4451ac9a064cSDimitry Andric                                      bool IsKnownNonNull);
4452ac9a064cSDimitry Andric   llvm::Value *emitPointerAuthResignCall(llvm::Value *Pointer,
4453ac9a064cSDimitry Andric                                          const CGPointerAuthInfo &CurInfo,
4454ac9a064cSDimitry Andric                                          const CGPointerAuthInfo &NewInfo);
4455ac9a064cSDimitry Andric 
4456ac9a064cSDimitry Andric   void EmitPointerAuthOperandBundle(
4457ac9a064cSDimitry Andric       const CGPointerAuthInfo &Info,
4458ac9a064cSDimitry Andric       SmallVectorImpl<llvm::OperandBundleDef> &Bundles);
4459ac9a064cSDimitry Andric 
4460ac9a064cSDimitry Andric   llvm::Value *authPointerToPointerCast(llvm::Value *ResultPtr,
4461ac9a064cSDimitry Andric                                         QualType SourceType, QualType DestType);
4462ac9a064cSDimitry Andric   Address authPointerToPointerCast(Address Ptr, QualType SourceType,
4463ac9a064cSDimitry Andric                                    QualType DestType);
4464ac9a064cSDimitry Andric 
4465ac9a064cSDimitry Andric   Address getAsNaturalAddressOf(Address Addr, QualType PointeeTy);
4466ac9a064cSDimitry Andric 
4467ac9a064cSDimitry Andric   llvm::Value *getAsNaturalPointerTo(Address Addr, QualType PointeeType) {
4468ac9a064cSDimitry Andric     return getAsNaturalAddressOf(Addr, PointeeType).getBasePointer();
4469ac9a064cSDimitry Andric   }
4470ac9a064cSDimitry Andric 
4471676fbe81SDimitry Andric   // Return the copy constructor name with the prefix "__copy_constructor_"
4472676fbe81SDimitry Andric   // removed.
4473676fbe81SDimitry Andric   static std::string getNonTrivialCopyConstructorStr(QualType QT,
4474676fbe81SDimitry Andric                                                      CharUnits Alignment,
4475676fbe81SDimitry Andric                                                      bool IsVolatile,
4476676fbe81SDimitry Andric                                                      ASTContext &Ctx);
4477676fbe81SDimitry Andric 
4478676fbe81SDimitry Andric   // Return the destructor name with the prefix "__destructor_" removed.
4479676fbe81SDimitry Andric   static std::string getNonTrivialDestructorStr(QualType QT,
4480676fbe81SDimitry Andric                                                 CharUnits Alignment,
4481676fbe81SDimitry Andric                                                 bool IsVolatile,
4482676fbe81SDimitry Andric                                                 ASTContext &Ctx);
4483676fbe81SDimitry Andric 
448448675466SDimitry Andric   // These functions emit calls to the special functions of non-trivial C
448548675466SDimitry Andric   // structs.
448648675466SDimitry Andric   void defaultInitNonTrivialCStructVar(LValue Dst);
448748675466SDimitry Andric   void callCStructDefaultConstructor(LValue Dst);
448848675466SDimitry Andric   void callCStructDestructor(LValue Dst);
448948675466SDimitry Andric   void callCStructCopyConstructor(LValue Dst, LValue Src);
449048675466SDimitry Andric   void callCStructMoveConstructor(LValue Dst, LValue Src);
449148675466SDimitry Andric   void callCStructCopyAssignmentOperator(LValue Dst, LValue Src);
449248675466SDimitry Andric   void callCStructMoveAssignmentOperator(LValue Dst, LValue Src);
449348675466SDimitry Andric 
449406d4ba38SDimitry Andric   RValue
4495bab175ecSDimitry Andric   EmitCXXMemberOrOperatorCall(const CXXMethodDecl *Method,
4496bab175ecSDimitry Andric                               const CGCallee &Callee,
449706d4ba38SDimitry Andric                               ReturnValueSlot ReturnValue, llvm::Value *This,
4498809500fcSDimitry Andric                               llvm::Value *ImplicitParam,
4499bab175ecSDimitry Andric                               QualType ImplicitParamTy, const CallExpr *E,
4500bab175ecSDimitry Andric                               CallArgList *RtlArgs);
450122989816SDimitry Andric   RValue EmitCXXDestructorCall(GlobalDecl Dtor, const CGCallee &Callee,
450222989816SDimitry Andric                                llvm::Value *This, QualType ThisTy,
450322989816SDimitry Andric                                llvm::Value *ImplicitParam,
450422989816SDimitry Andric                                QualType ImplicitParamTy, const CallExpr *E);
4505abe15e55SRoman Divacky   RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E,
4506abe15e55SRoman Divacky                                ReturnValueSlot ReturnValue);
450706d4ba38SDimitry Andric   RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE,
450806d4ba38SDimitry Andric                                                const CXXMethodDecl *MD,
450906d4ba38SDimitry Andric                                                ReturnValueSlot ReturnValue,
451006d4ba38SDimitry Andric                                                bool HasQualifier,
451106d4ba38SDimitry Andric                                                NestedNameSpecifier *Qualifier,
451206d4ba38SDimitry Andric                                                bool IsArrow, const Expr *Base);
451306d4ba38SDimitry Andric   // Compute the object pointer.
451445b53394SDimitry Andric   Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base,
451545b53394SDimitry Andric                                           llvm::Value *memberPtr,
451645b53394SDimitry Andric                                           const MemberPointerType *memberPtrType,
4517461a67faSDimitry Andric                                           LValueBaseInfo *BaseInfo = nullptr,
4518461a67faSDimitry Andric                                           TBAAAccessInfo *TBAAInfo = nullptr);
4519abe15e55SRoman Divacky   RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
4520abe15e55SRoman Divacky                                       ReturnValueSlot ReturnValue);
4521ec2b103cSEd Schouten 
4522ec2b103cSEd Schouten   RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
4523abe15e55SRoman Divacky                                        const CXXMethodDecl *MD,
4524abe15e55SRoman Divacky                                        ReturnValueSlot ReturnValue);
4525bab175ecSDimitry Andric   RValue EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
4526ec2b103cSEd Schouten 
452736981b17SDimitry Andric   RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E,
452836981b17SDimitry Andric                                 ReturnValueSlot ReturnValue);
452936981b17SDimitry Andric 
4530c0981da4SDimitry Andric   RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E);
4531c0981da4SDimitry Andric   RValue EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E);
4532c0981da4SDimitry Andric   RValue EmitOpenMPDevicePrintfCallExpr(const CallExpr *E);
45334c8b2481SRoman Divacky 
4534676fbe81SDimitry Andric   RValue EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
4535676fbe81SDimitry Andric                          const CallExpr *E, ReturnValueSlot ReturnValue);
4536676fbe81SDimitry Andric 
4537676fbe81SDimitry Andric   RValue emitRotate(const CallExpr *E, bool IsRotateRight);
4538ec2b103cSEd Schouten 
4539461a67faSDimitry Andric   /// Emit IR for __builtin_os_log_format.
4540461a67faSDimitry Andric   RValue emitBuiltinOSLogFormat(const CallExpr &E);
4541461a67faSDimitry Andric 
4542706b4fc4SDimitry Andric   /// Emit IR for __builtin_is_aligned.
4543706b4fc4SDimitry Andric   RValue EmitBuiltinIsAligned(const CallExpr *E);
4544706b4fc4SDimitry Andric   /// Emit IR for __builtin_align_up/__builtin_align_down.
4545706b4fc4SDimitry Andric   RValue EmitBuiltinAlignTo(const CallExpr *E, bool AlignUp);
4546706b4fc4SDimitry Andric 
4547461a67faSDimitry Andric   llvm::Function *generateBuiltinOSLogHelperFunction(
4548461a67faSDimitry Andric       const analyze_os_log::OSLogBufferLayout &Layout,
4549461a67faSDimitry Andric       CharUnits BufferAlignment);
4550461a67faSDimitry Andric 
4551abe15e55SRoman Divacky   RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue);
4552ec2b103cSEd Schouten 
4553ec2b103cSEd Schouten   /// EmitTargetBuiltinExpr - Emit the given builtin call. Returns 0 if the call
4554ec2b103cSEd Schouten   /// is unhandled by the current target.
4555706b4fc4SDimitry Andric   llvm::Value *EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4556706b4fc4SDimitry Andric                                      ReturnValueSlot ReturnValue);
4557ec2b103cSEd Schouten 
4558bfef3995SDimitry Andric   llvm::Value *EmitAArch64CompareBuiltinExpr(llvm::Value *Op, llvm::Type *Ty,
4559bfef3995SDimitry Andric                                              const llvm::CmpInst::Predicate Fp,
4560bfef3995SDimitry Andric                                              const llvm::CmpInst::Predicate Ip,
4561bfef3995SDimitry Andric                                              const llvm::Twine &Name = "");
45626252156dSDimitry Andric   llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4563706b4fc4SDimitry Andric                                   ReturnValueSlot ReturnValue,
4564706b4fc4SDimitry Andric                                   llvm::Triple::ArchType Arch);
4565706b4fc4SDimitry Andric   llvm::Value *EmitARMMVEBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4566706b4fc4SDimitry Andric                                      ReturnValueSlot ReturnValue,
45676252156dSDimitry Andric                                      llvm::Triple::ArchType Arch);
4568cfca06d7SDimitry Andric   llvm::Value *EmitARMCDEBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4569cfca06d7SDimitry Andric                                      ReturnValueSlot ReturnValue,
4570cfca06d7SDimitry Andric                                      llvm::Triple::ArchType Arch);
4571cfca06d7SDimitry Andric   llvm::Value *EmitCMSEClearRecord(llvm::Value *V, llvm::IntegerType *ITy,
4572cfca06d7SDimitry Andric                                    QualType RTy);
4573cfca06d7SDimitry Andric   llvm::Value *EmitCMSEClearRecord(llvm::Value *V, llvm::ArrayType *ATy,
4574cfca06d7SDimitry Andric                                    QualType RTy);
45759f4dbff6SDimitry Andric 
45769f4dbff6SDimitry Andric   llvm::Value *EmitCommonNeonBuiltinExpr(unsigned BuiltinID,
45779f4dbff6SDimitry Andric                                          unsigned LLVMIntrinsic,
45789f4dbff6SDimitry Andric                                          unsigned AltLLVMIntrinsic,
45799f4dbff6SDimitry Andric                                          const char *NameHint,
45809f4dbff6SDimitry Andric                                          unsigned Modifier,
45819f4dbff6SDimitry Andric                                          const CallExpr *E,
45829f4dbff6SDimitry Andric                                          SmallVectorImpl<llvm::Value *> &Ops,
45836252156dSDimitry Andric                                          Address PtrOp0, Address PtrOp1,
45846252156dSDimitry Andric                                          llvm::Triple::ArchType Arch);
458548675466SDimitry Andric 
45869f4dbff6SDimitry Andric   llvm::Function *LookupNeonLLVMIntrinsic(unsigned IntrinsicID,
45879f4dbff6SDimitry Andric                                           unsigned Modifier, llvm::Type *ArgTy,
45889f4dbff6SDimitry Andric                                           const CallExpr *E);
45894ba67500SRoman Divacky   llvm::Value *EmitNeonCall(llvm::Function *F,
459036981b17SDimitry Andric                             SmallVectorImpl<llvm::Value*> &O,
4591bca07a45SDimitry Andric                             const char *name,
45924ba67500SRoman Divacky                             unsigned shift = 0, bool rightshift = false);
4593cfca06d7SDimitry Andric   llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx,
4594cfca06d7SDimitry Andric                              const llvm::ElementCount &Count);
4595bca07a45SDimitry Andric   llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx);
459636981b17SDimitry Andric   llvm::Value *EmitNeonShiftVector(llvm::Value *V, llvm::Type *Ty,
45974ba67500SRoman Divacky                                    bool negateForRightShift);
4598bfef3995SDimitry Andric   llvm::Value *EmitNeonRShiftImm(llvm::Value *Vec, llvm::Value *Amt,
4599bfef3995SDimitry Andric                                  llvm::Type *Ty, bool usgn, const char *name);
46009f4dbff6SDimitry Andric   llvm::Value *vectorWrapScalar16(llvm::Value *Op);
4601cfca06d7SDimitry Andric   /// SVEBuiltinMemEltTy - Returns the memory element type for this memory
4602cfca06d7SDimitry Andric   /// access builtin.  Only required if it can't be inferred from the base
4603cfca06d7SDimitry Andric   /// pointer operand.
4604c0981da4SDimitry Andric   llvm::Type *SVEBuiltinMemEltTy(const SVETypeFlags &TypeFlags);
4605cfca06d7SDimitry Andric 
4606c0981da4SDimitry Andric   SmallVector<llvm::Type *, 2>
4607c0981da4SDimitry Andric   getSVEOverloadTypes(const SVETypeFlags &TypeFlags, llvm::Type *ReturnType,
4608cfca06d7SDimitry Andric                       ArrayRef<llvm::Value *> Ops);
4609c0981da4SDimitry Andric   llvm::Type *getEltType(const SVETypeFlags &TypeFlags);
4610cfca06d7SDimitry Andric   llvm::ScalableVectorType *getSVEType(const SVETypeFlags &TypeFlags);
4611c0981da4SDimitry Andric   llvm::ScalableVectorType *getSVEPredType(const SVETypeFlags &TypeFlags);
4612e3b55780SDimitry Andric   llvm::Value *EmitSVETupleSetOrGet(const SVETypeFlags &TypeFlags,
4613e3b55780SDimitry Andric                                     llvm::Type *ReturnType,
4614e3b55780SDimitry Andric                                     ArrayRef<llvm::Value *> Ops);
4615e3b55780SDimitry Andric   llvm::Value *EmitSVETupleCreate(const SVETypeFlags &TypeFlags,
4616e3b55780SDimitry Andric                                   llvm::Type *ReturnType,
4617e3b55780SDimitry Andric                                   ArrayRef<llvm::Value *> Ops);
4618c0981da4SDimitry Andric   llvm::Value *EmitSVEAllTruePred(const SVETypeFlags &TypeFlags);
4619cfca06d7SDimitry Andric   llvm::Value *EmitSVEDupX(llvm::Value *Scalar);
4620cfca06d7SDimitry Andric   llvm::Value *EmitSVEDupX(llvm::Value *Scalar, llvm::Type *Ty);
4621cfca06d7SDimitry Andric   llvm::Value *EmitSVEReinterpret(llvm::Value *Val, llvm::Type *Ty);
4622c0981da4SDimitry Andric   llvm::Value *EmitSVEPMull(const SVETypeFlags &TypeFlags,
4623cfca06d7SDimitry Andric                             llvm::SmallVectorImpl<llvm::Value *> &Ops,
4624cfca06d7SDimitry Andric                             unsigned BuiltinID);
4625c0981da4SDimitry Andric   llvm::Value *EmitSVEMovl(const SVETypeFlags &TypeFlags,
4626cfca06d7SDimitry Andric                            llvm::ArrayRef<llvm::Value *> Ops,
4627cfca06d7SDimitry Andric                            unsigned BuiltinID);
4628cfca06d7SDimitry Andric   llvm::Value *EmitSVEPredicateCast(llvm::Value *Pred,
4629cfca06d7SDimitry Andric                                     llvm::ScalableVectorType *VTy);
4630c0981da4SDimitry Andric   llvm::Value *EmitSVEGatherLoad(const SVETypeFlags &TypeFlags,
4631cfca06d7SDimitry Andric                                  llvm::SmallVectorImpl<llvm::Value *> &Ops,
4632cfca06d7SDimitry Andric                                  unsigned IntID);
4633c0981da4SDimitry Andric   llvm::Value *EmitSVEScatterStore(const SVETypeFlags &TypeFlags,
4634cfca06d7SDimitry Andric                                    llvm::SmallVectorImpl<llvm::Value *> &Ops,
4635cfca06d7SDimitry Andric                                    unsigned IntID);
4636cfca06d7SDimitry Andric   llvm::Value *EmitSVEMaskedLoad(const CallExpr *, llvm::Type *ReturnTy,
4637cfca06d7SDimitry Andric                                  SmallVectorImpl<llvm::Value *> &Ops,
4638cfca06d7SDimitry Andric                                  unsigned BuiltinID, bool IsZExtReturn);
4639cfca06d7SDimitry Andric   llvm::Value *EmitSVEMaskedStore(const CallExpr *,
4640cfca06d7SDimitry Andric                                   SmallVectorImpl<llvm::Value *> &Ops,
4641cfca06d7SDimitry Andric                                   unsigned BuiltinID);
4642c0981da4SDimitry Andric   llvm::Value *EmitSVEPrefetchLoad(const SVETypeFlags &TypeFlags,
4643cfca06d7SDimitry Andric                                    SmallVectorImpl<llvm::Value *> &Ops,
4644cfca06d7SDimitry Andric                                    unsigned BuiltinID);
4645c0981da4SDimitry Andric   llvm::Value *EmitSVEGatherPrefetch(const SVETypeFlags &TypeFlags,
4646cfca06d7SDimitry Andric                                      SmallVectorImpl<llvm::Value *> &Ops,
4647cfca06d7SDimitry Andric                                      unsigned IntID);
4648c0981da4SDimitry Andric   llvm::Value *EmitSVEStructLoad(const SVETypeFlags &TypeFlags,
4649c0981da4SDimitry Andric                                  SmallVectorImpl<llvm::Value *> &Ops,
4650c0981da4SDimitry Andric                                  unsigned IntID);
4651c0981da4SDimitry Andric   llvm::Value *EmitSVEStructStore(const SVETypeFlags &TypeFlags,
4652cfca06d7SDimitry Andric                                   SmallVectorImpl<llvm::Value *> &Ops,
4653cfca06d7SDimitry Andric                                   unsigned IntID);
4654b1c73532SDimitry Andric   /// FormSVEBuiltinResult - Returns the struct of scalable vectors as a wider
4655b1c73532SDimitry Andric   /// vector. It extracts the scalable vector from the struct and inserts into
4656b1c73532SDimitry Andric   /// the wider vector. This avoids the error when allocating space in llvm
4657b1c73532SDimitry Andric   /// for struct of scalable vectors if a function returns struct.
4658b1c73532SDimitry Andric   llvm::Value *FormSVEBuiltinResult(llvm::Value *Call);
4659b1c73532SDimitry Andric 
4660cfca06d7SDimitry Andric   llvm::Value *EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4661cfca06d7SDimitry Andric 
4662b1c73532SDimitry Andric   llvm::Value *EmitSMELd1St1(const SVETypeFlags &TypeFlags,
46637fa27ce4SDimitry Andric                              llvm::SmallVectorImpl<llvm::Value *> &Ops,
46647fa27ce4SDimitry Andric                              unsigned IntID);
4665b1c73532SDimitry Andric   llvm::Value *EmitSMEReadWrite(const SVETypeFlags &TypeFlags,
46667fa27ce4SDimitry Andric                                 llvm::SmallVectorImpl<llvm::Value *> &Ops,
46677fa27ce4SDimitry Andric                                 unsigned IntID);
4668b1c73532SDimitry Andric   llvm::Value *EmitSMEZero(const SVETypeFlags &TypeFlags,
46697fa27ce4SDimitry Andric                            llvm::SmallVectorImpl<llvm::Value *> &Ops,
46707fa27ce4SDimitry Andric                            unsigned IntID);
4671b1c73532SDimitry Andric   llvm::Value *EmitSMELdrStr(const SVETypeFlags &TypeFlags,
46727fa27ce4SDimitry Andric                              llvm::SmallVectorImpl<llvm::Value *> &Ops,
46737fa27ce4SDimitry Andric                              unsigned IntID);
4674b1c73532SDimitry Andric 
4675b1c73532SDimitry Andric   void GetAArch64SVEProcessedOperands(unsigned BuiltinID, const CallExpr *E,
4676b1c73532SDimitry Andric                                       SmallVectorImpl<llvm::Value *> &Ops,
4677b1c73532SDimitry Andric                                       SVETypeFlags TypeFlags);
4678b1c73532SDimitry Andric 
46797fa27ce4SDimitry Andric   llvm::Value *EmitAArch64SMEBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
46807fa27ce4SDimitry Andric 
46816252156dSDimitry Andric   llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E,
46826252156dSDimitry Andric                                       llvm::Triple::ArchType Arch);
4683519fc96cSDimitry Andric   llvm::Value *EmitBPFBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
46844ba67500SRoman Divacky 
4685dbe13110SDimitry Andric   llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops);
4686ec2b103cSEd Schouten   llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4687ec2b103cSEd Schouten   llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
46882e645aa5SDimitry Andric   llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4689ac9a064cSDimitry Andric   llvm::Value *EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4690b1c73532SDimitry Andric   llvm::Value *EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx,
4691b1c73532SDimitry Andric                                            const CallExpr *E);
46925e20cdd8SDimitry Andric   llvm::Value *EmitSystemZBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4693c192b3dcSDimitry Andric   llvm::Value *EmitNVPTXBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
469445b53394SDimitry Andric   llvm::Value *EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
469545b53394SDimitry Andric                                           const CallExpr *E);
4696461a67faSDimitry Andric   llvm::Value *EmitHexagonBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4697344a3780SDimitry Andric   llvm::Value *EmitRISCVBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4698344a3780SDimitry Andric                                     ReturnValueSlot ReturnValue);
4699ac9a064cSDimitry Andric 
4700ac9a064cSDimitry Andric   void AddAMDGPUFenceAddressSpaceMMRA(llvm::Instruction *Inst,
4701ac9a064cSDimitry Andric                                       const CallExpr *E);
4702e3b55780SDimitry Andric   void ProcessOrderScopeAMDGCN(llvm::Value *Order, llvm::Value *Scope,
4703cfca06d7SDimitry Andric                                llvm::AtomicOrdering &AO,
4704cfca06d7SDimitry Andric                                llvm::SyncScope::ID &SSID);
4705ec2b103cSEd Schouten 
4706bab175ecSDimitry Andric   enum class MSVCIntrin;
4707bab175ecSDimitry Andric   llvm::Value *EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E);
4708bab175ecSDimitry Andric 
4709b60736ecSDimitry Andric   llvm::Value *EmitBuiltinAvailable(const VersionTuple &Version);
47107442d6faSDimitry Andric 
4711ec2b103cSEd Schouten   llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
4712ec2b103cSEd Schouten   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
471356d91b49SDimitry Andric   llvm::Value *EmitObjCBoxedExpr(const ObjCBoxedExpr *E);
4714dbe13110SDimitry Andric   llvm::Value *EmitObjCArrayLiteral(const ObjCArrayLiteral *E);
4715dbe13110SDimitry Andric   llvm::Value *EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E);
4716dbe13110SDimitry Andric   llvm::Value *EmitObjCCollectionLiteral(const Expr *E,
4717dbe13110SDimitry Andric                                 const ObjCMethodDecl *MethodWithObjects);
4718ec2b103cSEd Schouten   llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
4719d7279c4cSRoman Divacky   RValue EmitObjCMessageExpr(const ObjCMessageExpr *E,
4720d7279c4cSRoman Divacky                              ReturnValueSlot Return = ReturnValueSlot());
4721ec2b103cSEd Schouten 
4722180abc3dSDimitry Andric   /// Retrieves the default cleanup kind for an ARC cleanup.
4723180abc3dSDimitry Andric   /// Except under -fobjc-arc-eh, ARC cleanups are normal-only.
4724180abc3dSDimitry Andric   CleanupKind getARCCleanupKind() {
4725180abc3dSDimitry Andric     return CGM.getCodeGenOpts().ObjCAutoRefCountExceptions
4726180abc3dSDimitry Andric              ? NormalAndEHCleanup : NormalCleanup;
4727180abc3dSDimitry Andric   }
4728180abc3dSDimitry Andric 
4729180abc3dSDimitry Andric   // ARC primitives.
473045b53394SDimitry Andric   void EmitARCInitWeak(Address addr, llvm::Value *value);
473145b53394SDimitry Andric   void EmitARCDestroyWeak(Address addr);
473245b53394SDimitry Andric   llvm::Value *EmitARCLoadWeak(Address addr);
473345b53394SDimitry Andric   llvm::Value *EmitARCLoadWeakRetained(Address addr);
473445b53394SDimitry Andric   llvm::Value *EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored);
473548675466SDimitry Andric   void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr);
473648675466SDimitry Andric   void emitARCMoveAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr);
473745b53394SDimitry Andric   void EmitARCCopyWeak(Address dst, Address src);
473845b53394SDimitry Andric   void EmitARCMoveWeak(Address dst, Address src);
4739180abc3dSDimitry Andric   llvm::Value *EmitARCRetainAutorelease(QualType type, llvm::Value *value);
4740180abc3dSDimitry Andric   llvm::Value *EmitARCRetainAutoreleaseNonBlock(llvm::Value *value);
4741180abc3dSDimitry Andric   llvm::Value *EmitARCStoreStrong(LValue lvalue, llvm::Value *value,
4742809500fcSDimitry Andric                                   bool resultIgnored);
474345b53394SDimitry Andric   llvm::Value *EmitARCStoreStrongCall(Address addr, llvm::Value *value,
4744809500fcSDimitry Andric                                       bool resultIgnored);
4745180abc3dSDimitry Andric   llvm::Value *EmitARCRetain(QualType type, llvm::Value *value);
4746180abc3dSDimitry Andric   llvm::Value *EmitARCRetainNonBlock(llvm::Value *value);
474736981b17SDimitry Andric   llvm::Value *EmitARCRetainBlock(llvm::Value *value, bool mandatory);
474845b53394SDimitry Andric   void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise);
4749809500fcSDimitry Andric   void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise);
4750180abc3dSDimitry Andric   llvm::Value *EmitARCAutorelease(llvm::Value *value);
4751180abc3dSDimitry Andric   llvm::Value *EmitARCAutoreleaseReturnValue(llvm::Value *value);
4752180abc3dSDimitry Andric   llvm::Value *EmitARCRetainAutoreleaseReturnValue(llvm::Value *value);
4753180abc3dSDimitry Andric   llvm::Value *EmitARCRetainAutoreleasedReturnValue(llvm::Value *value);
47542b6b257fSDimitry Andric   llvm::Value *EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value);
4755180abc3dSDimitry Andric 
4756676fbe81SDimitry Andric   llvm::Value *EmitObjCAutorelease(llvm::Value *value, llvm::Type *returnType);
4757676fbe81SDimitry Andric   llvm::Value *EmitObjCRetainNonBlock(llvm::Value *value,
4758676fbe81SDimitry Andric                                       llvm::Type *returnType);
4759676fbe81SDimitry Andric   void EmitObjCRelease(llvm::Value *value, ARCPreciseLifetime_t precise);
4760676fbe81SDimitry Andric 
4761180abc3dSDimitry Andric   std::pair<LValue,llvm::Value*>
4762180abc3dSDimitry Andric   EmitARCStoreAutoreleasing(const BinaryOperator *e);
4763180abc3dSDimitry Andric   std::pair<LValue,llvm::Value*>
4764180abc3dSDimitry Andric   EmitARCStoreStrong(const BinaryOperator *e, bool ignored);
47652b6b257fSDimitry Andric   std::pair<LValue,llvm::Value*>
47662b6b257fSDimitry Andric   EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored);
4767180abc3dSDimitry Andric 
4768676fbe81SDimitry Andric   llvm::Value *EmitObjCAlloc(llvm::Value *value,
4769676fbe81SDimitry Andric                              llvm::Type *returnType);
4770676fbe81SDimitry Andric   llvm::Value *EmitObjCAllocWithZone(llvm::Value *value,
4771676fbe81SDimitry Andric                                      llvm::Type *returnType);
477222989816SDimitry Andric   llvm::Value *EmitObjCAllocInit(llvm::Value *value, llvm::Type *resultType);
477322989816SDimitry Andric 
477436981b17SDimitry Andric   llvm::Value *EmitObjCThrowOperand(const Expr *expr);
4775180abc3dSDimitry Andric   llvm::Value *EmitObjCConsumeObject(QualType T, llvm::Value *Ptr);
4776180abc3dSDimitry Andric   llvm::Value *EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr);
4777180abc3dSDimitry Andric 
477836981b17SDimitry Andric   llvm::Value *EmitARCExtendBlockObject(const Expr *expr);
47792b6b257fSDimitry Andric   llvm::Value *EmitARCReclaimReturnedObject(const Expr *e,
47802b6b257fSDimitry Andric                                             bool allowUnsafeClaim);
4781180abc3dSDimitry Andric   llvm::Value *EmitARCRetainScalarExpr(const Expr *expr);
4782180abc3dSDimitry Andric   llvm::Value *EmitARCRetainAutoreleaseScalarExpr(const Expr *expr);
47832b6b257fSDimitry Andric   llvm::Value *EmitARCUnsafeUnretainedScalarExpr(const Expr *expr);
4784180abc3dSDimitry Andric 
47859f4dbff6SDimitry Andric   void EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values);
4786809500fcSDimitry Andric 
4787344a3780SDimitry Andric   void EmitARCNoopIntrinsicUse(ArrayRef<llvm::Value *> values);
4788344a3780SDimitry Andric 
4789180abc3dSDimitry Andric   static Destroyer destroyARCStrongImprecise;
4790180abc3dSDimitry Andric   static Destroyer destroyARCStrongPrecise;
4791180abc3dSDimitry Andric   static Destroyer destroyARCWeak;
479257091882SDimitry Andric   static Destroyer emitARCIntrinsicUse;
479348675466SDimitry Andric   static Destroyer destroyNonTrivialCStruct;
4794180abc3dSDimitry Andric 
4795180abc3dSDimitry Andric   void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr);
4796180abc3dSDimitry Andric   llvm::Value *EmitObjCAutoreleasePoolPush();
4797180abc3dSDimitry Andric   llvm::Value *EmitObjCMRRAutoreleasePoolPush();
4798180abc3dSDimitry Andric   void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr);
4799180abc3dSDimitry Andric   void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr);
4800180abc3dSDimitry Andric 
480148675466SDimitry Andric   /// Emits a reference binding to the passed in expression.
4802bfef3995SDimitry Andric   RValue EmitReferenceBindingToExpr(const Expr *E);
4803ec2b103cSEd Schouten 
4804ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
4805ec2b103cSEd Schouten   //                           Expression Emission
4806ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
4807ec2b103cSEd Schouten 
4808ec2b103cSEd Schouten   // Expressions are broken into three classes: scalar, complex, aggregate.
4809ec2b103cSEd Schouten 
4810ec2b103cSEd Schouten   /// EmitScalarExpr - Emit the computation of the specified expression of LLVM
4811ec2b103cSEd Schouten   /// scalar type, returning the result.
4812ec2b103cSEd Schouten   llvm::Value *EmitScalarExpr(const Expr *E , bool IgnoreResultAssign = false);
4813ec2b103cSEd Schouten 
481445b53394SDimitry Andric   /// Emit a conversion from the specified type to the specified destination
481545b53394SDimitry Andric   /// type, both of which are LLVM scalar types.
4816ec2b103cSEd Schouten   llvm::Value *EmitScalarConversion(llvm::Value *Src, QualType SrcTy,
481745b53394SDimitry Andric                                     QualType DstTy, SourceLocation Loc);
4818ec2b103cSEd Schouten 
481945b53394SDimitry Andric   /// Emit a conversion from the specified complex type to the specified
482045b53394SDimitry Andric   /// destination type, where the destination type is an LLVM scalar type.
4821ec2b103cSEd Schouten   llvm::Value *EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy,
482245b53394SDimitry Andric                                              QualType DstTy,
482345b53394SDimitry Andric                                              SourceLocation Loc);
4824ec2b103cSEd Schouten 
4825bca07a45SDimitry Andric   /// EmitAggExpr - Emit the computation of the specified expression
4826bca07a45SDimitry Andric   /// of aggregate type.  The result is computed into the given slot,
4827bca07a45SDimitry Andric   /// which may be null to indicate that the value is not needed.
482856d91b49SDimitry Andric   void EmitAggExpr(const Expr *E, AggValueSlot AS);
48294c8b2481SRoman Divacky 
4830ecb7e5c8SRoman Divacky   /// EmitAggExprToLValue - Emit the computation of the specified expression of
4831ecb7e5c8SRoman Divacky   /// aggregate type into a temporary LValue.
4832ecb7e5c8SRoman Divacky   LValue EmitAggExprToLValue(const Expr *E);
4833ecb7e5c8SRoman Divacky 
4834ac9a064cSDimitry Andric   enum ExprValueKind { EVK_RValue, EVK_NonRValue };
4835ac9a064cSDimitry Andric 
4836ac9a064cSDimitry Andric   /// EmitAggFinalDestCopy - Emit copy of the specified aggregate into
4837ac9a064cSDimitry Andric   /// destination address.
4838ac9a064cSDimitry Andric   void EmitAggFinalDestCopy(QualType Type, AggValueSlot Dest, const LValue &Src,
4839ac9a064cSDimitry Andric                             ExprValueKind SrcKind);
4840ac9a064cSDimitry Andric 
48411de139fdSDimitry Andric   /// Create a store to \arg DstPtr from \arg Src, truncating the stored value
48421de139fdSDimitry Andric   /// to at most \arg DstSize bytes.
48431de139fdSDimitry Andric   void CreateCoercedStore(llvm::Value *Src, Address Dst, llvm::TypeSize DstSize,
48441de139fdSDimitry Andric                           bool DstIsVolatile);
4845cfca06d7SDimitry Andric 
4846180abc3dSDimitry Andric   /// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
4847180abc3dSDimitry Andric   /// make sure it survives garbage collection until this point.
4848180abc3dSDimitry Andric   void EmitExtendGCLifetime(llvm::Value *object);
4849180abc3dSDimitry Andric 
4850ec2b103cSEd Schouten   /// EmitComplexExpr - Emit the computation of the specified expression of
4851ec2b103cSEd Schouten   /// complex type, returning the result.
4852bca07a45SDimitry Andric   ComplexPairTy EmitComplexExpr(const Expr *E,
4853bca07a45SDimitry Andric                                 bool IgnoreReal = false,
4854bca07a45SDimitry Andric                                 bool IgnoreImag = false);
4855ec2b103cSEd Schouten 
4856809500fcSDimitry Andric   /// EmitComplexExprIntoLValue - Emit the given expression of complex
4857809500fcSDimitry Andric   /// type and place its result into the specified l-value.
4858809500fcSDimitry Andric   void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit);
4859ec2b103cSEd Schouten 
4860809500fcSDimitry Andric   /// EmitStoreOfComplex - Store a complex number into the specified l-value.
4861809500fcSDimitry Andric   void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit);
4862809500fcSDimitry Andric 
4863809500fcSDimitry Andric   /// EmitLoadOfComplex - Load a complex number from the specified l-value.
4864bfef3995SDimitry Andric   ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc);
4865ec2b103cSEd Schouten 
4866e3b55780SDimitry Andric   ComplexPairTy EmitPromotedComplexExpr(const Expr *E, QualType PromotionType);
4867e3b55780SDimitry Andric   llvm::Value *EmitPromotedScalarExpr(const Expr *E, QualType PromotionType);
4868e3b55780SDimitry Andric   ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType);
4869e3b55780SDimitry Andric   ComplexPairTy EmitUnPromotedValue(ComplexPairTy result, QualType PromotionType);
4870e3b55780SDimitry Andric 
487145b53394SDimitry Andric   Address emitAddrOfRealComponent(Address complex, QualType complexType);
487245b53394SDimitry Andric   Address emitAddrOfImagComponent(Address complex, QualType complexType);
487345b53394SDimitry Andric 
4874bca07a45SDimitry Andric   /// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the
487534d02d0bSRoman Divacky   /// global variable that has already been created for it.  If the initializer
487634d02d0bSRoman Divacky   /// has a different type than GV does, this may free GV and return a different
487734d02d0bSRoman Divacky   /// one.  Otherwise it just returns GV.
487834d02d0bSRoman Divacky   llvm::GlobalVariable *
4879bca07a45SDimitry Andric   AddInitializerToStaticVarDecl(const VarDecl &D,
488034d02d0bSRoman Divacky                                 llvm::GlobalVariable *GV);
488134d02d0bSRoman Divacky 
4882676fbe81SDimitry Andric   // Emit an @llvm.invariant.start call for the given memory region.
4883676fbe81SDimitry Andric   void EmitInvariantStart(llvm::Constant *Addr, CharUnits Size);
488434d02d0bSRoman Divacky 
48854c8b2481SRoman Divacky   /// EmitCXXGlobalVarDeclInit - Create the initializer for a C++
48864c8b2481SRoman Divacky   /// variable with global storage.
488777fc4c14SDimitry Andric   void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV,
4888dbe13110SDimitry Andric                                 bool PerformInit);
48894c8b2481SRoman Divacky 
4890ac9a064cSDimitry Andric   llvm::Constant *createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor,
489106d4ba38SDimitry Andric                                    llvm::Constant *Addr);
489206d4ba38SDimitry Andric 
4893344a3780SDimitry Andric   llvm::Function *createTLSAtExitStub(const VarDecl &VD,
4894344a3780SDimitry Andric                                       llvm::FunctionCallee Dtor,
4895344a3780SDimitry Andric                                       llvm::Constant *Addr,
4896344a3780SDimitry Andric                                       llvm::FunctionCallee &AtExit);
4897344a3780SDimitry Andric 
489856d91b49SDimitry Andric   /// Call atexit() with a function that passes the given argument to
489956d91b49SDimitry Andric   /// the given function.
490022989816SDimitry Andric   void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn,
4901bfef3995SDimitry Andric                                     llvm::Constant *addr);
49024c8b2481SRoman Divacky 
4903b1c73532SDimitry Andric   /// Registers the dtor using 'llvm.global_dtors' for platforms that do not
4904b1c73532SDimitry Andric   /// support an 'atexit()' function.
4905b1c73532SDimitry Andric   void registerGlobalDtorWithLLVM(const VarDecl &D, llvm::FunctionCallee fn,
4906b1c73532SDimitry Andric                                   llvm::Constant *addr);
4907b1c73532SDimitry Andric 
490848675466SDimitry Andric   /// Call atexit() with function dtorStub.
490948675466SDimitry Andric   void registerGlobalDtorWithAtExit(llvm::Constant *dtorStub);
491048675466SDimitry Andric 
4911cfca06d7SDimitry Andric   /// Call unatexit() with function dtorStub.
4912b60736ecSDimitry Andric   llvm::Value *unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub);
4913cfca06d7SDimitry Andric 
4914bca07a45SDimitry Andric   /// Emit code in this function to perform a guarded variable
4915bca07a45SDimitry Andric   /// initialization.  Guarded initializations are used when it's not
4916bca07a45SDimitry Andric   /// possible to prove that an initialization will be done exactly
4917bca07a45SDimitry Andric   /// once, e.g. with a static local variable or a static data member
4918bca07a45SDimitry Andric   /// of a class template.
4919dbe13110SDimitry Andric   void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr,
4920dbe13110SDimitry Andric                           bool PerformInit);
4921bca07a45SDimitry Andric 
4922461a67faSDimitry Andric   enum class GuardKind { VariableGuard, TlsGuard };
4923461a67faSDimitry Andric 
4924461a67faSDimitry Andric   /// Emit a branch to select whether or not to perform guarded initialization.
4925461a67faSDimitry Andric   void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit,
4926461a67faSDimitry Andric                                 llvm::BasicBlock *InitBlock,
4927461a67faSDimitry Andric                                 llvm::BasicBlock *NoInitBlock,
4928461a67faSDimitry Andric                                 GuardKind Kind, const VarDecl *D);
4929461a67faSDimitry Andric 
49304c8b2481SRoman Divacky   /// GenerateCXXGlobalInitFunc - Generates code for initializing global
49314c8b2481SRoman Divacky   /// variables.
4932676fbe81SDimitry Andric   void
4933676fbe81SDimitry Andric   GenerateCXXGlobalInitFunc(llvm::Function *Fn,
493406d4ba38SDimitry Andric                             ArrayRef<llvm::Function *> CXXThreadLocals,
4935676fbe81SDimitry Andric                             ConstantAddress Guard = ConstantAddress::invalid());
49364c8b2481SRoman Divacky 
4937cfca06d7SDimitry Andric   /// GenerateCXXGlobalCleanUpFunc - Generates code for cleaning up global
4938c0c7bca4SRoman Divacky   /// variables.
4939cfca06d7SDimitry Andric   void GenerateCXXGlobalCleanUpFunc(
494057091882SDimitry Andric       llvm::Function *Fn,
4941344a3780SDimitry Andric       ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
4942344a3780SDimitry Andric                           llvm::Constant *>>
4943344a3780SDimitry Andric           DtorsOrStermFinalizers);
4944c0c7bca4SRoman Divacky 
494501af97d3SDimitry Andric   void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
494601af97d3SDimitry Andric                                         const VarDecl *D,
4947dbe13110SDimitry Andric                                         llvm::GlobalVariable *Addr,
4948dbe13110SDimitry Andric                                         bool PerformInit);
4949ee791ddeSRoman Divacky 
4950bca07a45SDimitry Andric   void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest);
4951ec2b103cSEd Schouten 
495245b53394SDimitry Andric   void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp);
4953bca07a45SDimitry Andric 
49546a037251SDimitry Andric   void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint = true);
495551fb8b01SRoman Divacky 
495645b53394SDimitry Andric   RValue EmitAtomicExpr(AtomicExpr *E);
495736981b17SDimitry Andric 
495836981b17SDimitry Andric   //===--------------------------------------------------------------------===//
495936981b17SDimitry Andric   //                         Annotations Emission
496036981b17SDimitry Andric   //===--------------------------------------------------------------------===//
496136981b17SDimitry Andric 
496222989816SDimitry Andric   /// Emit an annotation call (intrinsic).
496322989816SDimitry Andric   llvm::Value *EmitAnnotationCall(llvm::Function *AnnotationFn,
496436981b17SDimitry Andric                                   llvm::Value *AnnotatedVal,
4965809500fcSDimitry Andric                                   StringRef AnnotationStr,
4966b60736ecSDimitry Andric                                   SourceLocation Location,
4967b60736ecSDimitry Andric                                   const AnnotateAttr *Attr);
496836981b17SDimitry Andric 
496936981b17SDimitry Andric   /// Emit local annotations for the local variable V, declared by D.
497036981b17SDimitry Andric   void EmitVarAnnotations(const VarDecl *D, llvm::Value *V);
497136981b17SDimitry Andric 
497236981b17SDimitry Andric   /// Emit field annotations for the given field & value. Returns the
497336981b17SDimitry Andric   /// annotation result.
497445b53394SDimitry Andric   Address EmitFieldAnnotations(const FieldDecl *D, Address V);
497536981b17SDimitry Andric 
4976ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
4977ec2b103cSEd Schouten   //                             Internal Helpers
4978ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
4979ec2b103cSEd Schouten 
4980ec2b103cSEd Schouten   /// ContainsLabel - Return true if the statement contains a label in it.  If
4981ec2b103cSEd Schouten   /// this statement is not executed normally, it not containing a label means
4982ec2b103cSEd Schouten   /// that we can just remove the code.
4983ec2b103cSEd Schouten   static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false);
4984ec2b103cSEd Schouten 
498501af97d3SDimitry Andric   /// containsBreak - Return true if the statement contains a break out of it.
498601af97d3SDimitry Andric   /// If the statement (recursively) contains a switch or loop with a break
498701af97d3SDimitry Andric   /// inside of it, this is fine.
498801af97d3SDimitry Andric   static bool containsBreak(const Stmt *S);
498901af97d3SDimitry Andric 
499017c7957fSDimitry Andric   /// Determine if the given statement might introduce a declaration into the
499117c7957fSDimitry Andric   /// current scope, by being a (possibly-labelled) DeclStmt.
499217c7957fSDimitry Andric   static bool mightAddDeclToScope(const Stmt *S);
499317c7957fSDimitry Andric 
4994ec2b103cSEd Schouten   /// ConstantFoldsToSimpleInteger - If the specified expression does not fold
499501af97d3SDimitry Andric   /// to a constant, or if it does but contains a label, return false.  If it
499601af97d3SDimitry Andric   /// constant folds return true and set the boolean result in Result.
49972b6b257fSDimitry Andric   bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result,
49982b6b257fSDimitry Andric                                     bool AllowLabels = false);
499901af97d3SDimitry Andric 
500001af97d3SDimitry Andric   /// ConstantFoldsToSimpleInteger - If the specified expression does not fold
500101af97d3SDimitry Andric   /// to a constant, or if it does but contains a label, return false.  If it
500201af97d3SDimitry Andric   /// constant folds return true and set the folded value.
50032b6b257fSDimitry Andric   bool ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APSInt &Result,
50042b6b257fSDimitry Andric                                     bool AllowLabels = false);
5005ec2b103cSEd Schouten 
5006aca2e42cSDimitry Andric   /// Ignore parentheses and logical-NOT to track conditions consistently.
5007aca2e42cSDimitry Andric   static const Expr *stripCond(const Expr *C);
5008aca2e42cSDimitry Andric 
5009b60736ecSDimitry Andric   /// isInstrumentedCondition - Determine whether the given condition is an
5010b60736ecSDimitry Andric   /// instrumentable condition (i.e. no "&&" or "||").
5011b60736ecSDimitry Andric   static bool isInstrumentedCondition(const Expr *C);
5012b60736ecSDimitry Andric 
5013b60736ecSDimitry Andric   /// EmitBranchToCounterBlock - Emit a conditional branch to a new block that
5014b60736ecSDimitry Andric   /// increments a profile counter based on the semantics of the given logical
5015b60736ecSDimitry Andric   /// operator opcode.  This is used to instrument branch condition coverage
5016b60736ecSDimitry Andric   /// for logical operators.
5017b60736ecSDimitry Andric   void EmitBranchToCounterBlock(const Expr *Cond, BinaryOperator::Opcode LOp,
5018b60736ecSDimitry Andric                                 llvm::BasicBlock *TrueBlock,
5019b60736ecSDimitry Andric                                 llvm::BasicBlock *FalseBlock,
5020b60736ecSDimitry Andric                                 uint64_t TrueCount = 0,
5021b60736ecSDimitry Andric                                 Stmt::Likelihood LH = Stmt::LH_None,
5022b60736ecSDimitry Andric                                 const Expr *CntrIdx = nullptr);
5023b60736ecSDimitry Andric 
5024ec2b103cSEd Schouten   /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an
5025ec2b103cSEd Schouten   /// if statement) to the specified blocks.  Based on the condition, this might
5026ec2b103cSEd Schouten   /// try to simplify the codegen of the conditional based on the branch.
50279f4dbff6SDimitry Andric   /// TrueCount should be the number of times we expect the condition to
50289f4dbff6SDimitry Andric   /// evaluate to true based on PGO data.
5029ec2b103cSEd Schouten   void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock,
5030b60736ecSDimitry Andric                             llvm::BasicBlock *FalseBlock, uint64_t TrueCount,
5031aca2e42cSDimitry Andric                             Stmt::Likelihood LH = Stmt::LH_None,
5032aca2e42cSDimitry Andric                             const Expr *ConditionalOp = nullptr);
503334d02d0bSRoman Divacky 
50347442d6faSDimitry Andric   /// Given an assignment `*LHS = RHS`, emit a test that checks if \p RHS is
50357442d6faSDimitry Andric   /// nonnull, if \p LHS is marked _Nonnull.
50367442d6faSDimitry Andric   void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc);
50377442d6faSDimitry Andric 
5038de51d671SDimitry Andric   /// An enumeration which makes it easier to specify whether or not an
5039de51d671SDimitry Andric   /// operation is a subtraction.
5040de51d671SDimitry Andric   enum { NotSubtraction = false, IsSubtraction = true };
5041de51d671SDimitry Andric 
5042416ada0fSDimitry Andric   /// Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to
5043416ada0fSDimitry Andric   /// detect undefined behavior when the pointer overflow sanitizer is enabled.
5044325377b5SDimitry Andric   /// \p SignedIndices indicates whether any of the GEP indices are signed.
5045de51d671SDimitry Andric   /// \p IsSubtraction indicates whether the expression used to form the GEP
5046de51d671SDimitry Andric   /// is a subtraction.
504777fc4c14SDimitry Andric   llvm::Value *EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr,
5048416ada0fSDimitry Andric                                       ArrayRef<llvm::Value *> IdxList,
5049325377b5SDimitry Andric                                       bool SignedIndices,
5050de51d671SDimitry Andric                                       bool IsSubtraction,
5051416ada0fSDimitry Andric                                       SourceLocation Loc,
5052416ada0fSDimitry Andric                                       const Twine &Name = "");
5053416ada0fSDimitry Andric 
5054ac9a064cSDimitry Andric   Address EmitCheckedInBoundsGEP(Address Addr, ArrayRef<llvm::Value *> IdxList,
5055ac9a064cSDimitry Andric                                  llvm::Type *elementType, bool SignedIndices,
5056ac9a064cSDimitry Andric                                  bool IsSubtraction, SourceLocation Loc,
5057ac9a064cSDimitry Andric                                  CharUnits Align, const Twine &Name = "");
5058ac9a064cSDimitry Andric 
5059461a67faSDimitry Andric   /// Specifies which type of sanitizer check to apply when handling a
5060461a67faSDimitry Andric   /// particular builtin.
5061461a67faSDimitry Andric   enum BuiltinCheckKind {
5062461a67faSDimitry Andric     BCK_CTZPassedZero,
5063461a67faSDimitry Andric     BCK_CLZPassedZero,
5064461a67faSDimitry Andric   };
5065461a67faSDimitry Andric 
5066461a67faSDimitry Andric   /// Emits an argument for a call to a builtin. If the builtin sanitizer is
5067461a67faSDimitry Andric   /// enabled, a runtime check specified by \p Kind is also emitted.
5068461a67faSDimitry Andric   llvm::Value *EmitCheckedArgForBuiltin(const Expr *E, BuiltinCheckKind Kind);
5069461a67faSDimitry Andric 
507048675466SDimitry Andric   /// Emit a description of a type in a format suitable for passing to
507113cc256eSDimitry Andric   /// a runtime sanitizer handler.
507213cc256eSDimitry Andric   llvm::Constant *EmitCheckTypeDescriptor(QualType T);
507313cc256eSDimitry Andric 
507448675466SDimitry Andric   /// Convert a value into a format suitable for passing to a runtime
507513cc256eSDimitry Andric   /// sanitizer handler.
507613cc256eSDimitry Andric   llvm::Value *EmitCheckValue(llvm::Value *V);
507713cc256eSDimitry Andric 
507848675466SDimitry Andric   /// Emit a description of a source location in a format suitable for
507913cc256eSDimitry Andric   /// passing to a runtime sanitizer handler.
508013cc256eSDimitry Andric   llvm::Constant *EmitCheckSourceLocation(SourceLocation Loc);
508113cc256eSDimitry Andric 
5082e3b55780SDimitry Andric   void EmitKCFIOperandBundle(const CGCallee &Callee,
5083e3b55780SDimitry Andric                              SmallVectorImpl<llvm::OperandBundleDef> &Bundles);
5084e3b55780SDimitry Andric 
508522989816SDimitry Andric   /// Create a basic block that will either trap or call a handler function in
508622989816SDimitry Andric   /// the UBSan runtime with the provided arguments, and create a conditional
508713cc256eSDimitry Andric   /// branch to it.
50885e20cdd8SDimitry Andric   void EmitCheck(ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked,
5089bab175ecSDimitry Andric                  SanitizerHandler Check, ArrayRef<llvm::Constant *> StaticArgs,
509006d4ba38SDimitry Andric                  ArrayRef<llvm::Value *> DynamicArgs);
509113cc256eSDimitry Andric 
509248675466SDimitry Andric   /// Emit a slow path cross-DSO CFI check which calls __cfi_slowpath
509345b53394SDimitry Andric   /// if Cond if false.
50942b6b257fSDimitry Andric   void EmitCfiSlowPathCheck(SanitizerMask Kind, llvm::Value *Cond,
50952b6b257fSDimitry Andric                             llvm::ConstantInt *TypeId, llvm::Value *Ptr,
50962b6b257fSDimitry Andric                             ArrayRef<llvm::Constant *> StaticArgs);
509745b53394SDimitry Andric 
50986252156dSDimitry Andric   /// Emit a reached-unreachable diagnostic if \p Loc is valid and runtime
50996252156dSDimitry Andric   /// checking is enabled. Otherwise, just emit an unreachable instruction.
51006252156dSDimitry Andric   void EmitUnreachable(SourceLocation Loc);
51016252156dSDimitry Andric 
510248675466SDimitry Andric   /// Create a basic block that will call the trap intrinsic, and emit a
510313cc256eSDimitry Andric   /// conditional branch to it, for the -ftrapv checks.
5104b60736ecSDimitry Andric   void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID);
510511d2b2d2SRoman Divacky 
510648675466SDimitry Andric   /// Emit a call to trap or debugtrap and attach function attribute
5107c192b3dcSDimitry Andric   /// "trap-func-name" if specified.
5108c192b3dcSDimitry Andric   llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID);
5109c192b3dcSDimitry Andric 
511048675466SDimitry Andric   /// Emit a stub for the cross-DSO CFI check function.
51117442d6faSDimitry Andric   void EmitCfiCheckStub();
51127442d6faSDimitry Andric 
511348675466SDimitry Andric   /// Emit a cross-DSO CFI failure handling function.
51142b6b257fSDimitry Andric   void EmitCfiCheckFail();
51152b6b257fSDimitry Andric 
511648675466SDimitry Andric   /// Create a check for a function parameter that may potentially be
5117798321d8SDimitry Andric   /// declared as non-null.
5118798321d8SDimitry Andric   void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc,
51197442d6faSDimitry Andric                            AbstractCallee AC, unsigned ParmNum);
5120798321d8SDimitry Andric 
5121ac9a064cSDimitry Andric   void EmitNonNullArgCheck(Address Addr, QualType ArgType,
5122ac9a064cSDimitry Andric                            SourceLocation ArgLoc, AbstractCallee AC,
5123ac9a064cSDimitry Andric                            unsigned ParmNum);
5124ac9a064cSDimitry Andric 
512511d2b2d2SRoman Divacky   /// EmitCallArg - Emit a single call argument.
512601af97d3SDimitry Andric   void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);
512711d2b2d2SRoman Divacky 
5128d7279c4cSRoman Divacky   /// EmitDelegateCallArg - We are performing a delegate call; that
5129d7279c4cSRoman Divacky   /// is, the current function is delegating to another one.  Produce
5130d7279c4cSRoman Divacky   /// a r-value suitable for passing the given parameter.
5131bfef3995SDimitry Andric   void EmitDelegateCallArg(CallArgList &args, const VarDecl *param,
5132bfef3995SDimitry Andric                            SourceLocation loc);
5133d7279c4cSRoman Divacky 
5134dbe13110SDimitry Andric   /// SetFPAccuracy - Set the minimum required accuracy of the given floating
5135dbe13110SDimitry Andric   /// point operation, expressed as the maximum relative error in ulp.
5136dbe13110SDimitry Andric   void SetFPAccuracy(llvm::Value *Val, float Accuracy);
5137dbe13110SDimitry Andric 
51387fa27ce4SDimitry Andric   /// Set the minimum required accuracy of the given sqrt operation
51397fa27ce4SDimitry Andric   /// based on CodeGenOpts.
51407fa27ce4SDimitry Andric   void SetSqrtFPAccuracy(llvm::Value *Val);
51417fa27ce4SDimitry Andric 
51427fa27ce4SDimitry Andric   /// Set the minimum required accuracy of the given sqrt operation based on
51437fa27ce4SDimitry Andric   /// CodeGenOpts.
51447fa27ce4SDimitry Andric   void SetDivFPAccuracy(llvm::Value *Val);
51457fa27ce4SDimitry Andric 
5146cfca06d7SDimitry Andric   /// Set the codegen fast-math flags.
5147cfca06d7SDimitry Andric   void SetFastMathFlags(FPOptions FPFeatures);
5148cfca06d7SDimitry Andric 
5149145449b1SDimitry Andric   // Truncate or extend a boolean vector to the requested number of elements.
5150145449b1SDimitry Andric   llvm::Value *emitBoolVecConversion(llvm::Value *SrcVec,
5151145449b1SDimitry Andric                                      unsigned NumElementsDst,
5152145449b1SDimitry Andric                                      const llvm::Twine &Name = "");
5153ac9a064cSDimitry Andric   // Adds a convergence_ctrl token to |Input| and emits the required parent
5154ac9a064cSDimitry Andric   // convergence instructions.
5155ac9a064cSDimitry Andric   template <typename CallType>
5156ac9a064cSDimitry Andric   CallType *addControlledConvergenceToken(CallType *Input) {
5157ac9a064cSDimitry Andric     return cast<CallType>(
5158ac9a064cSDimitry Andric         addConvergenceControlToken(Input, ConvergenceTokenStack.back()));
5159ac9a064cSDimitry Andric   }
5160ac9a064cSDimitry Andric 
5161ac9a064cSDimitry Andric private:
5162ac9a064cSDimitry Andric   // Emits a convergence_loop instruction for the given |BB|, with |ParentToken|
5163ac9a064cSDimitry Andric   // as it's parent convergence instr.
5164ac9a064cSDimitry Andric   llvm::IntrinsicInst *emitConvergenceLoopToken(llvm::BasicBlock *BB,
5165ac9a064cSDimitry Andric                                                 llvm::Value *ParentToken);
5166ac9a064cSDimitry Andric   // Adds a convergence_ctrl token with |ParentToken| as parent convergence
5167ac9a064cSDimitry Andric   // instr to the call |Input|.
5168ac9a064cSDimitry Andric   llvm::CallBase *addConvergenceControlToken(llvm::CallBase *Input,
5169ac9a064cSDimitry Andric                                              llvm::Value *ParentToken);
5170ac9a064cSDimitry Andric   // Find the convergence_entry instruction |F|, or emits ones if none exists.
5171ac9a064cSDimitry Andric   // Returns the convergence instruction.
5172ac9a064cSDimitry Andric   llvm::IntrinsicInst *getOrEmitConvergenceEntryToken(llvm::Function *F);
5173ac9a064cSDimitry Andric   // Find the convergence_loop instruction for the loop defined by |LI|, or
5174ac9a064cSDimitry Andric   // emits one if none exists. Returns the convergence instruction.
5175ac9a064cSDimitry Andric   llvm::IntrinsicInst *getOrEmitConvergenceLoopToken(const LoopInfo *LI);
5176145449b1SDimitry Andric 
5177ec2b103cSEd Schouten private:
5178dbe13110SDimitry Andric   llvm::MDNode *getRangeForLoadFromType(QualType Ty);
5179ec2b103cSEd Schouten   void EmitReturnOfRValue(RValue RV, QualType Ty);
5180ec2b103cSEd Schouten 
51819f4dbff6SDimitry Andric   void deferPlaceholderReplacement(llvm::Instruction *Old, llvm::Value *New);
51829f4dbff6SDimitry Andric 
5183344a3780SDimitry Andric   llvm::SmallVector<std::pair<llvm::WeakTrackingVH, llvm::Value *>, 4>
51849f4dbff6SDimitry Andric       DeferredReplacements;
51859f4dbff6SDimitry Andric 
518645b53394SDimitry Andric   /// Set the address of a local variable.
518745b53394SDimitry Andric   void setAddrOfLocalVar(const VarDecl *VD, Address Addr) {
518845b53394SDimitry Andric     assert(!LocalDeclMap.count(VD) && "Decl already exists in LocalDeclMap!");
518945b53394SDimitry Andric     LocalDeclMap.insert({VD, Addr});
519045b53394SDimitry Andric   }
519145b53394SDimitry Andric 
5192ec2b103cSEd Schouten   /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty
5193ec2b103cSEd Schouten   /// from function arguments into \arg Dst. See ABIArgInfo::Expand.
5194ec2b103cSEd Schouten   ///
5195ec2b103cSEd Schouten   /// \param AI - The first function argument of the expansion.
519606d4ba38SDimitry Andric   void ExpandTypeFromArgs(QualType Ty, LValue Dst,
5197cfca06d7SDimitry Andric                           llvm::Function::arg_iterator &AI);
5198ec2b103cSEd Schouten 
519948675466SDimitry Andric   /// ExpandTypeToArgs - Expand an CallArg \arg Arg, with the LLVM type for \arg
520006d4ba38SDimitry Andric   /// Ty, into individual arguments on the provided vector \arg IRCallArgs,
520106d4ba38SDimitry Andric   /// starting at index \arg IRCallArgPos. See ABIArgInfo::Expand.
520248675466SDimitry Andric   void ExpandTypeToArgs(QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy,
520306d4ba38SDimitry Andric                         SmallVectorImpl<llvm::Value *> &IRCallArgs,
520406d4ba38SDimitry Andric                         unsigned &IRCallArgPos);
5205ec2b103cSEd Schouten 
52066f8fc217SDimitry Andric   std::pair<llvm::Value *, llvm::Type *>
52076f8fc217SDimitry Andric   EmitAsmInput(const TargetInfo::ConstraintInfo &Info, const Expr *InputExpr,
52086f8fc217SDimitry Andric                std::string &ConstraintStr);
5209ec2b103cSEd Schouten 
52106f8fc217SDimitry Andric   std::pair<llvm::Value *, llvm::Type *>
52116f8fc217SDimitry Andric   EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, LValue InputValue,
52126f8fc217SDimitry Andric                      QualType InputType, std::string &ConstraintStr,
5213bfef3995SDimitry Andric                      SourceLocation Loc);
52143d1dcd9bSDimitry Andric 
521548675466SDimitry Andric   /// Attempts to statically evaluate the object size of E. If that
521645b53394SDimitry Andric   /// fails, emits code to figure the size of E out for us. This is
521745b53394SDimitry Andric   /// pass_object_size aware.
52187442d6faSDimitry Andric   ///
52197442d6faSDimitry Andric   /// If EmittedExpr is non-null, this will use that instead of re-emitting E.
522045b53394SDimitry Andric   llvm::Value *evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
52217442d6faSDimitry Andric                                                llvm::IntegerType *ResType,
522222989816SDimitry Andric                                                llvm::Value *EmittedE,
522322989816SDimitry Andric                                                bool IsDynamic);
522445b53394SDimitry Andric 
522548675466SDimitry Andric   /// Emits the size of E, as required by __builtin_object_size. This
522645b53394SDimitry Andric   /// function is aware of pass_object_size parameters, and will act accordingly
522745b53394SDimitry Andric   /// if E is a parameter with the pass_object_size attribute.
522845b53394SDimitry Andric   llvm::Value *emitBuiltinObjectSize(const Expr *E, unsigned Type,
52297442d6faSDimitry Andric                                      llvm::IntegerType *ResType,
523022989816SDimitry Andric                                      llvm::Value *EmittedE,
523122989816SDimitry Andric                                      bool IsDynamic);
523222989816SDimitry Andric 
5233950076cdSDimitry Andric   llvm::Value *emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
5234950076cdSDimitry Andric                                            llvm::IntegerType *ResType);
5235950076cdSDimitry Andric 
523622989816SDimitry Andric   void emitZeroOrPatternForAutoVarInit(QualType type, const VarDecl &D,
523722989816SDimitry Andric                                        Address Loc);
523845b53394SDimitry Andric 
52399f4dbff6SDimitry Andric public:
5240bab175ecSDimitry Andric   enum class EvaluationOrder {
5241bab175ecSDimitry Andric     ///! No language constraints on evaluation order.
5242bab175ecSDimitry Andric     Default,
5243bab175ecSDimitry Andric     ///! Language semantics require left-to-right evaluation.
5244bab175ecSDimitry Andric     ForceLeftToRight,
5245bab175ecSDimitry Andric     ///! Language semantics require right-to-left evaluation.
5246bab175ecSDimitry Andric     ForceRightToLeft
5247bab175ecSDimitry Andric   };
5248bab175ecSDimitry Andric 
5249b60736ecSDimitry Andric   // Wrapper for function prototype sources. Wraps either a FunctionProtoType or
5250b60736ecSDimitry Andric   // an ObjCMethodDecl.
5251b60736ecSDimitry Andric   struct PrototypeWrapper {
5252b60736ecSDimitry Andric     llvm::PointerUnion<const FunctionProtoType *, const ObjCMethodDecl *> P;
5253ec2b103cSEd Schouten 
5254b60736ecSDimitry Andric     PrototypeWrapper(const FunctionProtoType *FT) : P(FT) {}
5255b60736ecSDimitry Andric     PrototypeWrapper(const ObjCMethodDecl *MD) : P(MD) {}
5256b60736ecSDimitry Andric   };
525751ece4aaSDimitry Andric 
5258b60736ecSDimitry Andric   void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype,
525945b53394SDimitry Andric                     llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
52607442d6faSDimitry Andric                     AbstractCallee AC = AbstractCallee(),
5261bab175ecSDimitry Andric                     unsigned ParamsToSkip = 0,
5262bab175ecSDimitry Andric                     EvaluationOrder Order = EvaluationOrder::Default);
52639f4dbff6SDimitry Andric 
5264aa803409SDimitry Andric   /// EmitPointerWithAlignment - Given an expression with a pointer type,
5265aa803409SDimitry Andric   /// emit the value and compute our best estimate of the alignment of the
5266aa803409SDimitry Andric   /// pointee.
526745b53394SDimitry Andric   ///
5268aa803409SDimitry Andric   /// \param BaseInfo - If non-null, this will be initialized with
5269aa803409SDimitry Andric   /// information about the source of the alignment and the may-alias
5270aa803409SDimitry Andric   /// attribute.  Note that this function will conservatively fall back on
5271aa803409SDimitry Andric   /// the type when it doesn't recognize the expression and may-alias will
5272aa803409SDimitry Andric   /// be set to false.
527345b53394SDimitry Andric   ///
5274aa803409SDimitry Andric   /// One reasonable way to use this information is when there's a language
5275aa803409SDimitry Andric   /// guarantee that the pointer must be aligned to some stricter value, and
5276aa803409SDimitry Andric   /// we're simply trying to ensure that sufficiently obvious uses of under-
5277aa803409SDimitry Andric   /// aligned objects don't get miscompiled; for example, a placement new
5278aa803409SDimitry Andric   /// into the address of a local variable.  In such a case, it's quite
5279aa803409SDimitry Andric   /// reasonable to just ignore the returned alignment when it isn't from an
528045b53394SDimitry Andric   /// explicit source.
52817fa27ce4SDimitry Andric   Address
52827fa27ce4SDimitry Andric   EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo = nullptr,
52837fa27ce4SDimitry Andric                            TBAAAccessInfo *TBAAInfo = nullptr,
52847fa27ce4SDimitry Andric                            KnownNonNull_t IsKnownNonNull = NotKnownNonNull);
5285461a67faSDimitry Andric 
5286461a67faSDimitry Andric   /// If \p E references a parameter with pass_object_size info or a constant
5287461a67faSDimitry Andric   /// array size modifier, emit the object size divided by the size of \p EltTy.
5288461a67faSDimitry Andric   /// Otherwise return null.
5289461a67faSDimitry Andric   llvm::Value *LoadPassedObjectSize(const Expr *E, QualType EltTy);
529045b53394SDimitry Andric 
52912b6b257fSDimitry Andric   void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK);
52922b6b257fSDimitry Andric 
5293676fbe81SDimitry Andric   struct MultiVersionResolverOption {
529448675466SDimitry Andric     llvm::Function *Function;
5295676fbe81SDimitry Andric     struct Conds {
5296676fbe81SDimitry Andric       StringRef Architecture;
5297676fbe81SDimitry Andric       llvm::SmallVector<StringRef, 8> Features;
529848675466SDimitry Andric 
5299676fbe81SDimitry Andric       Conds(StringRef Arch, ArrayRef<StringRef> Feats)
5300676fbe81SDimitry Andric           : Architecture(Arch), Features(Feats.begin(), Feats.end()) {}
5301676fbe81SDimitry Andric     } Conditions;
530248675466SDimitry Andric 
5303676fbe81SDimitry Andric     MultiVersionResolverOption(llvm::Function *F, StringRef Arch,
5304676fbe81SDimitry Andric                                ArrayRef<StringRef> Feats)
5305676fbe81SDimitry Andric         : Function(F), Conditions(Arch, Feats) {}
530648675466SDimitry Andric   };
530748675466SDimitry Andric 
5308676fbe81SDimitry Andric   // Emits the body of a multiversion function's resolver. Assumes that the
5309676fbe81SDimitry Andric   // options are already sorted in the proper order, with the 'default' option
5310676fbe81SDimitry Andric   // last (if it exists).
5311676fbe81SDimitry Andric   void EmitMultiVersionResolver(llvm::Function *Resolver,
5312676fbe81SDimitry Andric                                 ArrayRef<MultiVersionResolverOption> Options);
5313e3b55780SDimitry Andric   void
5314e3b55780SDimitry Andric   EmitX86MultiVersionResolver(llvm::Function *Resolver,
5315e3b55780SDimitry Andric                               ArrayRef<MultiVersionResolverOption> Options);
5316e3b55780SDimitry Andric   void
5317e3b55780SDimitry Andric   EmitAArch64MultiVersionResolver(llvm::Function *Resolver,
5318e3b55780SDimitry Andric                                   ArrayRef<MultiVersionResolverOption> Options);
5319676fbe81SDimitry Andric 
53209f4dbff6SDimitry Andric private:
532106d4ba38SDimitry Andric   QualType getVarArgType(const Expr *Arg);
532206d4ba38SDimitry Andric 
53234ba67500SRoman Divacky   void EmitDeclMetadata();
532401af97d3SDimitry Andric 
532545b53394SDimitry Andric   BlockByrefHelpers *buildByrefHelpers(llvm::StructType &byrefType,
532601af97d3SDimitry Andric                                   const AutoVarEmission &emission);
5327dbe13110SDimitry Andric 
5328dbe13110SDimitry Andric   void AddObjCARCExceptionMetadata(llvm::Instruction *Inst);
5329dbe13110SDimitry Andric 
533006d4ba38SDimitry Andric   llvm::Value *GetValueForARMHint(unsigned BuiltinID);
5331461a67faSDimitry Andric   llvm::Value *EmitX86CpuIs(const CallExpr *E);
5332461a67faSDimitry Andric   llvm::Value *EmitX86CpuIs(StringRef CPUStr);
5333461a67faSDimitry Andric   llvm::Value *EmitX86CpuSupports(const CallExpr *E);
5334461a67faSDimitry Andric   llvm::Value *EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs);
5335b1c73532SDimitry Andric   llvm::Value *EmitX86CpuSupports(std::array<uint32_t, 4> FeatureMask);
5336461a67faSDimitry Andric   llvm::Value *EmitX86CpuInit();
5337e3b55780SDimitry Andric   llvm::Value *FormX86ResolverCondition(const MultiVersionResolverOption &RO);
5338e3b55780SDimitry Andric   llvm::Value *EmitAArch64CpuInit();
5339e3b55780SDimitry Andric   llvm::Value *
5340e3b55780SDimitry Andric   FormAArch64ResolverCondition(const MultiVersionResolverOption &RO);
5341ac9a064cSDimitry Andric   llvm::Value *EmitAArch64CpuSupports(const CallExpr *E);
5342e3b55780SDimitry Andric   llvm::Value *EmitAArch64CpuSupports(ArrayRef<StringRef> FeatureStrs);
5343ec2b103cSEd Schouten };
5344ec2b103cSEd Schouten 
534548675466SDimitry Andric inline DominatingLLVMValue::saved_type
534648675466SDimitry Andric DominatingLLVMValue::save(CodeGenFunction &CGF, llvm::Value *value) {
5347bca07a45SDimitry Andric   if (!needsSaving(value)) return saved_type(value, false);
5348bca07a45SDimitry Andric 
534945b53394SDimitry Andric   // Otherwise, we need an alloca.
535045b53394SDimitry Andric   auto align = CharUnits::fromQuantity(
5351e3b55780SDimitry Andric       CGF.CGM.getDataLayout().getPrefTypeAlign(value->getType()));
535245b53394SDimitry Andric   Address alloca =
535345b53394SDimitry Andric       CGF.CreateTempAlloca(value->getType(), align, "cond-cleanup.save");
5354bca07a45SDimitry Andric   CGF.Builder.CreateStore(value, alloca);
5355bca07a45SDimitry Andric 
5356ac9a064cSDimitry Andric   return saved_type(alloca.emitRawPointer(CGF), true);
5357bca07a45SDimitry Andric }
5358bca07a45SDimitry Andric 
535948675466SDimitry Andric inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF,
536048675466SDimitry Andric                                                  saved_type value) {
536145b53394SDimitry Andric   // If the value says it wasn't saved, trust that it's still dominating.
5362bca07a45SDimitry Andric   if (!value.getInt()) return value.getPointer();
536345b53394SDimitry Andric 
536445b53394SDimitry Andric   // Otherwise, it should be an alloca instruction, as set up in save().
536545b53394SDimitry Andric   auto alloca = cast<llvm::AllocaInst>(value.getPointer());
5366344a3780SDimitry Andric   return CGF.Builder.CreateAlignedLoad(alloca->getAllocatedType(), alloca,
5367344a3780SDimitry Andric                                        alloca->getAlign());
5368bca07a45SDimitry Andric }
5369ec2b103cSEd Schouten 
5370ec2b103cSEd Schouten }  // end namespace CodeGen
5371cfca06d7SDimitry Andric 
5372cfca06d7SDimitry Andric // Map the LangOption for floating point exception behavior into
5373cfca06d7SDimitry Andric // the corresponding enum in the IR.
5374cfca06d7SDimitry Andric llvm::fp::ExceptionBehavior
5375cfca06d7SDimitry Andric ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind);
5376ec2b103cSEd Schouten }  // end namespace clang
5377ec2b103cSEd Schouten 
5378ec2b103cSEd Schouten #endif
5379