xref: /freebsd-src/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.h (revision c80e69b00d976a5a3b3e84527f270fa7e72a8205)
10b57cec5SDimitry Andric //===-- CodeGenFunction.h - Per-Function state for LLVM CodeGen -*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This is the internal per-function state used for llvm translation.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENFUNCTION_H
140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CODEGENFUNCTION_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "CGBuilder.h"
170b57cec5SDimitry Andric #include "CGDebugInfo.h"
180b57cec5SDimitry Andric #include "CGLoopInfo.h"
190b57cec5SDimitry Andric #include "CGValue.h"
200b57cec5SDimitry Andric #include "CodeGenModule.h"
210b57cec5SDimitry Andric #include "CodeGenPGO.h"
220b57cec5SDimitry Andric #include "EHScopeStack.h"
230b57cec5SDimitry Andric #include "VarBypassDetector.h"
240b57cec5SDimitry Andric #include "clang/AST/CharUnits.h"
250b57cec5SDimitry Andric #include "clang/AST/CurrentSourceLocExprScope.h"
260b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h"
270b57cec5SDimitry Andric #include "clang/AST/ExprObjC.h"
280b57cec5SDimitry Andric #include "clang/AST/ExprOpenMP.h"
290fca6ea1SDimitry Andric #include "clang/AST/StmtOpenACC.h"
305ffd83dbSDimitry Andric #include "clang/AST/StmtOpenMP.h"
310b57cec5SDimitry Andric #include "clang/AST/Type.h"
320b57cec5SDimitry Andric #include "clang/Basic/ABI.h"
330b57cec5SDimitry Andric #include "clang/Basic/CapturedStmt.h"
340b57cec5SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
350b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.h"
360b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
370b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
380b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
390b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h"
400b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
415ffd83dbSDimitry Andric #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
420fca6ea1SDimitry Andric #include "llvm/IR/Instructions.h"
430b57cec5SDimitry Andric #include "llvm/IR/ValueHandle.h"
440b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
450b57cec5SDimitry Andric #include "llvm/Transforms/Utils/SanitizerStats.h"
46bdd1243dSDimitry Andric #include <optional>
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric namespace llvm {
490b57cec5SDimitry Andric class BasicBlock;
500b57cec5SDimitry Andric class LLVMContext;
510b57cec5SDimitry Andric class MDNode;
520b57cec5SDimitry Andric class SwitchInst;
530b57cec5SDimitry Andric class Twine;
540b57cec5SDimitry Andric class Value;
55fe6060f1SDimitry Andric class CanonicalLoopInfo;
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric namespace clang {
590b57cec5SDimitry Andric class ASTContext;
600b57cec5SDimitry Andric class CXXDestructorDecl;
610b57cec5SDimitry Andric class CXXForRangeStmt;
620b57cec5SDimitry Andric class CXXTryStmt;
630b57cec5SDimitry Andric class Decl;
640b57cec5SDimitry Andric class LabelDecl;
650b57cec5SDimitry Andric class FunctionDecl;
660b57cec5SDimitry Andric class FunctionProtoType;
670b57cec5SDimitry Andric class LabelStmt;
680b57cec5SDimitry Andric class ObjCContainerDecl;
690b57cec5SDimitry Andric class ObjCInterfaceDecl;
700b57cec5SDimitry Andric class ObjCIvarDecl;
710b57cec5SDimitry Andric class ObjCMethodDecl;
720b57cec5SDimitry Andric class ObjCImplementationDecl;
730b57cec5SDimitry Andric class ObjCPropertyImplDecl;
740b57cec5SDimitry Andric class TargetInfo;
750b57cec5SDimitry Andric class VarDecl;
760b57cec5SDimitry Andric class ObjCForCollectionStmt;
770b57cec5SDimitry Andric class ObjCAtTryStmt;
780b57cec5SDimitry Andric class ObjCAtThrowStmt;
790b57cec5SDimitry Andric class ObjCAtSynchronizedStmt;
800b57cec5SDimitry Andric class ObjCAutoreleasePoolStmt;
815ffd83dbSDimitry Andric class OMPUseDevicePtrClause;
825ffd83dbSDimitry Andric class OMPUseDeviceAddrClause;
835ffd83dbSDimitry Andric class SVETypeFlags;
845ffd83dbSDimitry Andric class OMPExecutableDirective;
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric namespace analyze_os_log {
870b57cec5SDimitry Andric class OSLogBufferLayout;
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric namespace CodeGen {
910b57cec5SDimitry Andric class CodeGenTypes;
920b57cec5SDimitry Andric class CGCallee;
930b57cec5SDimitry Andric class CGFunctionInfo;
940b57cec5SDimitry Andric class CGBlockInfo;
950b57cec5SDimitry Andric class CGCXXABI;
960b57cec5SDimitry Andric class BlockByrefHelpers;
970b57cec5SDimitry Andric class BlockByrefInfo;
980b57cec5SDimitry Andric class BlockFieldFlags;
990b57cec5SDimitry Andric class RegionCodeGenTy;
1000b57cec5SDimitry Andric class TargetCodeGenInfo;
1010b57cec5SDimitry Andric struct OMPTaskDataTy;
1020b57cec5SDimitry Andric struct CGCoroData;
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric /// The kind of evaluation to perform on values of a particular
1050b57cec5SDimitry Andric /// type.  Basically, is the code in CGExprScalar, CGExprComplex, or
1060b57cec5SDimitry Andric /// CGExprAgg?
1070b57cec5SDimitry Andric ///
1080b57cec5SDimitry Andric /// TODO: should vectors maybe be split out into their own thing?
1090b57cec5SDimitry Andric enum TypeEvaluationKind {
1100b57cec5SDimitry Andric   TEK_Scalar,
1110b57cec5SDimitry Andric   TEK_Complex,
1120b57cec5SDimitry Andric   TEK_Aggregate
1130b57cec5SDimitry Andric };
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric #define LIST_SANITIZER_CHECKS                                                  \
1160b57cec5SDimitry Andric   SANITIZER_CHECK(AddOverflow, add_overflow, 0)                                \
1170b57cec5SDimitry Andric   SANITIZER_CHECK(BuiltinUnreachable, builtin_unreachable, 0)                  \
1180b57cec5SDimitry Andric   SANITIZER_CHECK(CFICheckFail, cfi_check_fail, 0)                             \
1190b57cec5SDimitry Andric   SANITIZER_CHECK(DivremOverflow, divrem_overflow, 0)                          \
1200b57cec5SDimitry Andric   SANITIZER_CHECK(DynamicTypeCacheMiss, dynamic_type_cache_miss, 0)            \
1210b57cec5SDimitry Andric   SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0)                   \
12206c3fb27SDimitry Andric   SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 0)             \
1230b57cec5SDimitry Andric   SANITIZER_CHECK(ImplicitConversion, implicit_conversion, 0)                  \
1240b57cec5SDimitry Andric   SANITIZER_CHECK(InvalidBuiltin, invalid_builtin, 0)                          \
1255ffd83dbSDimitry Andric   SANITIZER_CHECK(InvalidObjCCast, invalid_objc_cast, 0)                       \
1260b57cec5SDimitry Andric   SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0)                     \
1270b57cec5SDimitry Andric   SANITIZER_CHECK(MissingReturn, missing_return, 0)                            \
1280b57cec5SDimitry Andric   SANITIZER_CHECK(MulOverflow, mul_overflow, 0)                                \
1290b57cec5SDimitry Andric   SANITIZER_CHECK(NegateOverflow, negate_overflow, 0)                          \
1300b57cec5SDimitry Andric   SANITIZER_CHECK(NullabilityArg, nullability_arg, 0)                          \
1310b57cec5SDimitry Andric   SANITIZER_CHECK(NullabilityReturn, nullability_return, 1)                    \
1320b57cec5SDimitry Andric   SANITIZER_CHECK(NonnullArg, nonnull_arg, 0)                                  \
1330b57cec5SDimitry Andric   SANITIZER_CHECK(NonnullReturn, nonnull_return, 1)                            \
1340b57cec5SDimitry Andric   SANITIZER_CHECK(OutOfBounds, out_of_bounds, 0)                               \
1350b57cec5SDimitry Andric   SANITIZER_CHECK(PointerOverflow, pointer_overflow, 0)                        \
1360b57cec5SDimitry Andric   SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0)                    \
1370b57cec5SDimitry Andric   SANITIZER_CHECK(SubOverflow, sub_overflow, 0)                                \
1380b57cec5SDimitry Andric   SANITIZER_CHECK(TypeMismatch, type_mismatch, 1)                              \
1390b57cec5SDimitry Andric   SANITIZER_CHECK(AlignmentAssumption, alignment_assumption, 0)                \
1400fca6ea1SDimitry Andric   SANITIZER_CHECK(VLABoundNotPositive, vla_bound_not_positive, 0)              \
1410fca6ea1SDimitry Andric   SANITIZER_CHECK(BoundsSafety, bounds_safety, 0)
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric enum SanitizerHandler {
1440b57cec5SDimitry Andric #define SANITIZER_CHECK(Enum, Name, Version) Enum,
1450b57cec5SDimitry Andric   LIST_SANITIZER_CHECKS
1460b57cec5SDimitry Andric #undef SANITIZER_CHECK
1470b57cec5SDimitry Andric };
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric /// Helper class with most of the code for saving a value for a
1500b57cec5SDimitry Andric /// conditional expression cleanup.
1510b57cec5SDimitry Andric struct DominatingLLVMValue {
1520b57cec5SDimitry Andric   typedef llvm::PointerIntPair<llvm::Value*, 1, bool> saved_type;
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric   /// Answer whether the given value needs extra work to be saved.
1550b57cec5SDimitry Andric   static bool needsSaving(llvm::Value *value) {
1560fca6ea1SDimitry Andric     if (!value)
1570fca6ea1SDimitry Andric       return false;
1580fca6ea1SDimitry Andric 
1590b57cec5SDimitry Andric     // If it's not an instruction, we don't need to save.
1600b57cec5SDimitry Andric     if (!isa<llvm::Instruction>(value)) return false;
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric     // If it's an instruction in the entry block, we don't need to save.
1630b57cec5SDimitry Andric     llvm::BasicBlock *block = cast<llvm::Instruction>(value)->getParent();
1640b57cec5SDimitry Andric     return (block != &block->getParent()->getEntryBlock());
1650b57cec5SDimitry Andric   }
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   static saved_type save(CodeGenFunction &CGF, llvm::Value *value);
1680b57cec5SDimitry Andric   static llvm::Value *restore(CodeGenFunction &CGF, saved_type value);
1690b57cec5SDimitry Andric };
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric /// A partial specialization of DominatingValue for llvm::Values that
1720b57cec5SDimitry Andric /// might be llvm::Instructions.
1730b57cec5SDimitry Andric template <class T> struct DominatingPointer<T,true> : DominatingLLVMValue {
1740b57cec5SDimitry Andric   typedef T *type;
1750b57cec5SDimitry Andric   static type restore(CodeGenFunction &CGF, saved_type value) {
1760b57cec5SDimitry Andric     return static_cast<T*>(DominatingLLVMValue::restore(CGF, value));
1770b57cec5SDimitry Andric   }
1780b57cec5SDimitry Andric };
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric /// A specialization of DominatingValue for Address.
1810b57cec5SDimitry Andric template <> struct DominatingValue<Address> {
1820b57cec5SDimitry Andric   typedef Address type;
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   struct saved_type {
1850fca6ea1SDimitry Andric     DominatingLLVMValue::saved_type BasePtr;
18604eeddc0SDimitry Andric     llvm::Type *ElementType;
1870b57cec5SDimitry Andric     CharUnits Alignment;
1880fca6ea1SDimitry Andric     DominatingLLVMValue::saved_type Offset;
1890fca6ea1SDimitry Andric     llvm::PointerType *EffectiveType;
1900b57cec5SDimitry Andric   };
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric   static bool needsSaving(type value) {
1930fca6ea1SDimitry Andric     if (DominatingLLVMValue::needsSaving(value.getBasePointer()) ||
1940fca6ea1SDimitry Andric         DominatingLLVMValue::needsSaving(value.getOffset()))
1950fca6ea1SDimitry Andric       return true;
1960fca6ea1SDimitry Andric     return false;
1970b57cec5SDimitry Andric   }
1980b57cec5SDimitry Andric   static saved_type save(CodeGenFunction &CGF, type value) {
1990fca6ea1SDimitry Andric     return {DominatingLLVMValue::save(CGF, value.getBasePointer()),
2000fca6ea1SDimitry Andric             value.getElementType(), value.getAlignment(),
2010fca6ea1SDimitry Andric             DominatingLLVMValue::save(CGF, value.getOffset()), value.getType()};
2020b57cec5SDimitry Andric   }
2030b57cec5SDimitry Andric   static type restore(CodeGenFunction &CGF, saved_type value) {
2040fca6ea1SDimitry Andric     return Address(DominatingLLVMValue::restore(CGF, value.BasePtr),
2050fca6ea1SDimitry Andric                    value.ElementType, value.Alignment, CGPointerAuthInfo(),
2060fca6ea1SDimitry Andric                    DominatingLLVMValue::restore(CGF, value.Offset));
2070b57cec5SDimitry Andric   }
2080b57cec5SDimitry Andric };
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric /// A specialization of DominatingValue for RValue.
2110b57cec5SDimitry Andric template <> struct DominatingValue<RValue> {
2120b57cec5SDimitry Andric   typedef RValue type;
2130b57cec5SDimitry Andric   class saved_type {
2140b57cec5SDimitry Andric     enum Kind { ScalarLiteral, ScalarAddress, AggregateLiteral,
2150b57cec5SDimitry Andric                 AggregateAddress, ComplexAddress };
2160fca6ea1SDimitry Andric     union {
2170fca6ea1SDimitry Andric       struct {
2180fca6ea1SDimitry Andric         DominatingLLVMValue::saved_type first, second;
2190fca6ea1SDimitry Andric       } Vals;
2200fca6ea1SDimitry Andric       DominatingValue<Address>::saved_type AggregateAddr;
2210fca6ea1SDimitry Andric     };
2220fca6ea1SDimitry Andric     LLVM_PREFERRED_TYPE(Kind)
2230b57cec5SDimitry Andric     unsigned K : 3;
2240fca6ea1SDimitry Andric 
2250fca6ea1SDimitry Andric     saved_type(DominatingLLVMValue::saved_type Val1, unsigned K)
2260fca6ea1SDimitry Andric         : Vals{Val1, DominatingLLVMValue::saved_type()}, K(K) {}
2270fca6ea1SDimitry Andric 
2280fca6ea1SDimitry Andric     saved_type(DominatingLLVMValue::saved_type Val1,
2290fca6ea1SDimitry Andric                DominatingLLVMValue::saved_type Val2)
2300fca6ea1SDimitry Andric         : Vals{Val1, Val2}, K(ComplexAddress) {}
2310fca6ea1SDimitry Andric 
2320fca6ea1SDimitry Andric     saved_type(DominatingValue<Address>::saved_type AggregateAddr, unsigned K)
2330fca6ea1SDimitry Andric         : AggregateAddr(AggregateAddr), K(K) {}
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric   public:
2360b57cec5SDimitry Andric     static bool needsSaving(RValue value);
2370b57cec5SDimitry Andric     static saved_type save(CodeGenFunction &CGF, RValue value);
2380b57cec5SDimitry Andric     RValue restore(CodeGenFunction &CGF);
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric     // implementations in CGCleanup.cpp
2410b57cec5SDimitry Andric   };
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric   static bool needsSaving(type value) {
2440b57cec5SDimitry Andric     return saved_type::needsSaving(value);
2450b57cec5SDimitry Andric   }
2460b57cec5SDimitry Andric   static saved_type save(CodeGenFunction &CGF, type value) {
2470b57cec5SDimitry Andric     return saved_type::save(CGF, value);
2480b57cec5SDimitry Andric   }
2490b57cec5SDimitry Andric   static type restore(CodeGenFunction &CGF, saved_type value) {
2500b57cec5SDimitry Andric     return value.restore(CGF);
2510b57cec5SDimitry Andric   }
2520b57cec5SDimitry Andric };
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric /// CodeGenFunction - This class organizes the per-function state that is used
2550b57cec5SDimitry Andric /// while generating LLVM code.
2560b57cec5SDimitry Andric class CodeGenFunction : public CodeGenTypeCache {
2570b57cec5SDimitry Andric   CodeGenFunction(const CodeGenFunction &) = delete;
2580b57cec5SDimitry Andric   void operator=(const CodeGenFunction &) = delete;
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   friend class CGCXXABI;
2610b57cec5SDimitry Andric public:
2620b57cec5SDimitry Andric   /// A jump destination is an abstract label, branching to which may
2630b57cec5SDimitry Andric   /// require a jump out through normal cleanups.
2640b57cec5SDimitry Andric   struct JumpDest {
26504eeddc0SDimitry Andric     JumpDest() : Block(nullptr), Index(0) {}
26604eeddc0SDimitry Andric     JumpDest(llvm::BasicBlock *Block, EHScopeStack::stable_iterator Depth,
2670b57cec5SDimitry Andric              unsigned Index)
2680b57cec5SDimitry Andric         : Block(Block), ScopeDepth(Depth), Index(Index) {}
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric     bool isValid() const { return Block != nullptr; }
2710b57cec5SDimitry Andric     llvm::BasicBlock *getBlock() const { return Block; }
2720b57cec5SDimitry Andric     EHScopeStack::stable_iterator getScopeDepth() const { return ScopeDepth; }
2730b57cec5SDimitry Andric     unsigned getDestIndex() const { return Index; }
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric     // This should be used cautiously.
2760b57cec5SDimitry Andric     void setScopeDepth(EHScopeStack::stable_iterator depth) {
2770b57cec5SDimitry Andric       ScopeDepth = depth;
2780b57cec5SDimitry Andric     }
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   private:
2810b57cec5SDimitry Andric     llvm::BasicBlock *Block;
2820b57cec5SDimitry Andric     EHScopeStack::stable_iterator ScopeDepth;
2830b57cec5SDimitry Andric     unsigned Index;
2840b57cec5SDimitry Andric   };
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric   CodeGenModule &CGM;  // Per-module state.
2870b57cec5SDimitry Andric   const TargetInfo &Target;
2880b57cec5SDimitry Andric 
2895ffd83dbSDimitry Andric   // For EH/SEH outlined funclets, this field points to parent's CGF
2905ffd83dbSDimitry Andric   CodeGenFunction *ParentCGF = nullptr;
2915ffd83dbSDimitry Andric 
2920b57cec5SDimitry Andric   typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
2930b57cec5SDimitry Andric   LoopInfoStack LoopStack;
2940b57cec5SDimitry Andric   CGBuilderTy Builder;
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric   // Stores variables for which we can't generate correct lifetime markers
2970b57cec5SDimitry Andric   // because of jumps.
2980b57cec5SDimitry Andric   VarBypassDetector Bypasses;
2990b57cec5SDimitry Andric 
300fe6060f1SDimitry Andric   /// List of recently emitted OMPCanonicalLoops.
301fe6060f1SDimitry Andric   ///
302fe6060f1SDimitry Andric   /// Since OMPCanonicalLoops are nested inside other statements (in particular
303fe6060f1SDimitry Andric   /// CapturedStmt generated by OMPExecutableDirective and non-perfectly nested
304fe6060f1SDimitry Andric   /// loops), we cannot directly call OMPEmitOMPCanonicalLoop and receive its
305fe6060f1SDimitry Andric   /// llvm::CanonicalLoopInfo. Instead, we call EmitStmt and any
306fe6060f1SDimitry Andric   /// OMPEmitOMPCanonicalLoop called by it will add its CanonicalLoopInfo to
307fe6060f1SDimitry Andric   /// this stack when done. Entering a new loop requires clearing this list; it
308fe6060f1SDimitry Andric   /// either means we start parsing a new loop nest (in which case the previous
309fe6060f1SDimitry Andric   /// loop nest goes out of scope) or a second loop in the same level in which
310fe6060f1SDimitry Andric   /// case it would be ambiguous into which of the two (or more) loops the loop
311fe6060f1SDimitry Andric   /// nest would extend.
312fe6060f1SDimitry Andric   SmallVector<llvm::CanonicalLoopInfo *, 4> OMPLoopNestStack;
313fe6060f1SDimitry Andric 
3141db9f3b2SDimitry Andric   /// Stack to track the Logical Operator recursion nest for MC/DC.
3151db9f3b2SDimitry Andric   SmallVector<const BinaryOperator *, 16> MCDCLogOpStack;
3161db9f3b2SDimitry Andric 
3170fca6ea1SDimitry Andric   /// Stack to track the controlled convergence tokens.
3180fca6ea1SDimitry Andric   SmallVector<llvm::IntrinsicInst *, 4> ConvergenceTokenStack;
3190fca6ea1SDimitry Andric 
320349cc55cSDimitry Andric   /// Number of nested loop to be consumed by the last surrounding
321349cc55cSDimitry Andric   /// loop-associated directive.
322349cc55cSDimitry Andric   int ExpectedOMPLoopDepth = 0;
323349cc55cSDimitry Andric 
3240b57cec5SDimitry Andric   // CodeGen lambda for loops and support for ordered clause
3250b57cec5SDimitry Andric   typedef llvm::function_ref<void(CodeGenFunction &, const OMPLoopDirective &,
3260b57cec5SDimitry Andric                                   JumpDest)>
3270b57cec5SDimitry Andric       CodeGenLoopTy;
3280b57cec5SDimitry Andric   typedef llvm::function_ref<void(CodeGenFunction &, SourceLocation,
3290b57cec5SDimitry Andric                                   const unsigned, const bool)>
3300b57cec5SDimitry Andric       CodeGenOrderedTy;
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric   // Codegen lambda for loop bounds in worksharing loop constructs
3330b57cec5SDimitry Andric   typedef llvm::function_ref<std::pair<LValue, LValue>(
3340b57cec5SDimitry Andric       CodeGenFunction &, const OMPExecutableDirective &S)>
3350b57cec5SDimitry Andric       CodeGenLoopBoundsTy;
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric   // Codegen lambda for loop bounds in dispatch-based loop implementation
3380b57cec5SDimitry Andric   typedef llvm::function_ref<std::pair<llvm::Value *, llvm::Value *>(
3390b57cec5SDimitry Andric       CodeGenFunction &, const OMPExecutableDirective &S, Address LB,
3400b57cec5SDimitry Andric       Address UB)>
3410b57cec5SDimitry Andric       CodeGenDispatchBoundsTy;
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric   /// CGBuilder insert helper. This function is called after an
3440b57cec5SDimitry Andric   /// instruction is created using Builder.
3450b57cec5SDimitry Andric   void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
3460b57cec5SDimitry Andric                     llvm::BasicBlock::iterator InsertPt) const;
3470b57cec5SDimitry Andric 
3480b57cec5SDimitry Andric   /// CurFuncDecl - Holds the Decl for the current outermost
3490b57cec5SDimitry Andric   /// non-closure context.
35006c3fb27SDimitry Andric   const Decl *CurFuncDecl = nullptr;
3510b57cec5SDimitry Andric   /// CurCodeDecl - This is the inner-most code context, which includes blocks.
35206c3fb27SDimitry Andric   const Decl *CurCodeDecl = nullptr;
35306c3fb27SDimitry Andric   const CGFunctionInfo *CurFnInfo = nullptr;
3540b57cec5SDimitry Andric   QualType FnRetTy;
3550b57cec5SDimitry Andric   llvm::Function *CurFn = nullptr;
3560b57cec5SDimitry Andric 
357fe6060f1SDimitry Andric   /// Save Parameter Decl for coroutine.
358fe6060f1SDimitry Andric   llvm::SmallVector<const ParmVarDecl *, 4> FnArgs;
359fe6060f1SDimitry Andric 
3600b57cec5SDimitry Andric   // Holds coroutine data if the current function is a coroutine. We use a
3610b57cec5SDimitry Andric   // wrapper to manage its lifetime, so that we don't have to define CGCoroData
3620b57cec5SDimitry Andric   // in this header.
3630b57cec5SDimitry Andric   struct CGCoroInfo {
3640b57cec5SDimitry Andric     std::unique_ptr<CGCoroData> Data;
36506c3fb27SDimitry Andric     bool InSuspendBlock = false;
3660b57cec5SDimitry Andric     CGCoroInfo();
3670b57cec5SDimitry Andric     ~CGCoroInfo();
3680b57cec5SDimitry Andric   };
3690b57cec5SDimitry Andric   CGCoroInfo CurCoro;
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric   bool isCoroutine() const {
3720b57cec5SDimitry Andric     return CurCoro.Data != nullptr;
3730b57cec5SDimitry Andric   }
3740b57cec5SDimitry Andric 
37506c3fb27SDimitry Andric   bool inSuspendBlock() const {
37606c3fb27SDimitry Andric     return isCoroutine() && CurCoro.InSuspendBlock;
37706c3fb27SDimitry Andric   }
37806c3fb27SDimitry Andric 
3790fca6ea1SDimitry Andric   // Holds FramePtr for await_suspend wrapper generation,
3800fca6ea1SDimitry Andric   // so that __builtin_coro_frame call can be lowered
3810fca6ea1SDimitry Andric   // directly to value of its second argument
3820fca6ea1SDimitry Andric   struct AwaitSuspendWrapperInfo {
3830fca6ea1SDimitry Andric     llvm::Value *FramePtr = nullptr;
3840fca6ea1SDimitry Andric   };
3850fca6ea1SDimitry Andric   AwaitSuspendWrapperInfo CurAwaitSuspendWrapper;
3860fca6ea1SDimitry Andric 
3870fca6ea1SDimitry Andric   // Generates wrapper function for `llvm.coro.await.suspend.*` intrinisics.
3880fca6ea1SDimitry Andric   // It encapsulates SuspendExpr in a function, to separate it's body
3890fca6ea1SDimitry Andric   // from the main coroutine to avoid miscompilations. Intrinisic
3900fca6ea1SDimitry Andric   // is lowered to this function call in CoroSplit pass
3910fca6ea1SDimitry Andric   // Function signature is:
3920fca6ea1SDimitry Andric   // <type> __await_suspend_wrapper_<name>(ptr %awaiter, ptr %hdl)
3930fca6ea1SDimitry Andric   // where type is one of (void, i1, ptr)
3940fca6ea1SDimitry Andric   llvm::Function *generateAwaitSuspendWrapper(Twine const &CoroName,
3950fca6ea1SDimitry Andric                                               Twine const &SuspendPointName,
3960fca6ea1SDimitry Andric                                               CoroutineSuspendExpr const &S);
3970fca6ea1SDimitry Andric 
3980b57cec5SDimitry Andric   /// CurGD - The GlobalDecl for the current function being compiled.
3990b57cec5SDimitry Andric   GlobalDecl CurGD;
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   /// PrologueCleanupDepth - The cleanup depth enclosing all the
4020b57cec5SDimitry Andric   /// cleanups associated with the parameters.
4030b57cec5SDimitry Andric   EHScopeStack::stable_iterator PrologueCleanupDepth;
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric   /// ReturnBlock - Unified return block.
4060b57cec5SDimitry Andric   JumpDest ReturnBlock;
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric   /// ReturnValue - The temporary alloca to hold the return
4090b57cec5SDimitry Andric   /// value. This is invalid iff the function has no return value.
4100b57cec5SDimitry Andric   Address ReturnValue = Address::invalid();
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric   /// ReturnValuePointer - The temporary alloca to hold a pointer to sret.
4130b57cec5SDimitry Andric   /// This is invalid if sret is not in use.
4140b57cec5SDimitry Andric   Address ReturnValuePointer = Address::invalid();
4150b57cec5SDimitry Andric 
4165ffd83dbSDimitry Andric   /// If a return statement is being visited, this holds the return statment's
4175ffd83dbSDimitry Andric   /// result expression.
4185ffd83dbSDimitry Andric   const Expr *RetExpr = nullptr;
4195ffd83dbSDimitry Andric 
4200b57cec5SDimitry Andric   /// Return true if a label was seen in the current scope.
4210b57cec5SDimitry Andric   bool hasLabelBeenSeenInCurrentScope() const {
4220b57cec5SDimitry Andric     if (CurLexicalScope)
4230b57cec5SDimitry Andric       return CurLexicalScope->hasLabels();
4240b57cec5SDimitry Andric     return !LabelMap.empty();
4250b57cec5SDimitry Andric   }
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric   /// AllocaInsertPoint - This is an instruction in the entry block before which
4280b57cec5SDimitry Andric   /// we prefer to insert allocas.
4290b57cec5SDimitry Andric   llvm::AssertingVH<llvm::Instruction> AllocaInsertPt;
4300b57cec5SDimitry Andric 
431349cc55cSDimitry Andric private:
432349cc55cSDimitry Andric   /// PostAllocaInsertPt - This is a place in the prologue where code can be
433349cc55cSDimitry Andric   /// inserted that will be dominated by all the static allocas. This helps
434349cc55cSDimitry Andric   /// achieve two things:
435349cc55cSDimitry Andric   ///   1. Contiguity of all static allocas (within the prologue) is maintained.
436349cc55cSDimitry Andric   ///   2. All other prologue code (which are dominated by static allocas) do
437349cc55cSDimitry Andric   ///      appear in the source order immediately after all static allocas.
438349cc55cSDimitry Andric   ///
439349cc55cSDimitry Andric   /// PostAllocaInsertPt will be lazily created when it is *really* required.
440349cc55cSDimitry Andric   llvm::AssertingVH<llvm::Instruction> PostAllocaInsertPt = nullptr;
441349cc55cSDimitry Andric 
442349cc55cSDimitry Andric public:
443349cc55cSDimitry Andric   /// Return PostAllocaInsertPt. If it is not yet created, then insert it
444349cc55cSDimitry Andric   /// immediately after AllocaInsertPt.
445349cc55cSDimitry Andric   llvm::Instruction *getPostAllocaInsertPoint() {
446349cc55cSDimitry Andric     if (!PostAllocaInsertPt) {
447349cc55cSDimitry Andric       assert(AllocaInsertPt &&
448349cc55cSDimitry Andric              "Expected static alloca insertion point at function prologue");
449349cc55cSDimitry Andric       assert(AllocaInsertPt->getParent()->isEntryBlock() &&
450349cc55cSDimitry Andric              "EBB should be entry block of the current code gen function");
451349cc55cSDimitry Andric       PostAllocaInsertPt = AllocaInsertPt->clone();
452349cc55cSDimitry Andric       PostAllocaInsertPt->setName("postallocapt");
453349cc55cSDimitry Andric       PostAllocaInsertPt->insertAfter(AllocaInsertPt);
454349cc55cSDimitry Andric     }
455349cc55cSDimitry Andric 
456349cc55cSDimitry Andric     return PostAllocaInsertPt;
457349cc55cSDimitry Andric   }
458349cc55cSDimitry Andric 
4590b57cec5SDimitry Andric   /// API for captured statement code generation.
4600b57cec5SDimitry Andric   class CGCapturedStmtInfo {
4610b57cec5SDimitry Andric   public:
4620b57cec5SDimitry Andric     explicit CGCapturedStmtInfo(CapturedRegionKind K = CR_Default)
4630b57cec5SDimitry Andric         : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {}
4640b57cec5SDimitry Andric     explicit CGCapturedStmtInfo(const CapturedStmt &S,
4650b57cec5SDimitry Andric                                 CapturedRegionKind K = CR_Default)
4660b57cec5SDimitry Andric       : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric       RecordDecl::field_iterator Field =
4690b57cec5SDimitry Andric         S.getCapturedRecordDecl()->field_begin();
4700b57cec5SDimitry Andric       for (CapturedStmt::const_capture_iterator I = S.capture_begin(),
4710b57cec5SDimitry Andric                                                 E = S.capture_end();
4720b57cec5SDimitry Andric            I != E; ++I, ++Field) {
4730b57cec5SDimitry Andric         if (I->capturesThis())
4740b57cec5SDimitry Andric           CXXThisFieldDecl = *Field;
4750b57cec5SDimitry Andric         else if (I->capturesVariable())
4760b57cec5SDimitry Andric           CaptureFields[I->getCapturedVar()->getCanonicalDecl()] = *Field;
4770b57cec5SDimitry Andric         else if (I->capturesVariableByCopy())
4780b57cec5SDimitry Andric           CaptureFields[I->getCapturedVar()->getCanonicalDecl()] = *Field;
4790b57cec5SDimitry Andric       }
4800b57cec5SDimitry Andric     }
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric     virtual ~CGCapturedStmtInfo();
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric     CapturedRegionKind getKind() const { return Kind; }
4850b57cec5SDimitry Andric 
4860b57cec5SDimitry Andric     virtual void setContextValue(llvm::Value *V) { ThisValue = V; }
4870b57cec5SDimitry Andric     // Retrieve the value of the context parameter.
4880b57cec5SDimitry Andric     virtual llvm::Value *getContextValue() const { return ThisValue; }
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric     /// Lookup the captured field decl for a variable.
4910b57cec5SDimitry Andric     virtual const FieldDecl *lookup(const VarDecl *VD) const {
4920b57cec5SDimitry Andric       return CaptureFields.lookup(VD->getCanonicalDecl());
4930b57cec5SDimitry Andric     }
4940b57cec5SDimitry Andric 
4950b57cec5SDimitry Andric     bool isCXXThisExprCaptured() const { return getThisFieldDecl() != nullptr; }
4960b57cec5SDimitry Andric     virtual FieldDecl *getThisFieldDecl() const { return CXXThisFieldDecl; }
4970b57cec5SDimitry Andric 
4980b57cec5SDimitry Andric     static bool classof(const CGCapturedStmtInfo *) {
4990b57cec5SDimitry Andric       return true;
5000b57cec5SDimitry Andric     }
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric     /// Emit the captured statement body.
5030b57cec5SDimitry Andric     virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S) {
5040b57cec5SDimitry Andric       CGF.incrementProfileCounter(S);
5050b57cec5SDimitry Andric       CGF.EmitStmt(S);
5060b57cec5SDimitry Andric     }
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric     /// Get the name of the capture helper.
5090b57cec5SDimitry Andric     virtual StringRef getHelperName() const { return "__captured_stmt"; }
5100b57cec5SDimitry Andric 
5110eae32dcSDimitry Andric     /// Get the CaptureFields
5120eae32dcSDimitry Andric     llvm::SmallDenseMap<const VarDecl *, FieldDecl *> getCaptureFields() {
5130eae32dcSDimitry Andric       return CaptureFields;
5140eae32dcSDimitry Andric     }
5150eae32dcSDimitry Andric 
5160b57cec5SDimitry Andric   private:
5170b57cec5SDimitry Andric     /// The kind of captured statement being generated.
5180b57cec5SDimitry Andric     CapturedRegionKind Kind;
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric     /// Keep the map between VarDecl and FieldDecl.
5210b57cec5SDimitry Andric     llvm::SmallDenseMap<const VarDecl *, FieldDecl *> CaptureFields;
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric     /// The base address of the captured record, passed in as the first
5240b57cec5SDimitry Andric     /// argument of the parallel region function.
5250b57cec5SDimitry Andric     llvm::Value *ThisValue;
5260b57cec5SDimitry Andric 
5270b57cec5SDimitry Andric     /// Captured 'this' type.
5280b57cec5SDimitry Andric     FieldDecl *CXXThisFieldDecl;
5290b57cec5SDimitry Andric   };
5300b57cec5SDimitry Andric   CGCapturedStmtInfo *CapturedStmtInfo = nullptr;
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric   /// RAII for correct setting/restoring of CapturedStmtInfo.
5330b57cec5SDimitry Andric   class CGCapturedStmtRAII {
5340b57cec5SDimitry Andric   private:
5350b57cec5SDimitry Andric     CodeGenFunction &CGF;
5360b57cec5SDimitry Andric     CGCapturedStmtInfo *PrevCapturedStmtInfo;
5370b57cec5SDimitry Andric   public:
5380b57cec5SDimitry Andric     CGCapturedStmtRAII(CodeGenFunction &CGF,
5390b57cec5SDimitry Andric                        CGCapturedStmtInfo *NewCapturedStmtInfo)
5400b57cec5SDimitry Andric         : CGF(CGF), PrevCapturedStmtInfo(CGF.CapturedStmtInfo) {
5410b57cec5SDimitry Andric       CGF.CapturedStmtInfo = NewCapturedStmtInfo;
5420b57cec5SDimitry Andric     }
5430b57cec5SDimitry Andric     ~CGCapturedStmtRAII() { CGF.CapturedStmtInfo = PrevCapturedStmtInfo; }
5440b57cec5SDimitry Andric   };
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric   /// An abstract representation of regular/ObjC call/message targets.
5470b57cec5SDimitry Andric   class AbstractCallee {
5480b57cec5SDimitry Andric     /// The function declaration of the callee.
5490b57cec5SDimitry Andric     const Decl *CalleeDecl;
5500b57cec5SDimitry Andric 
5510b57cec5SDimitry Andric   public:
5520b57cec5SDimitry Andric     AbstractCallee() : CalleeDecl(nullptr) {}
5530b57cec5SDimitry Andric     AbstractCallee(const FunctionDecl *FD) : CalleeDecl(FD) {}
5540b57cec5SDimitry Andric     AbstractCallee(const ObjCMethodDecl *OMD) : CalleeDecl(OMD) {}
5550b57cec5SDimitry Andric     bool hasFunctionDecl() const {
556349cc55cSDimitry Andric       return isa_and_nonnull<FunctionDecl>(CalleeDecl);
5570b57cec5SDimitry Andric     }
5580b57cec5SDimitry Andric     const Decl *getDecl() const { return CalleeDecl; }
5590b57cec5SDimitry Andric     unsigned getNumParams() const {
5600b57cec5SDimitry Andric       if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl))
5610b57cec5SDimitry Andric         return FD->getNumParams();
5620b57cec5SDimitry Andric       return cast<ObjCMethodDecl>(CalleeDecl)->param_size();
5630b57cec5SDimitry Andric     }
5640b57cec5SDimitry Andric     const ParmVarDecl *getParamDecl(unsigned I) const {
5650b57cec5SDimitry Andric       if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl))
5660b57cec5SDimitry Andric         return FD->getParamDecl(I);
5670b57cec5SDimitry Andric       return *(cast<ObjCMethodDecl>(CalleeDecl)->param_begin() + I);
5680b57cec5SDimitry Andric     }
5690b57cec5SDimitry Andric   };
5700b57cec5SDimitry Andric 
5710b57cec5SDimitry Andric   /// Sanitizers enabled for this function.
5720b57cec5SDimitry Andric   SanitizerSet SanOpts;
5730b57cec5SDimitry Andric 
5740b57cec5SDimitry Andric   /// True if CodeGen currently emits code implementing sanitizer checks.
5750b57cec5SDimitry Andric   bool IsSanitizerScope = false;
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric   /// RAII object to set/unset CodeGenFunction::IsSanitizerScope.
5780b57cec5SDimitry Andric   class SanitizerScope {
5790b57cec5SDimitry Andric     CodeGenFunction *CGF;
5800b57cec5SDimitry Andric   public:
5810b57cec5SDimitry Andric     SanitizerScope(CodeGenFunction *CGF);
5820b57cec5SDimitry Andric     ~SanitizerScope();
5830b57cec5SDimitry Andric   };
5840b57cec5SDimitry Andric 
5850b57cec5SDimitry Andric   /// In C++, whether we are code generating a thunk.  This controls whether we
5860b57cec5SDimitry Andric   /// should emit cleanups.
5870b57cec5SDimitry Andric   bool CurFuncIsThunk = false;
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric   /// In ARC, whether we should autorelease the return value.
5900b57cec5SDimitry Andric   bool AutoreleaseResult = false;
5910b57cec5SDimitry Andric 
5920b57cec5SDimitry Andric   /// Whether we processed a Microsoft-style asm block during CodeGen. These can
5930b57cec5SDimitry Andric   /// potentially set the return value.
5940b57cec5SDimitry Andric   bool SawAsmBlock = false;
5950b57cec5SDimitry Andric 
596bdd1243dSDimitry Andric   GlobalDecl CurSEHParent;
5970b57cec5SDimitry Andric 
5980b57cec5SDimitry Andric   /// True if the current function is an outlined SEH helper. This can be a
5990b57cec5SDimitry Andric   /// finally block or filter expression.
6000b57cec5SDimitry Andric   bool IsOutlinedSEHHelper = false;
6010b57cec5SDimitry Andric 
6020b57cec5SDimitry Andric   /// True if CodeGen currently emits code inside presereved access index
6030b57cec5SDimitry Andric   /// region.
6040b57cec5SDimitry Andric   bool IsInPreservedAIRegion = false;
6050b57cec5SDimitry Andric 
6065ffd83dbSDimitry Andric   /// True if the current statement has nomerge attribute.
6075ffd83dbSDimitry Andric   bool InNoMergeAttributedStmt = false;
6085ffd83dbSDimitry Andric 
60981ad6265SDimitry Andric   /// True if the current statement has noinline attribute.
61081ad6265SDimitry Andric   bool InNoInlineAttributedStmt = false;
61181ad6265SDimitry Andric 
61281ad6265SDimitry Andric   /// True if the current statement has always_inline attribute.
61381ad6265SDimitry Andric   bool InAlwaysInlineAttributedStmt = false;
61481ad6265SDimitry Andric 
615fe6060f1SDimitry Andric   // The CallExpr within the current statement that the musttail attribute
616fe6060f1SDimitry Andric   // applies to.  nullptr if there is no 'musttail' on the current statement.
617fe6060f1SDimitry Andric   const CallExpr *MustTailCall = nullptr;
618e8d8bef9SDimitry Andric 
619fe6060f1SDimitry Andric   /// Returns true if a function must make progress, which means the
620fe6060f1SDimitry Andric   /// mustprogress attribute can be added.
621fe6060f1SDimitry Andric   bool checkIfFunctionMustProgress() {
622d409305fSDimitry Andric     if (CGM.getCodeGenOpts().getFiniteLoops() ==
623d409305fSDimitry Andric         CodeGenOptions::FiniteLoopsKind::Never)
624d409305fSDimitry Andric       return false;
625d409305fSDimitry Andric 
626fe6060f1SDimitry Andric     // C++11 and later guarantees that a thread eventually will do one of the
627bdd1243dSDimitry Andric     // following (C++11 [intro.multithread]p24 and C++17 [intro.progress]p1):
628fe6060f1SDimitry Andric     // - terminate,
629fe6060f1SDimitry Andric     //  - make a call to a library I/O function,
630fe6060f1SDimitry Andric     //  - perform an access through a volatile glvalue, or
631fe6060f1SDimitry Andric     //  - perform a synchronization operation or an atomic operation.
632fe6060f1SDimitry Andric     //
633fe6060f1SDimitry Andric     // Hence each function is 'mustprogress' in C++11 or later.
634fe6060f1SDimitry Andric     return getLangOpts().CPlusPlus11;
635e8d8bef9SDimitry Andric   }
636e8d8bef9SDimitry Andric 
637fe6060f1SDimitry Andric   /// Returns true if a loop must make progress, which means the mustprogress
638fe6060f1SDimitry Andric   /// attribute can be added. \p HasConstantCond indicates whether the branch
639fe6060f1SDimitry Andric   /// condition is a known constant.
6400fca6ea1SDimitry Andric   bool checkIfLoopMustProgress(const Expr *, bool HasEmptyBody);
641e8d8bef9SDimitry Andric 
6420b57cec5SDimitry Andric   const CodeGen::CGBlockInfo *BlockInfo = nullptr;
6430b57cec5SDimitry Andric   llvm::Value *BlockPointer = nullptr;
6440b57cec5SDimitry Andric 
645bdd1243dSDimitry Andric   llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
6460b57cec5SDimitry Andric   FieldDecl *LambdaThisCaptureField = nullptr;
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric   /// A mapping from NRVO variables to the flags used to indicate
6490b57cec5SDimitry Andric   /// when the NRVO has been applied to this variable.
6500b57cec5SDimitry Andric   llvm::DenseMap<const VarDecl *, llvm::Value *> NRVOFlags;
6510b57cec5SDimitry Andric 
6520b57cec5SDimitry Andric   EHScopeStack EHStack;
6530b57cec5SDimitry Andric   llvm::SmallVector<char, 256> LifetimeExtendedCleanupStack;
6540fca6ea1SDimitry Andric 
6550fca6ea1SDimitry Andric   // A stack of cleanups which were added to EHStack but have to be deactivated
6560fca6ea1SDimitry Andric   // later before being popped or emitted. These are usually deactivated on
6570fca6ea1SDimitry Andric   // exiting a `CleanupDeactivationScope` scope. For instance, after a
6580fca6ea1SDimitry Andric   // full-expr.
6590fca6ea1SDimitry Andric   //
6600fca6ea1SDimitry Andric   // These are specially useful for correctly emitting cleanups while
6610fca6ea1SDimitry Andric   // encountering branches out of expression (through stmt-expr or coroutine
6620fca6ea1SDimitry Andric   // suspensions).
6630fca6ea1SDimitry Andric   struct DeferredDeactivateCleanup {
6640fca6ea1SDimitry Andric     EHScopeStack::stable_iterator Cleanup;
6650fca6ea1SDimitry Andric     llvm::Instruction *DominatingIP;
6660fca6ea1SDimitry Andric   };
6670fca6ea1SDimitry Andric   llvm::SmallVector<DeferredDeactivateCleanup> DeferredDeactivationCleanupStack;
6680fca6ea1SDimitry Andric 
6690fca6ea1SDimitry Andric   // Enters a new scope for capturing cleanups which are deferred to be
6700fca6ea1SDimitry Andric   // deactivated, all of which will be deactivated once the scope is exited.
6710fca6ea1SDimitry Andric   struct CleanupDeactivationScope {
6720fca6ea1SDimitry Andric     CodeGenFunction &CGF;
6730fca6ea1SDimitry Andric     size_t OldDeactivateCleanupStackSize;
6740fca6ea1SDimitry Andric     bool Deactivated;
6750fca6ea1SDimitry Andric     CleanupDeactivationScope(CodeGenFunction &CGF)
6760fca6ea1SDimitry Andric         : CGF(CGF), OldDeactivateCleanupStackSize(
6770fca6ea1SDimitry Andric                         CGF.DeferredDeactivationCleanupStack.size()),
6780fca6ea1SDimitry Andric           Deactivated(false) {}
6790fca6ea1SDimitry Andric 
6800fca6ea1SDimitry Andric     void ForceDeactivate() {
6810fca6ea1SDimitry Andric       assert(!Deactivated && "Deactivating already deactivated scope");
6820fca6ea1SDimitry Andric       auto &Stack = CGF.DeferredDeactivationCleanupStack;
6830fca6ea1SDimitry Andric       for (size_t I = Stack.size(); I > OldDeactivateCleanupStackSize; I--) {
6840fca6ea1SDimitry Andric         CGF.DeactivateCleanupBlock(Stack[I - 1].Cleanup,
6850fca6ea1SDimitry Andric                                    Stack[I - 1].DominatingIP);
6860fca6ea1SDimitry Andric         Stack[I - 1].DominatingIP->eraseFromParent();
6870fca6ea1SDimitry Andric       }
6880fca6ea1SDimitry Andric       Stack.resize(OldDeactivateCleanupStackSize);
6890fca6ea1SDimitry Andric       Deactivated = true;
6900fca6ea1SDimitry Andric     }
6910fca6ea1SDimitry Andric 
6920fca6ea1SDimitry Andric     ~CleanupDeactivationScope() {
6930fca6ea1SDimitry Andric       if (Deactivated)
6940fca6ea1SDimitry Andric         return;
6950fca6ea1SDimitry Andric       ForceDeactivate();
6960fca6ea1SDimitry Andric     }
6970fca6ea1SDimitry Andric   };
6980fca6ea1SDimitry Andric 
6990b57cec5SDimitry Andric   llvm::SmallVector<const JumpDest *, 2> SEHTryEpilogueStack;
7000b57cec5SDimitry Andric 
7010b57cec5SDimitry Andric   llvm::Instruction *CurrentFuncletPad = nullptr;
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric   class CallLifetimeEnd final : public EHScopeStack::Cleanup {
704fe6060f1SDimitry Andric     bool isRedundantBeforeReturn() override { return true; }
705fe6060f1SDimitry Andric 
7060b57cec5SDimitry Andric     llvm::Value *Addr;
7070b57cec5SDimitry Andric     llvm::Value *Size;
7080b57cec5SDimitry Andric 
7090b57cec5SDimitry Andric   public:
7100fca6ea1SDimitry Andric     CallLifetimeEnd(RawAddress addr, llvm::Value *size)
7110b57cec5SDimitry Andric         : Addr(addr.getPointer()), Size(size) {}
7120b57cec5SDimitry Andric 
7130b57cec5SDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
7140b57cec5SDimitry Andric       CGF.EmitLifetimeEnd(Size, Addr);
7150b57cec5SDimitry Andric     }
7160b57cec5SDimitry Andric   };
7170b57cec5SDimitry Andric 
7180b57cec5SDimitry Andric   /// Header for data within LifetimeExtendedCleanupStack.
7190b57cec5SDimitry Andric   struct LifetimeExtendedCleanupHeader {
7200b57cec5SDimitry Andric     /// The size of the following cleanup object.
7210b57cec5SDimitry Andric     unsigned Size;
7220fca6ea1SDimitry Andric     /// The kind of cleanup to push.
7230fca6ea1SDimitry Andric     LLVM_PREFERRED_TYPE(CleanupKind)
7240b57cec5SDimitry Andric     unsigned Kind : 31;
7250b57cec5SDimitry Andric     /// Whether this is a conditional cleanup.
7260fca6ea1SDimitry Andric     LLVM_PREFERRED_TYPE(bool)
7270b57cec5SDimitry Andric     unsigned IsConditional : 1;
7280b57cec5SDimitry Andric 
7290b57cec5SDimitry Andric     size_t getSize() const { return Size; }
7300b57cec5SDimitry Andric     CleanupKind getKind() const { return (CleanupKind)Kind; }
7310b57cec5SDimitry Andric     bool isConditional() const { return IsConditional; }
7320b57cec5SDimitry Andric   };
7330b57cec5SDimitry Andric 
7340b57cec5SDimitry Andric   /// i32s containing the indexes of the cleanup destinations.
7350fca6ea1SDimitry Andric   RawAddress NormalCleanupDest = RawAddress::invalid();
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric   unsigned NextCleanupDestIndex = 1;
7380b57cec5SDimitry Andric 
7390b57cec5SDimitry Andric   /// EHResumeBlock - Unified block containing a call to llvm.eh.resume.
7400b57cec5SDimitry Andric   llvm::BasicBlock *EHResumeBlock = nullptr;
7410b57cec5SDimitry Andric 
7420b57cec5SDimitry Andric   /// The exception slot.  All landing pads write the current exception pointer
7430b57cec5SDimitry Andric   /// into this alloca.
7440b57cec5SDimitry Andric   llvm::Value *ExceptionSlot = nullptr;
7450b57cec5SDimitry Andric 
7460b57cec5SDimitry Andric   /// The selector slot.  Under the MandatoryCleanup model, all landing pads
7470b57cec5SDimitry Andric   /// write the current selector value into this alloca.
7480b57cec5SDimitry Andric   llvm::AllocaInst *EHSelectorSlot = nullptr;
7490b57cec5SDimitry Andric 
7500b57cec5SDimitry Andric   /// A stack of exception code slots. Entering an __except block pushes a slot
7510b57cec5SDimitry Andric   /// on the stack and leaving pops one. The __exception_code() intrinsic loads
7520b57cec5SDimitry Andric   /// a value from the top of the stack.
7530b57cec5SDimitry Andric   SmallVector<Address, 1> SEHCodeSlotStack;
7540b57cec5SDimitry Andric 
7550b57cec5SDimitry Andric   /// Value returned by __exception_info intrinsic.
7560b57cec5SDimitry Andric   llvm::Value *SEHInfo = nullptr;
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric   /// Emits a landing pad for the current EH stack.
7590b57cec5SDimitry Andric   llvm::BasicBlock *EmitLandingPad();
7600b57cec5SDimitry Andric 
7610b57cec5SDimitry Andric   llvm::BasicBlock *getInvokeDestImpl();
7620b57cec5SDimitry Andric 
7635ffd83dbSDimitry Andric   /// Parent loop-based directive for scan directive.
7645ffd83dbSDimitry Andric   const OMPExecutableDirective *OMPParentLoopDirectiveForScan = nullptr;
7655ffd83dbSDimitry Andric   llvm::BasicBlock *OMPBeforeScanBlock = nullptr;
7665ffd83dbSDimitry Andric   llvm::BasicBlock *OMPAfterScanBlock = nullptr;
7675ffd83dbSDimitry Andric   llvm::BasicBlock *OMPScanExitBlock = nullptr;
7685ffd83dbSDimitry Andric   llvm::BasicBlock *OMPScanDispatch = nullptr;
7695ffd83dbSDimitry Andric   bool OMPFirstScanLoop = false;
7705ffd83dbSDimitry Andric 
7715ffd83dbSDimitry Andric   /// Manages parent directive for scan directives.
7725ffd83dbSDimitry Andric   class ParentLoopDirectiveForScanRegion {
7735ffd83dbSDimitry Andric     CodeGenFunction &CGF;
7745ffd83dbSDimitry Andric     const OMPExecutableDirective *ParentLoopDirectiveForScan;
7755ffd83dbSDimitry Andric 
7765ffd83dbSDimitry Andric   public:
7775ffd83dbSDimitry Andric     ParentLoopDirectiveForScanRegion(
7785ffd83dbSDimitry Andric         CodeGenFunction &CGF,
7795ffd83dbSDimitry Andric         const OMPExecutableDirective &ParentLoopDirectiveForScan)
7805ffd83dbSDimitry Andric         : CGF(CGF),
7815ffd83dbSDimitry Andric           ParentLoopDirectiveForScan(CGF.OMPParentLoopDirectiveForScan) {
7825ffd83dbSDimitry Andric       CGF.OMPParentLoopDirectiveForScan = &ParentLoopDirectiveForScan;
7835ffd83dbSDimitry Andric     }
7845ffd83dbSDimitry Andric     ~ParentLoopDirectiveForScanRegion() {
7855ffd83dbSDimitry Andric       CGF.OMPParentLoopDirectiveForScan = ParentLoopDirectiveForScan;
7865ffd83dbSDimitry Andric     }
7875ffd83dbSDimitry Andric   };
7885ffd83dbSDimitry Andric 
7890b57cec5SDimitry Andric   template <class T>
7900b57cec5SDimitry Andric   typename DominatingValue<T>::saved_type saveValueInCond(T value) {
7910b57cec5SDimitry Andric     return DominatingValue<T>::save(*this, value);
7920b57cec5SDimitry Andric   }
7930b57cec5SDimitry Andric 
7945ffd83dbSDimitry Andric   class CGFPOptionsRAII {
7955ffd83dbSDimitry Andric   public:
7965ffd83dbSDimitry Andric     CGFPOptionsRAII(CodeGenFunction &CGF, FPOptions FPFeatures);
797e8d8bef9SDimitry Andric     CGFPOptionsRAII(CodeGenFunction &CGF, const Expr *E);
7985ffd83dbSDimitry Andric     ~CGFPOptionsRAII();
7995ffd83dbSDimitry Andric 
8005ffd83dbSDimitry Andric   private:
801e8d8bef9SDimitry Andric     void ConstructorHelper(FPOptions FPFeatures);
8025ffd83dbSDimitry Andric     CodeGenFunction &CGF;
8035ffd83dbSDimitry Andric     FPOptions OldFPFeatures;
804e8d8bef9SDimitry Andric     llvm::fp::ExceptionBehavior OldExcept;
805e8d8bef9SDimitry Andric     llvm::RoundingMode OldRounding;
806bdd1243dSDimitry Andric     std::optional<CGBuilderTy::FastMathFlagGuard> FMFGuard;
8075ffd83dbSDimitry Andric   };
8085ffd83dbSDimitry Andric   FPOptions CurFPFeatures;
8095ffd83dbSDimitry Andric 
8100b57cec5SDimitry Andric public:
8110b57cec5SDimitry Andric   /// ObjCEHValueStack - Stack of Objective-C exception values, used for
8120b57cec5SDimitry Andric   /// rethrows.
8130b57cec5SDimitry Andric   SmallVector<llvm::Value*, 8> ObjCEHValueStack;
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric   /// A class controlling the emission of a finally block.
8160b57cec5SDimitry Andric   class FinallyInfo {
8170b57cec5SDimitry Andric     /// Where the catchall's edge through the cleanup should go.
8180b57cec5SDimitry Andric     JumpDest RethrowDest;
8190b57cec5SDimitry Andric 
8200b57cec5SDimitry Andric     /// A function to call to enter the catch.
8210b57cec5SDimitry Andric     llvm::FunctionCallee BeginCatchFn;
8220b57cec5SDimitry Andric 
8230b57cec5SDimitry Andric     /// An i1 variable indicating whether or not the @finally is
8240b57cec5SDimitry Andric     /// running for an exception.
82506c3fb27SDimitry Andric     llvm::AllocaInst *ForEHVar = nullptr;
8260b57cec5SDimitry Andric 
8270b57cec5SDimitry Andric     /// An i8* variable into which the exception pointer to rethrow
8280b57cec5SDimitry Andric     /// has been saved.
82906c3fb27SDimitry Andric     llvm::AllocaInst *SavedExnVar = nullptr;
8300b57cec5SDimitry Andric 
8310b57cec5SDimitry Andric   public:
8320b57cec5SDimitry Andric     void enter(CodeGenFunction &CGF, const Stmt *Finally,
8330b57cec5SDimitry Andric                llvm::FunctionCallee beginCatchFn,
8340b57cec5SDimitry Andric                llvm::FunctionCallee endCatchFn, llvm::FunctionCallee rethrowFn);
8350b57cec5SDimitry Andric     void exit(CodeGenFunction &CGF);
8360b57cec5SDimitry Andric   };
8370b57cec5SDimitry Andric 
8380b57cec5SDimitry Andric   /// Returns true inside SEH __try blocks.
8390b57cec5SDimitry Andric   bool isSEHTryScope() const { return !SEHTryEpilogueStack.empty(); }
8400b57cec5SDimitry Andric 
8410b57cec5SDimitry Andric   /// Returns true while emitting a cleanuppad.
8420b57cec5SDimitry Andric   bool isCleanupPadScope() const {
8430b57cec5SDimitry Andric     return CurrentFuncletPad && isa<llvm::CleanupPadInst>(CurrentFuncletPad);
8440b57cec5SDimitry Andric   }
8450b57cec5SDimitry Andric 
8460b57cec5SDimitry Andric   /// pushFullExprCleanup - Push a cleanup to be run at the end of the
8470b57cec5SDimitry Andric   /// current full-expression.  Safe against the possibility that
8480b57cec5SDimitry Andric   /// we're currently inside a conditionally-evaluated expression.
8490b57cec5SDimitry Andric   template <class T, class... As>
8500b57cec5SDimitry Andric   void pushFullExprCleanup(CleanupKind kind, As... A) {
8510b57cec5SDimitry Andric     // If we're not in a conditional branch, or if none of the
8520b57cec5SDimitry Andric     // arguments requires saving, then use the unconditional cleanup.
8530b57cec5SDimitry Andric     if (!isInConditionalBranch())
8540b57cec5SDimitry Andric       return EHStack.pushCleanup<T>(kind, A...);
8550b57cec5SDimitry Andric 
8560b57cec5SDimitry Andric     // Stash values in a tuple so we can guarantee the order of saves.
8570b57cec5SDimitry Andric     typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple;
8580b57cec5SDimitry Andric     SavedTuple Saved{saveValueInCond(A)...};
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric     typedef EHScopeStack::ConditionalCleanup<T, As...> CleanupType;
8610b57cec5SDimitry Andric     EHStack.pushCleanupTuple<CleanupType>(kind, Saved);
8620b57cec5SDimitry Andric     initFullExprCleanup();
8630b57cec5SDimitry Andric   }
8640b57cec5SDimitry Andric 
865e8d8bef9SDimitry Andric   /// Queue a cleanup to be pushed after finishing the current full-expression,
866e8d8bef9SDimitry Andric   /// potentially with an active flag.
8670b57cec5SDimitry Andric   template <class T, class... As>
8680b57cec5SDimitry Andric   void pushCleanupAfterFullExpr(CleanupKind Kind, As... A) {
8690b57cec5SDimitry Andric     if (!isInConditionalBranch())
8700fca6ea1SDimitry Andric       return pushCleanupAfterFullExprWithActiveFlag<T>(
8710fca6ea1SDimitry Andric           Kind, RawAddress::invalid(), A...);
8720b57cec5SDimitry Andric 
8730fca6ea1SDimitry Andric     RawAddress ActiveFlag = createCleanupActiveFlag();
8740b57cec5SDimitry Andric     assert(!DominatingValue<Address>::needsSaving(ActiveFlag) &&
8750b57cec5SDimitry Andric            "cleanup active flag should never need saving");
8760b57cec5SDimitry Andric 
8770b57cec5SDimitry Andric     typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple;
8780b57cec5SDimitry Andric     SavedTuple Saved{saveValueInCond(A)...};
8790b57cec5SDimitry Andric 
8800b57cec5SDimitry Andric     typedef EHScopeStack::ConditionalCleanup<T, As...> CleanupType;
881e8d8bef9SDimitry Andric     pushCleanupAfterFullExprWithActiveFlag<CleanupType>(Kind, ActiveFlag, Saved);
8820b57cec5SDimitry Andric   }
8830b57cec5SDimitry Andric 
8840b57cec5SDimitry Andric   template <class T, class... As>
885e8d8bef9SDimitry Andric   void pushCleanupAfterFullExprWithActiveFlag(CleanupKind Kind,
8860fca6ea1SDimitry Andric                                               RawAddress ActiveFlag, As... A) {
8870b57cec5SDimitry Andric     LifetimeExtendedCleanupHeader Header = {sizeof(T), Kind,
8880b57cec5SDimitry Andric                                             ActiveFlag.isValid()};
8890b57cec5SDimitry Andric 
8900b57cec5SDimitry Andric     size_t OldSize = LifetimeExtendedCleanupStack.size();
8910b57cec5SDimitry Andric     LifetimeExtendedCleanupStack.resize(
8920b57cec5SDimitry Andric         LifetimeExtendedCleanupStack.size() + sizeof(Header) + Header.Size +
8930b57cec5SDimitry Andric         (Header.IsConditional ? sizeof(ActiveFlag) : 0));
8940b57cec5SDimitry Andric 
8950b57cec5SDimitry Andric     static_assert(sizeof(Header) % alignof(T) == 0,
8960b57cec5SDimitry Andric                   "Cleanup will be allocated on misaligned address");
8970b57cec5SDimitry Andric     char *Buffer = &LifetimeExtendedCleanupStack[OldSize];
8980b57cec5SDimitry Andric     new (Buffer) LifetimeExtendedCleanupHeader(Header);
8990b57cec5SDimitry Andric     new (Buffer + sizeof(Header)) T(A...);
9000b57cec5SDimitry Andric     if (Header.IsConditional)
9010fca6ea1SDimitry Andric       new (Buffer + sizeof(Header) + sizeof(T)) RawAddress(ActiveFlag);
9020fca6ea1SDimitry Andric   }
9030fca6ea1SDimitry Andric 
9040fca6ea1SDimitry Andric   // Push a cleanup onto EHStack and deactivate it later. It is usually
9050fca6ea1SDimitry Andric   // deactivated when exiting a `CleanupDeactivationScope` (for example: after a
9060fca6ea1SDimitry Andric   // full expression).
9070fca6ea1SDimitry Andric   template <class T, class... As>
9080fca6ea1SDimitry Andric   void pushCleanupAndDeferDeactivation(CleanupKind Kind, As... A) {
9090fca6ea1SDimitry Andric     // Placeholder dominating IP for this cleanup.
9100fca6ea1SDimitry Andric     llvm::Instruction *DominatingIP =
9110fca6ea1SDimitry Andric         Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy));
9120fca6ea1SDimitry Andric     EHStack.pushCleanup<T>(Kind, A...);
9130fca6ea1SDimitry Andric     DeferredDeactivationCleanupStack.push_back(
9140fca6ea1SDimitry Andric         {EHStack.stable_begin(), DominatingIP});
9150b57cec5SDimitry Andric   }
9160b57cec5SDimitry Andric 
9170b57cec5SDimitry Andric   /// Set up the last cleanup that was pushed as a conditional
9180b57cec5SDimitry Andric   /// full-expression cleanup.
9190b57cec5SDimitry Andric   void initFullExprCleanup() {
9200b57cec5SDimitry Andric     initFullExprCleanupWithFlag(createCleanupActiveFlag());
9210b57cec5SDimitry Andric   }
9220b57cec5SDimitry Andric 
9230fca6ea1SDimitry Andric   void initFullExprCleanupWithFlag(RawAddress ActiveFlag);
9240fca6ea1SDimitry Andric   RawAddress createCleanupActiveFlag();
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric   /// PushDestructorCleanup - Push a cleanup to call the
9270b57cec5SDimitry Andric   /// complete-object destructor of an object of the given type at the
9280b57cec5SDimitry Andric   /// given address.  Does nothing if T is not a C++ class type with a
9290b57cec5SDimitry Andric   /// non-trivial destructor.
9300b57cec5SDimitry Andric   void PushDestructorCleanup(QualType T, Address Addr);
9310b57cec5SDimitry Andric 
9320b57cec5SDimitry Andric   /// PushDestructorCleanup - Push a cleanup to call the
9330b57cec5SDimitry Andric   /// complete-object variant of the given destructor on the object at
9340b57cec5SDimitry Andric   /// the given address.
9350b57cec5SDimitry Andric   void PushDestructorCleanup(const CXXDestructorDecl *Dtor, QualType T,
9360b57cec5SDimitry Andric                              Address Addr);
9370b57cec5SDimitry Andric 
9380b57cec5SDimitry Andric   /// PopCleanupBlock - Will pop the cleanup entry on the stack and
9390b57cec5SDimitry Andric   /// process all branch fixups.
9400fca6ea1SDimitry Andric   void PopCleanupBlock(bool FallThroughIsBranchThrough = false,
9410fca6ea1SDimitry Andric                        bool ForDeactivation = false);
9420b57cec5SDimitry Andric 
9430b57cec5SDimitry Andric   /// DeactivateCleanupBlock - Deactivates the given cleanup block.
9440b57cec5SDimitry Andric   /// The block cannot be reactivated.  Pops it if it's the top of the
9450b57cec5SDimitry Andric   /// stack.
9460b57cec5SDimitry Andric   ///
9470b57cec5SDimitry Andric   /// \param DominatingIP - An instruction which is known to
9480b57cec5SDimitry Andric   ///   dominate the current IP (if set) and which lies along
9490b57cec5SDimitry Andric   ///   all paths of execution between the current IP and the
9500b57cec5SDimitry Andric   ///   the point at which the cleanup comes into scope.
9510b57cec5SDimitry Andric   void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup,
9520b57cec5SDimitry Andric                               llvm::Instruction *DominatingIP);
9530b57cec5SDimitry Andric 
9540b57cec5SDimitry Andric   /// ActivateCleanupBlock - Activates an initially-inactive cleanup.
9550b57cec5SDimitry Andric   /// Cannot be used to resurrect a deactivated cleanup.
9560b57cec5SDimitry Andric   ///
9570b57cec5SDimitry Andric   /// \param DominatingIP - An instruction which is known to
9580b57cec5SDimitry Andric   ///   dominate the current IP (if set) and which lies along
9590b57cec5SDimitry Andric   ///   all paths of execution between the current IP and the
9600b57cec5SDimitry Andric   ///   the point at which the cleanup comes into scope.
9610b57cec5SDimitry Andric   void ActivateCleanupBlock(EHScopeStack::stable_iterator Cleanup,
9620b57cec5SDimitry Andric                             llvm::Instruction *DominatingIP);
9630b57cec5SDimitry Andric 
9640b57cec5SDimitry Andric   /// Enters a new scope for capturing cleanups, all of which
9650b57cec5SDimitry Andric   /// will be executed once the scope is exited.
9660b57cec5SDimitry Andric   class RunCleanupsScope {
9670b57cec5SDimitry Andric     EHScopeStack::stable_iterator CleanupStackDepth, OldCleanupScopeDepth;
9680b57cec5SDimitry Andric     size_t LifetimeExtendedCleanupStackSize;
9690fca6ea1SDimitry Andric     CleanupDeactivationScope DeactivateCleanups;
9700b57cec5SDimitry Andric     bool OldDidCallStackSave;
9710b57cec5SDimitry Andric   protected:
9720b57cec5SDimitry Andric     bool PerformCleanup;
9730b57cec5SDimitry Andric   private:
9740b57cec5SDimitry Andric 
9750b57cec5SDimitry Andric     RunCleanupsScope(const RunCleanupsScope &) = delete;
9760b57cec5SDimitry Andric     void operator=(const RunCleanupsScope &) = delete;
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric   protected:
9790b57cec5SDimitry Andric     CodeGenFunction& CGF;
9800b57cec5SDimitry Andric 
9810b57cec5SDimitry Andric   public:
9820b57cec5SDimitry Andric     /// Enter a new cleanup scope.
9830b57cec5SDimitry Andric     explicit RunCleanupsScope(CodeGenFunction &CGF)
9840fca6ea1SDimitry Andric         : DeactivateCleanups(CGF), PerformCleanup(true), CGF(CGF) {
9850b57cec5SDimitry Andric       CleanupStackDepth = CGF.EHStack.stable_begin();
9860b57cec5SDimitry Andric       LifetimeExtendedCleanupStackSize =
9870b57cec5SDimitry Andric           CGF.LifetimeExtendedCleanupStack.size();
9880b57cec5SDimitry Andric       OldDidCallStackSave = CGF.DidCallStackSave;
9890b57cec5SDimitry Andric       CGF.DidCallStackSave = false;
9900b57cec5SDimitry Andric       OldCleanupScopeDepth = CGF.CurrentCleanupScopeDepth;
9910b57cec5SDimitry Andric       CGF.CurrentCleanupScopeDepth = CleanupStackDepth;
9920b57cec5SDimitry Andric     }
9930b57cec5SDimitry Andric 
9940b57cec5SDimitry Andric     /// Exit this cleanup scope, emitting any accumulated cleanups.
9950b57cec5SDimitry Andric     ~RunCleanupsScope() {
9960b57cec5SDimitry Andric       if (PerformCleanup)
9970b57cec5SDimitry Andric         ForceCleanup();
9980b57cec5SDimitry Andric     }
9990b57cec5SDimitry Andric 
10000b57cec5SDimitry Andric     /// Determine whether this scope requires any cleanups.
10010b57cec5SDimitry Andric     bool requiresCleanups() const {
10020b57cec5SDimitry Andric       return CGF.EHStack.stable_begin() != CleanupStackDepth;
10030b57cec5SDimitry Andric     }
10040b57cec5SDimitry Andric 
10050b57cec5SDimitry Andric     /// Force the emission of cleanups now, instead of waiting
10060b57cec5SDimitry Andric     /// until this object is destroyed.
10070b57cec5SDimitry Andric     /// \param ValuesToReload - A list of values that need to be available at
10080b57cec5SDimitry Andric     /// the insertion point after cleanup emission. If cleanup emission created
10090b57cec5SDimitry Andric     /// a shared cleanup block, these value pointers will be rewritten.
10100b57cec5SDimitry Andric     /// Otherwise, they not will be modified.
10110b57cec5SDimitry Andric     void ForceCleanup(std::initializer_list<llvm::Value**> ValuesToReload = {}) {
10120b57cec5SDimitry Andric       assert(PerformCleanup && "Already forced cleanup");
10130b57cec5SDimitry Andric       CGF.DidCallStackSave = OldDidCallStackSave;
10140fca6ea1SDimitry Andric       DeactivateCleanups.ForceDeactivate();
10150b57cec5SDimitry Andric       CGF.PopCleanupBlocks(CleanupStackDepth, LifetimeExtendedCleanupStackSize,
10160b57cec5SDimitry Andric                            ValuesToReload);
10170b57cec5SDimitry Andric       PerformCleanup = false;
10180b57cec5SDimitry Andric       CGF.CurrentCleanupScopeDepth = OldCleanupScopeDepth;
10190b57cec5SDimitry Andric     }
10200b57cec5SDimitry Andric   };
10210b57cec5SDimitry Andric 
10220b57cec5SDimitry Andric   // Cleanup stack depth of the RunCleanupsScope that was pushed most recently.
10230b57cec5SDimitry Andric   EHScopeStack::stable_iterator CurrentCleanupScopeDepth =
10240b57cec5SDimitry Andric       EHScopeStack::stable_end();
10250b57cec5SDimitry Andric 
10260b57cec5SDimitry Andric   class LexicalScope : public RunCleanupsScope {
10270b57cec5SDimitry Andric     SourceRange Range;
10280b57cec5SDimitry Andric     SmallVector<const LabelDecl*, 4> Labels;
10290b57cec5SDimitry Andric     LexicalScope *ParentScope;
10300b57cec5SDimitry Andric 
10310b57cec5SDimitry Andric     LexicalScope(const LexicalScope &) = delete;
10320b57cec5SDimitry Andric     void operator=(const LexicalScope &) = delete;
10330b57cec5SDimitry Andric 
10340b57cec5SDimitry Andric   public:
10350b57cec5SDimitry Andric     /// Enter a new cleanup scope.
10360b57cec5SDimitry Andric     explicit LexicalScope(CodeGenFunction &CGF, SourceRange Range)
10370b57cec5SDimitry Andric       : RunCleanupsScope(CGF), Range(Range), ParentScope(CGF.CurLexicalScope) {
10380b57cec5SDimitry Andric       CGF.CurLexicalScope = this;
10390b57cec5SDimitry Andric       if (CGDebugInfo *DI = CGF.getDebugInfo())
10400b57cec5SDimitry Andric         DI->EmitLexicalBlockStart(CGF.Builder, Range.getBegin());
10410b57cec5SDimitry Andric     }
10420b57cec5SDimitry Andric 
10430b57cec5SDimitry Andric     void addLabel(const LabelDecl *label) {
10440b57cec5SDimitry Andric       assert(PerformCleanup && "adding label to dead scope?");
10450b57cec5SDimitry Andric       Labels.push_back(label);
10460b57cec5SDimitry Andric     }
10470b57cec5SDimitry Andric 
10480b57cec5SDimitry Andric     /// Exit this cleanup scope, emitting any accumulated
10490b57cec5SDimitry Andric     /// cleanups.
10500b57cec5SDimitry Andric     ~LexicalScope() {
10510b57cec5SDimitry Andric       if (CGDebugInfo *DI = CGF.getDebugInfo())
10520b57cec5SDimitry Andric         DI->EmitLexicalBlockEnd(CGF.Builder, Range.getEnd());
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric       // If we should perform a cleanup, force them now.  Note that
10550b57cec5SDimitry Andric       // this ends the cleanup scope before rescoping any labels.
10560b57cec5SDimitry Andric       if (PerformCleanup) {
10570b57cec5SDimitry Andric         ApplyDebugLocation DL(CGF, Range.getEnd());
10580b57cec5SDimitry Andric         ForceCleanup();
10590b57cec5SDimitry Andric       }
10600b57cec5SDimitry Andric     }
10610b57cec5SDimitry Andric 
10620b57cec5SDimitry Andric     /// Force the emission of cleanups now, instead of waiting
10630b57cec5SDimitry Andric     /// until this object is destroyed.
10640b57cec5SDimitry Andric     void ForceCleanup() {
10650b57cec5SDimitry Andric       CGF.CurLexicalScope = ParentScope;
10660b57cec5SDimitry Andric       RunCleanupsScope::ForceCleanup();
10670b57cec5SDimitry Andric 
10680b57cec5SDimitry Andric       if (!Labels.empty())
10690b57cec5SDimitry Andric         rescopeLabels();
10700b57cec5SDimitry Andric     }
10710b57cec5SDimitry Andric 
10720b57cec5SDimitry Andric     bool hasLabels() const {
10730b57cec5SDimitry Andric       return !Labels.empty();
10740b57cec5SDimitry Andric     }
10750b57cec5SDimitry Andric 
10760b57cec5SDimitry Andric     void rescopeLabels();
10770b57cec5SDimitry Andric   };
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric   typedef llvm::DenseMap<const Decl *, Address> DeclMapTy;
10800b57cec5SDimitry Andric 
10810b57cec5SDimitry Andric   /// The class used to assign some variables some temporarily addresses.
10820b57cec5SDimitry Andric   class OMPMapVars {
10830b57cec5SDimitry Andric     DeclMapTy SavedLocals;
10840b57cec5SDimitry Andric     DeclMapTy SavedTempAddresses;
10850b57cec5SDimitry Andric     OMPMapVars(const OMPMapVars &) = delete;
10860b57cec5SDimitry Andric     void operator=(const OMPMapVars &) = delete;
10870b57cec5SDimitry Andric 
10880b57cec5SDimitry Andric   public:
10890b57cec5SDimitry Andric     explicit OMPMapVars() = default;
10900b57cec5SDimitry Andric     ~OMPMapVars() {
10910b57cec5SDimitry Andric       assert(SavedLocals.empty() && "Did not restored original addresses.");
10920b57cec5SDimitry Andric     };
10930b57cec5SDimitry Andric 
10940b57cec5SDimitry Andric     /// Sets the address of the variable \p LocalVD to be \p TempAddr in
10950b57cec5SDimitry Andric     /// function \p CGF.
10960b57cec5SDimitry Andric     /// \return true if at least one variable was set already, false otherwise.
10970b57cec5SDimitry Andric     bool setVarAddr(CodeGenFunction &CGF, const VarDecl *LocalVD,
10980b57cec5SDimitry Andric                     Address TempAddr) {
10990b57cec5SDimitry Andric       LocalVD = LocalVD->getCanonicalDecl();
11000b57cec5SDimitry Andric       // Only save it once.
11010b57cec5SDimitry Andric       if (SavedLocals.count(LocalVD)) return false;
11020b57cec5SDimitry Andric 
11030b57cec5SDimitry Andric       // Copy the existing local entry to SavedLocals.
11040b57cec5SDimitry Andric       auto it = CGF.LocalDeclMap.find(LocalVD);
11050b57cec5SDimitry Andric       if (it != CGF.LocalDeclMap.end())
11060b57cec5SDimitry Andric         SavedLocals.try_emplace(LocalVD, it->second);
11070b57cec5SDimitry Andric       else
11080b57cec5SDimitry Andric         SavedLocals.try_emplace(LocalVD, Address::invalid());
11090b57cec5SDimitry Andric 
11100b57cec5SDimitry Andric       // Generate the private entry.
11110b57cec5SDimitry Andric       QualType VarTy = LocalVD->getType();
11120b57cec5SDimitry Andric       if (VarTy->isReferenceType()) {
11130b57cec5SDimitry Andric         Address Temp = CGF.CreateMemTemp(VarTy);
11140fca6ea1SDimitry Andric         CGF.Builder.CreateStore(TempAddr.emitRawPointer(CGF), Temp);
11150b57cec5SDimitry Andric         TempAddr = Temp;
11160b57cec5SDimitry Andric       }
11170b57cec5SDimitry Andric       SavedTempAddresses.try_emplace(LocalVD, TempAddr);
11180b57cec5SDimitry Andric 
11190b57cec5SDimitry Andric       return true;
11200b57cec5SDimitry Andric     }
11210b57cec5SDimitry Andric 
11220b57cec5SDimitry Andric     /// Applies new addresses to the list of the variables.
11230b57cec5SDimitry Andric     /// \return true if at least one variable is using new address, false
11240b57cec5SDimitry Andric     /// otherwise.
11250b57cec5SDimitry Andric     bool apply(CodeGenFunction &CGF) {
11260b57cec5SDimitry Andric       copyInto(SavedTempAddresses, CGF.LocalDeclMap);
11270b57cec5SDimitry Andric       SavedTempAddresses.clear();
11280b57cec5SDimitry Andric       return !SavedLocals.empty();
11290b57cec5SDimitry Andric     }
11300b57cec5SDimitry Andric 
11310b57cec5SDimitry Andric     /// Restores original addresses of the variables.
11320b57cec5SDimitry Andric     void restore(CodeGenFunction &CGF) {
11330b57cec5SDimitry Andric       if (!SavedLocals.empty()) {
11340b57cec5SDimitry Andric         copyInto(SavedLocals, CGF.LocalDeclMap);
11350b57cec5SDimitry Andric         SavedLocals.clear();
11360b57cec5SDimitry Andric       }
11370b57cec5SDimitry Andric     }
11380b57cec5SDimitry Andric 
11390b57cec5SDimitry Andric   private:
11400b57cec5SDimitry Andric     /// Copy all the entries in the source map over the corresponding
11410b57cec5SDimitry Andric     /// entries in the destination, which must exist.
11420b57cec5SDimitry Andric     static void copyInto(const DeclMapTy &Src, DeclMapTy &Dest) {
11430b57cec5SDimitry Andric       for (auto &Pair : Src) {
11440b57cec5SDimitry Andric         if (!Pair.second.isValid()) {
11450b57cec5SDimitry Andric           Dest.erase(Pair.first);
11460b57cec5SDimitry Andric           continue;
11470b57cec5SDimitry Andric         }
11480b57cec5SDimitry Andric 
11490b57cec5SDimitry Andric         auto I = Dest.find(Pair.first);
11500b57cec5SDimitry Andric         if (I != Dest.end())
11510b57cec5SDimitry Andric           I->second = Pair.second;
11520b57cec5SDimitry Andric         else
11530b57cec5SDimitry Andric           Dest.insert(Pair);
11540b57cec5SDimitry Andric       }
11550b57cec5SDimitry Andric     }
11560b57cec5SDimitry Andric   };
11570b57cec5SDimitry Andric 
11580b57cec5SDimitry Andric   /// The scope used to remap some variables as private in the OpenMP loop body
11590b57cec5SDimitry Andric   /// (or other captured region emitted without outlining), and to restore old
11600b57cec5SDimitry Andric   /// vars back on exit.
11610b57cec5SDimitry Andric   class OMPPrivateScope : public RunCleanupsScope {
11620b57cec5SDimitry Andric     OMPMapVars MappedVars;
11630b57cec5SDimitry Andric     OMPPrivateScope(const OMPPrivateScope &) = delete;
11640b57cec5SDimitry Andric     void operator=(const OMPPrivateScope &) = delete;
11650b57cec5SDimitry Andric 
11660b57cec5SDimitry Andric   public:
11670b57cec5SDimitry Andric     /// Enter a new OpenMP private scope.
11680b57cec5SDimitry Andric     explicit OMPPrivateScope(CodeGenFunction &CGF) : RunCleanupsScope(CGF) {}
11690b57cec5SDimitry Andric 
117081ad6265SDimitry Andric     /// Registers \p LocalVD variable as a private with \p Addr as the address
117181ad6265SDimitry Andric     /// of the corresponding private variable. \p
117281ad6265SDimitry Andric     /// PrivateGen is the address of the generated private variable.
11730b57cec5SDimitry Andric     /// \return true if the variable is registered as private, false if it has
11740b57cec5SDimitry Andric     /// been privatized already.
117581ad6265SDimitry Andric     bool addPrivate(const VarDecl *LocalVD, Address Addr) {
11760b57cec5SDimitry Andric       assert(PerformCleanup && "adding private to dead scope");
117781ad6265SDimitry Andric       return MappedVars.setVarAddr(CGF, LocalVD, Addr);
11780b57cec5SDimitry Andric     }
11790b57cec5SDimitry Andric 
11800b57cec5SDimitry Andric     /// Privatizes local variables previously registered as private.
11810b57cec5SDimitry Andric     /// Registration is separate from the actual privatization to allow
11820b57cec5SDimitry Andric     /// initializers use values of the original variables, not the private one.
11830b57cec5SDimitry Andric     /// This is important, for example, if the private variable is a class
11840b57cec5SDimitry Andric     /// variable initialized by a constructor that references other private
11850b57cec5SDimitry Andric     /// variables. But at initialization original variables must be used, not
11860b57cec5SDimitry Andric     /// private copies.
11870b57cec5SDimitry Andric     /// \return true if at least one variable was privatized, false otherwise.
11880b57cec5SDimitry Andric     bool Privatize() { return MappedVars.apply(CGF); }
11890b57cec5SDimitry Andric 
11900b57cec5SDimitry Andric     void ForceCleanup() {
11910b57cec5SDimitry Andric       RunCleanupsScope::ForceCleanup();
1192a4a491e2SDimitry Andric       restoreMap();
11930b57cec5SDimitry Andric     }
11940b57cec5SDimitry Andric 
11950b57cec5SDimitry Andric     /// Exit scope - all the mapped variables are restored.
11960b57cec5SDimitry Andric     ~OMPPrivateScope() {
11970b57cec5SDimitry Andric       if (PerformCleanup)
11980b57cec5SDimitry Andric         ForceCleanup();
11990b57cec5SDimitry Andric     }
12000b57cec5SDimitry Andric 
12010b57cec5SDimitry Andric     /// Checks if the global variable is captured in current function.
12020b57cec5SDimitry Andric     bool isGlobalVarCaptured(const VarDecl *VD) const {
12030b57cec5SDimitry Andric       VD = VD->getCanonicalDecl();
12040b57cec5SDimitry Andric       return !VD->isLocalVarDeclOrParm() && CGF.LocalDeclMap.count(VD) > 0;
12050b57cec5SDimitry Andric     }
1206a4a491e2SDimitry Andric 
1207a4a491e2SDimitry Andric     /// Restore all mapped variables w/o clean up. This is usefully when we want
1208a4a491e2SDimitry Andric     /// to reference the original variables but don't want the clean up because
1209a4a491e2SDimitry Andric     /// that could emit lifetime end too early, causing backend issue #56913.
1210a4a491e2SDimitry Andric     void restoreMap() { MappedVars.restore(CGF); }
12110b57cec5SDimitry Andric   };
12120b57cec5SDimitry Andric 
1213480093f4SDimitry Andric   /// Save/restore original map of previously emitted local vars in case when we
1214480093f4SDimitry Andric   /// need to duplicate emission of the same code several times in the same
1215480093f4SDimitry Andric   /// function for OpenMP code.
1216480093f4SDimitry Andric   class OMPLocalDeclMapRAII {
1217480093f4SDimitry Andric     CodeGenFunction &CGF;
1218480093f4SDimitry Andric     DeclMapTy SavedMap;
1219480093f4SDimitry Andric 
1220480093f4SDimitry Andric   public:
1221480093f4SDimitry Andric     OMPLocalDeclMapRAII(CodeGenFunction &CGF)
1222480093f4SDimitry Andric         : CGF(CGF), SavedMap(CGF.LocalDeclMap) {}
1223480093f4SDimitry Andric     ~OMPLocalDeclMapRAII() { SavedMap.swap(CGF.LocalDeclMap); }
1224480093f4SDimitry Andric   };
1225480093f4SDimitry Andric 
12260b57cec5SDimitry Andric   /// Takes the old cleanup stack size and emits the cleanup blocks
12270b57cec5SDimitry Andric   /// that have been added.
12280b57cec5SDimitry Andric   void
12290b57cec5SDimitry Andric   PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize,
12300b57cec5SDimitry Andric                    std::initializer_list<llvm::Value **> ValuesToReload = {});
12310b57cec5SDimitry Andric 
12320b57cec5SDimitry Andric   /// Takes the old cleanup stack size and emits the cleanup blocks
12330b57cec5SDimitry Andric   /// that have been added, then adds all lifetime-extended cleanups from
12340b57cec5SDimitry Andric   /// the given position to the stack.
12350b57cec5SDimitry Andric   void
12360b57cec5SDimitry Andric   PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize,
12370b57cec5SDimitry Andric                    size_t OldLifetimeExtendedStackSize,
12380b57cec5SDimitry Andric                    std::initializer_list<llvm::Value **> ValuesToReload = {});
12390b57cec5SDimitry Andric 
12400b57cec5SDimitry Andric   void ResolveBranchFixups(llvm::BasicBlock *Target);
12410b57cec5SDimitry Andric 
12420b57cec5SDimitry Andric   /// The given basic block lies in the current EH scope, but may be a
12430b57cec5SDimitry Andric   /// target of a potentially scope-crossing jump; get a stable handle
12440b57cec5SDimitry Andric   /// to which we can perform this jump later.
12450b57cec5SDimitry Andric   JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target) {
12460b57cec5SDimitry Andric     return JumpDest(Target,
12470b57cec5SDimitry Andric                     EHStack.getInnermostNormalCleanup(),
12480b57cec5SDimitry Andric                     NextCleanupDestIndex++);
12490b57cec5SDimitry Andric   }
12500b57cec5SDimitry Andric 
12510b57cec5SDimitry Andric   /// The given basic block lies in the current EH scope, but may be a
12520b57cec5SDimitry Andric   /// target of a potentially scope-crossing jump; get a stable handle
12530b57cec5SDimitry Andric   /// to which we can perform this jump later.
12540b57cec5SDimitry Andric   JumpDest getJumpDestInCurrentScope(StringRef Name = StringRef()) {
12550b57cec5SDimitry Andric     return getJumpDestInCurrentScope(createBasicBlock(Name));
12560b57cec5SDimitry Andric   }
12570b57cec5SDimitry Andric 
12580b57cec5SDimitry Andric   /// EmitBranchThroughCleanup - Emit a branch from the current insert
12590b57cec5SDimitry Andric   /// block through the normal cleanup handling code (if any) and then
12600b57cec5SDimitry Andric   /// on to \arg Dest.
12610b57cec5SDimitry Andric   void EmitBranchThroughCleanup(JumpDest Dest);
12620b57cec5SDimitry Andric 
12630b57cec5SDimitry Andric   /// isObviouslyBranchWithoutCleanups - Return true if a branch to the
12640b57cec5SDimitry Andric   /// specified destination obviously has no cleanups to run.  'false' is always
12650b57cec5SDimitry Andric   /// a conservatively correct answer for this method.
12660b57cec5SDimitry Andric   bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const;
12670b57cec5SDimitry Andric 
12680b57cec5SDimitry Andric   /// popCatchScope - Pops the catch scope at the top of the EHScope
12690b57cec5SDimitry Andric   /// stack, emitting any required code (other than the catch handlers
12700b57cec5SDimitry Andric   /// themselves).
12710b57cec5SDimitry Andric   void popCatchScope();
12720b57cec5SDimitry Andric 
12730b57cec5SDimitry Andric   llvm::BasicBlock *getEHResumeBlock(bool isCleanup);
12740b57cec5SDimitry Andric   llvm::BasicBlock *getEHDispatchBlock(EHScopeStack::stable_iterator scope);
12750b57cec5SDimitry Andric   llvm::BasicBlock *
12760b57cec5SDimitry Andric   getFuncletEHDispatchBlock(EHScopeStack::stable_iterator scope);
12770b57cec5SDimitry Andric 
12780b57cec5SDimitry Andric   /// An object to manage conditionally-evaluated expressions.
12790b57cec5SDimitry Andric   class ConditionalEvaluation {
12800b57cec5SDimitry Andric     llvm::BasicBlock *StartBB;
12810b57cec5SDimitry Andric 
12820b57cec5SDimitry Andric   public:
12830b57cec5SDimitry Andric     ConditionalEvaluation(CodeGenFunction &CGF)
12840b57cec5SDimitry Andric       : StartBB(CGF.Builder.GetInsertBlock()) {}
12850b57cec5SDimitry Andric 
12860b57cec5SDimitry Andric     void begin(CodeGenFunction &CGF) {
12870b57cec5SDimitry Andric       assert(CGF.OutermostConditional != this);
12880b57cec5SDimitry Andric       if (!CGF.OutermostConditional)
12890b57cec5SDimitry Andric         CGF.OutermostConditional = this;
12900b57cec5SDimitry Andric     }
12910b57cec5SDimitry Andric 
12920b57cec5SDimitry Andric     void end(CodeGenFunction &CGF) {
12930b57cec5SDimitry Andric       assert(CGF.OutermostConditional != nullptr);
12940b57cec5SDimitry Andric       if (CGF.OutermostConditional == this)
12950b57cec5SDimitry Andric         CGF.OutermostConditional = nullptr;
12960b57cec5SDimitry Andric     }
12970b57cec5SDimitry Andric 
12980b57cec5SDimitry Andric     /// Returns a block which will be executed prior to each
12990b57cec5SDimitry Andric     /// evaluation of the conditional code.
13000b57cec5SDimitry Andric     llvm::BasicBlock *getStartingBlock() const {
13010b57cec5SDimitry Andric       return StartBB;
13020b57cec5SDimitry Andric     }
13030b57cec5SDimitry Andric   };
13040b57cec5SDimitry Andric 
13050b57cec5SDimitry Andric   /// isInConditionalBranch - Return true if we're currently emitting
13060b57cec5SDimitry Andric   /// one branch or the other of a conditional expression.
13070b57cec5SDimitry Andric   bool isInConditionalBranch() const { return OutermostConditional != nullptr; }
13080b57cec5SDimitry Andric 
13090fca6ea1SDimitry Andric   void setBeforeOutermostConditional(llvm::Value *value, Address addr,
13100fca6ea1SDimitry Andric                                      CodeGenFunction &CGF) {
13110b57cec5SDimitry Andric     assert(isInConditionalBranch());
13120b57cec5SDimitry Andric     llvm::BasicBlock *block = OutermostConditional->getStartingBlock();
13130fca6ea1SDimitry Andric     auto store =
13140fca6ea1SDimitry Andric         new llvm::StoreInst(value, addr.emitRawPointer(CGF), &block->back());
1315a7dea167SDimitry Andric     store->setAlignment(addr.getAlignment().getAsAlign());
13160b57cec5SDimitry Andric   }
13170b57cec5SDimitry Andric 
13180b57cec5SDimitry Andric   /// An RAII object to record that we're evaluating a statement
13190b57cec5SDimitry Andric   /// expression.
13200b57cec5SDimitry Andric   class StmtExprEvaluation {
13210b57cec5SDimitry Andric     CodeGenFunction &CGF;
13220b57cec5SDimitry Andric 
13230b57cec5SDimitry Andric     /// We have to save the outermost conditional: cleanups in a
13240b57cec5SDimitry Andric     /// statement expression aren't conditional just because the
13250b57cec5SDimitry Andric     /// StmtExpr is.
13260b57cec5SDimitry Andric     ConditionalEvaluation *SavedOutermostConditional;
13270b57cec5SDimitry Andric 
13280b57cec5SDimitry Andric   public:
13290b57cec5SDimitry Andric     StmtExprEvaluation(CodeGenFunction &CGF)
13300b57cec5SDimitry Andric       : CGF(CGF), SavedOutermostConditional(CGF.OutermostConditional) {
13310b57cec5SDimitry Andric       CGF.OutermostConditional = nullptr;
13320b57cec5SDimitry Andric     }
13330b57cec5SDimitry Andric 
13340b57cec5SDimitry Andric     ~StmtExprEvaluation() {
13350b57cec5SDimitry Andric       CGF.OutermostConditional = SavedOutermostConditional;
13360b57cec5SDimitry Andric       CGF.EnsureInsertPoint();
13370b57cec5SDimitry Andric     }
13380b57cec5SDimitry Andric   };
13390b57cec5SDimitry Andric 
13400b57cec5SDimitry Andric   /// An object which temporarily prevents a value from being
13410b57cec5SDimitry Andric   /// destroyed by aggressive peephole optimizations that assume that
13420b57cec5SDimitry Andric   /// all uses of a value have been realized in the IR.
13430b57cec5SDimitry Andric   class PeepholeProtection {
13445f757f3fSDimitry Andric     llvm::Instruction *Inst = nullptr;
13450b57cec5SDimitry Andric     friend class CodeGenFunction;
13460b57cec5SDimitry Andric 
13470b57cec5SDimitry Andric   public:
13485f757f3fSDimitry Andric     PeepholeProtection() = default;
13490b57cec5SDimitry Andric   };
13500b57cec5SDimitry Andric 
13510b57cec5SDimitry Andric   /// A non-RAII class containing all the information about a bound
13520b57cec5SDimitry Andric   /// opaque value.  OpaqueValueMapping, below, is a RAII wrapper for
13530b57cec5SDimitry Andric   /// this which makes individual mappings very simple; using this
13540b57cec5SDimitry Andric   /// class directly is useful when you have a variable number of
13550b57cec5SDimitry Andric   /// opaque values or don't want the RAII functionality for some
13560b57cec5SDimitry Andric   /// reason.
13570b57cec5SDimitry Andric   class OpaqueValueMappingData {
13580b57cec5SDimitry Andric     const OpaqueValueExpr *OpaqueValue;
13590b57cec5SDimitry Andric     bool BoundLValue;
13600b57cec5SDimitry Andric     CodeGenFunction::PeepholeProtection Protection;
13610b57cec5SDimitry Andric 
13620b57cec5SDimitry Andric     OpaqueValueMappingData(const OpaqueValueExpr *ov,
13630b57cec5SDimitry Andric                            bool boundLValue)
13640b57cec5SDimitry Andric       : OpaqueValue(ov), BoundLValue(boundLValue) {}
13650b57cec5SDimitry Andric   public:
13660b57cec5SDimitry Andric     OpaqueValueMappingData() : OpaqueValue(nullptr) {}
13670b57cec5SDimitry Andric 
13680b57cec5SDimitry Andric     static bool shouldBindAsLValue(const Expr *expr) {
13690b57cec5SDimitry Andric       // gl-values should be bound as l-values for obvious reasons.
13700b57cec5SDimitry Andric       // Records should be bound as l-values because IR generation
13710b57cec5SDimitry Andric       // always keeps them in memory.  Expressions of function type
13720b57cec5SDimitry Andric       // act exactly like l-values but are formally required to be
13730b57cec5SDimitry Andric       // r-values in C.
13740b57cec5SDimitry Andric       return expr->isGLValue() ||
13750b57cec5SDimitry Andric              expr->getType()->isFunctionType() ||
13760b57cec5SDimitry Andric              hasAggregateEvaluationKind(expr->getType());
13770b57cec5SDimitry Andric     }
13780b57cec5SDimitry Andric 
13790b57cec5SDimitry Andric     static OpaqueValueMappingData bind(CodeGenFunction &CGF,
13800b57cec5SDimitry Andric                                        const OpaqueValueExpr *ov,
13810b57cec5SDimitry Andric                                        const Expr *e) {
13820b57cec5SDimitry Andric       if (shouldBindAsLValue(ov))
13830b57cec5SDimitry Andric         return bind(CGF, ov, CGF.EmitLValue(e));
13840b57cec5SDimitry Andric       return bind(CGF, ov, CGF.EmitAnyExpr(e));
13850b57cec5SDimitry Andric     }
13860b57cec5SDimitry Andric 
13870b57cec5SDimitry Andric     static OpaqueValueMappingData bind(CodeGenFunction &CGF,
13880b57cec5SDimitry Andric                                        const OpaqueValueExpr *ov,
13890b57cec5SDimitry Andric                                        const LValue &lv) {
13900b57cec5SDimitry Andric       assert(shouldBindAsLValue(ov));
13910b57cec5SDimitry Andric       CGF.OpaqueLValues.insert(std::make_pair(ov, lv));
13920b57cec5SDimitry Andric       return OpaqueValueMappingData(ov, true);
13930b57cec5SDimitry Andric     }
13940b57cec5SDimitry Andric 
13950b57cec5SDimitry Andric     static OpaqueValueMappingData bind(CodeGenFunction &CGF,
13960b57cec5SDimitry Andric                                        const OpaqueValueExpr *ov,
13970b57cec5SDimitry Andric                                        const RValue &rv) {
13980b57cec5SDimitry Andric       assert(!shouldBindAsLValue(ov));
13990b57cec5SDimitry Andric       CGF.OpaqueRValues.insert(std::make_pair(ov, rv));
14000b57cec5SDimitry Andric 
14010b57cec5SDimitry Andric       OpaqueValueMappingData data(ov, false);
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric       // Work around an extremely aggressive peephole optimization in
14040b57cec5SDimitry Andric       // EmitScalarConversion which assumes that all other uses of a
14050b57cec5SDimitry Andric       // value are extant.
14060b57cec5SDimitry Andric       data.Protection = CGF.protectFromPeepholes(rv);
14070b57cec5SDimitry Andric 
14080b57cec5SDimitry Andric       return data;
14090b57cec5SDimitry Andric     }
14100b57cec5SDimitry Andric 
14110b57cec5SDimitry Andric     bool isValid() const { return OpaqueValue != nullptr; }
14120b57cec5SDimitry Andric     void clear() { OpaqueValue = nullptr; }
14130b57cec5SDimitry Andric 
14140b57cec5SDimitry Andric     void unbind(CodeGenFunction &CGF) {
14150b57cec5SDimitry Andric       assert(OpaqueValue && "no data to unbind!");
14160b57cec5SDimitry Andric 
14170b57cec5SDimitry Andric       if (BoundLValue) {
14180b57cec5SDimitry Andric         CGF.OpaqueLValues.erase(OpaqueValue);
14190b57cec5SDimitry Andric       } else {
14200b57cec5SDimitry Andric         CGF.OpaqueRValues.erase(OpaqueValue);
14210b57cec5SDimitry Andric         CGF.unprotectFromPeepholes(Protection);
14220b57cec5SDimitry Andric       }
14230b57cec5SDimitry Andric     }
14240b57cec5SDimitry Andric   };
14250b57cec5SDimitry Andric 
14260b57cec5SDimitry Andric   /// An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
14270b57cec5SDimitry Andric   class OpaqueValueMapping {
14280b57cec5SDimitry Andric     CodeGenFunction &CGF;
14290b57cec5SDimitry Andric     OpaqueValueMappingData Data;
14300b57cec5SDimitry Andric 
14310b57cec5SDimitry Andric   public:
14320b57cec5SDimitry Andric     static bool shouldBindAsLValue(const Expr *expr) {
14330b57cec5SDimitry Andric       return OpaqueValueMappingData::shouldBindAsLValue(expr);
14340b57cec5SDimitry Andric     }
14350b57cec5SDimitry Andric 
14360b57cec5SDimitry Andric     /// Build the opaque value mapping for the given conditional
14370b57cec5SDimitry Andric     /// operator if it's the GNU ?: extension.  This is a common
14380b57cec5SDimitry Andric     /// enough pattern that the convenience operator is really
14390b57cec5SDimitry Andric     /// helpful.
14400b57cec5SDimitry Andric     ///
14410b57cec5SDimitry Andric     OpaqueValueMapping(CodeGenFunction &CGF,
14420b57cec5SDimitry Andric                        const AbstractConditionalOperator *op) : CGF(CGF) {
14430b57cec5SDimitry Andric       if (isa<ConditionalOperator>(op))
14440b57cec5SDimitry Andric         // Leave Data empty.
14450b57cec5SDimitry Andric         return;
14460b57cec5SDimitry Andric 
14470b57cec5SDimitry Andric       const BinaryConditionalOperator *e = cast<BinaryConditionalOperator>(op);
14480b57cec5SDimitry Andric       Data = OpaqueValueMappingData::bind(CGF, e->getOpaqueValue(),
14490b57cec5SDimitry Andric                                           e->getCommon());
14500b57cec5SDimitry Andric     }
14510b57cec5SDimitry Andric 
14520b57cec5SDimitry Andric     /// Build the opaque value mapping for an OpaqueValueExpr whose source
14530b57cec5SDimitry Andric     /// expression is set to the expression the OVE represents.
14540b57cec5SDimitry Andric     OpaqueValueMapping(CodeGenFunction &CGF, const OpaqueValueExpr *OV)
14550b57cec5SDimitry Andric         : CGF(CGF) {
14560b57cec5SDimitry Andric       if (OV) {
14570b57cec5SDimitry Andric         assert(OV->getSourceExpr() && "wrong form of OpaqueValueMapping used "
14580b57cec5SDimitry Andric                                       "for OVE with no source expression");
14590b57cec5SDimitry Andric         Data = OpaqueValueMappingData::bind(CGF, OV, OV->getSourceExpr());
14600b57cec5SDimitry Andric       }
14610b57cec5SDimitry Andric     }
14620b57cec5SDimitry Andric 
14630b57cec5SDimitry Andric     OpaqueValueMapping(CodeGenFunction &CGF,
14640b57cec5SDimitry Andric                        const OpaqueValueExpr *opaqueValue,
14650b57cec5SDimitry Andric                        LValue lvalue)
14660b57cec5SDimitry Andric       : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, lvalue)) {
14670b57cec5SDimitry Andric     }
14680b57cec5SDimitry Andric 
14690b57cec5SDimitry Andric     OpaqueValueMapping(CodeGenFunction &CGF,
14700b57cec5SDimitry Andric                        const OpaqueValueExpr *opaqueValue,
14710b57cec5SDimitry Andric                        RValue rvalue)
14720b57cec5SDimitry Andric       : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, rvalue)) {
14730b57cec5SDimitry Andric     }
14740b57cec5SDimitry Andric 
14750b57cec5SDimitry Andric     void pop() {
14760b57cec5SDimitry Andric       Data.unbind(CGF);
14770b57cec5SDimitry Andric       Data.clear();
14780b57cec5SDimitry Andric     }
14790b57cec5SDimitry Andric 
14800b57cec5SDimitry Andric     ~OpaqueValueMapping() {
14810b57cec5SDimitry Andric       if (Data.isValid()) Data.unbind(CGF);
14820b57cec5SDimitry Andric     }
14830b57cec5SDimitry Andric   };
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric private:
14860b57cec5SDimitry Andric   CGDebugInfo *DebugInfo;
14870b57cec5SDimitry Andric   /// Used to create unique names for artificial VLA size debug info variables.
14880b57cec5SDimitry Andric   unsigned VLAExprCounter = 0;
14890b57cec5SDimitry Andric   bool DisableDebugInfo = false;
14900b57cec5SDimitry Andric 
14910b57cec5SDimitry Andric   /// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid
14920b57cec5SDimitry Andric   /// calling llvm.stacksave for multiple VLAs in the same scope.
14930b57cec5SDimitry Andric   bool DidCallStackSave = false;
14940b57cec5SDimitry Andric 
14950b57cec5SDimitry Andric   /// IndirectBranch - The first time an indirect goto is seen we create a block
14960b57cec5SDimitry Andric   /// with an indirect branch.  Every time we see the address of a label taken,
14970b57cec5SDimitry Andric   /// we add the label to the indirect goto.  Every subsequent indirect goto is
14980b57cec5SDimitry Andric   /// codegen'd as a jump to the IndirectBranch's basic block.
14990b57cec5SDimitry Andric   llvm::IndirectBrInst *IndirectBranch = nullptr;
15000b57cec5SDimitry Andric 
15010b57cec5SDimitry Andric   /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
15020b57cec5SDimitry Andric   /// decls.
15030b57cec5SDimitry Andric   DeclMapTy LocalDeclMap;
15040b57cec5SDimitry Andric 
15050b57cec5SDimitry Andric   // Keep track of the cleanups for callee-destructed parameters pushed to the
15060b57cec5SDimitry Andric   // cleanup stack so that they can be deactivated later.
15070b57cec5SDimitry Andric   llvm::DenseMap<const ParmVarDecl *, EHScopeStack::stable_iterator>
15080b57cec5SDimitry Andric       CalleeDestructedParamCleanups;
15090b57cec5SDimitry Andric 
15100b57cec5SDimitry Andric   /// SizeArguments - If a ParmVarDecl had the pass_object_size attribute, this
15110b57cec5SDimitry Andric   /// will contain a mapping from said ParmVarDecl to its implicit "object_size"
15120b57cec5SDimitry Andric   /// parameter.
15130b57cec5SDimitry Andric   llvm::SmallDenseMap<const ParmVarDecl *, const ImplicitParamDecl *, 2>
15140b57cec5SDimitry Andric       SizeArguments;
15150b57cec5SDimitry Andric 
15160b57cec5SDimitry Andric   /// Track escaped local variables with auto storage. Used during SEH
15170b57cec5SDimitry Andric   /// outlining to produce a call to llvm.localescape.
15180b57cec5SDimitry Andric   llvm::DenseMap<llvm::AllocaInst *, int> EscapedLocals;
15190b57cec5SDimitry Andric 
15200b57cec5SDimitry Andric   /// LabelMap - This keeps track of the LLVM basic block for each C label.
15210b57cec5SDimitry Andric   llvm::DenseMap<const LabelDecl*, JumpDest> LabelMap;
15220b57cec5SDimitry Andric 
15230b57cec5SDimitry Andric   // BreakContinueStack - This keeps track of where break and continue
15240b57cec5SDimitry Andric   // statements should jump to.
15250b57cec5SDimitry Andric   struct BreakContinue {
15260b57cec5SDimitry Andric     BreakContinue(JumpDest Break, JumpDest Continue)
15270b57cec5SDimitry Andric       : BreakBlock(Break), ContinueBlock(Continue) {}
15280b57cec5SDimitry Andric 
15290b57cec5SDimitry Andric     JumpDest BreakBlock;
15300b57cec5SDimitry Andric     JumpDest ContinueBlock;
15310b57cec5SDimitry Andric   };
15320b57cec5SDimitry Andric   SmallVector<BreakContinue, 8> BreakContinueStack;
15330b57cec5SDimitry Andric 
15340b57cec5SDimitry Andric   /// Handles cancellation exit points in OpenMP-related constructs.
15350b57cec5SDimitry Andric   class OpenMPCancelExitStack {
15360b57cec5SDimitry Andric     /// Tracks cancellation exit point and join point for cancel-related exit
15370b57cec5SDimitry Andric     /// and normal exit.
15380b57cec5SDimitry Andric     struct CancelExit {
15390b57cec5SDimitry Andric       CancelExit() = default;
15400b57cec5SDimitry Andric       CancelExit(OpenMPDirectiveKind Kind, JumpDest ExitBlock,
15410b57cec5SDimitry Andric                  JumpDest ContBlock)
15420b57cec5SDimitry Andric           : Kind(Kind), ExitBlock(ExitBlock), ContBlock(ContBlock) {}
1543480093f4SDimitry Andric       OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown;
15440b57cec5SDimitry Andric       /// true if the exit block has been emitted already by the special
15450b57cec5SDimitry Andric       /// emitExit() call, false if the default codegen is used.
15460b57cec5SDimitry Andric       bool HasBeenEmitted = false;
15470b57cec5SDimitry Andric       JumpDest ExitBlock;
15480b57cec5SDimitry Andric       JumpDest ContBlock;
15490b57cec5SDimitry Andric     };
15500b57cec5SDimitry Andric 
15510b57cec5SDimitry Andric     SmallVector<CancelExit, 8> Stack;
15520b57cec5SDimitry Andric 
15530b57cec5SDimitry Andric   public:
15540b57cec5SDimitry Andric     OpenMPCancelExitStack() : Stack(1) {}
15550b57cec5SDimitry Andric     ~OpenMPCancelExitStack() = default;
15560b57cec5SDimitry Andric     /// Fetches the exit block for the current OpenMP construct.
15570b57cec5SDimitry Andric     JumpDest getExitBlock() const { return Stack.back().ExitBlock; }
15580b57cec5SDimitry Andric     /// Emits exit block with special codegen procedure specific for the related
15590b57cec5SDimitry Andric     /// OpenMP construct + emits code for normal construct cleanup.
15600b57cec5SDimitry Andric     void emitExit(CodeGenFunction &CGF, OpenMPDirectiveKind Kind,
15610b57cec5SDimitry Andric                   const llvm::function_ref<void(CodeGenFunction &)> CodeGen) {
15620b57cec5SDimitry Andric       if (Stack.back().Kind == Kind && getExitBlock().isValid()) {
15630b57cec5SDimitry Andric         assert(CGF.getOMPCancelDestination(Kind).isValid());
15640b57cec5SDimitry Andric         assert(CGF.HaveInsertPoint());
15650b57cec5SDimitry Andric         assert(!Stack.back().HasBeenEmitted);
15660b57cec5SDimitry Andric         auto IP = CGF.Builder.saveAndClearIP();
15670b57cec5SDimitry Andric         CGF.EmitBlock(Stack.back().ExitBlock.getBlock());
15680b57cec5SDimitry Andric         CodeGen(CGF);
15690b57cec5SDimitry Andric         CGF.EmitBranch(Stack.back().ContBlock.getBlock());
15700b57cec5SDimitry Andric         CGF.Builder.restoreIP(IP);
15710b57cec5SDimitry Andric         Stack.back().HasBeenEmitted = true;
15720b57cec5SDimitry Andric       }
15730b57cec5SDimitry Andric       CodeGen(CGF);
15740b57cec5SDimitry Andric     }
15750b57cec5SDimitry Andric     /// Enter the cancel supporting \a Kind construct.
15760b57cec5SDimitry Andric     /// \param Kind OpenMP directive that supports cancel constructs.
15770b57cec5SDimitry Andric     /// \param HasCancel true, if the construct has inner cancel directive,
15780b57cec5SDimitry Andric     /// false otherwise.
15790b57cec5SDimitry Andric     void enter(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, bool HasCancel) {
15800b57cec5SDimitry Andric       Stack.push_back({Kind,
15810b57cec5SDimitry Andric                        HasCancel ? CGF.getJumpDestInCurrentScope("cancel.exit")
15820b57cec5SDimitry Andric                                  : JumpDest(),
15830b57cec5SDimitry Andric                        HasCancel ? CGF.getJumpDestInCurrentScope("cancel.cont")
15840b57cec5SDimitry Andric                                  : JumpDest()});
15850b57cec5SDimitry Andric     }
15860b57cec5SDimitry Andric     /// Emits default exit point for the cancel construct (if the special one
15870b57cec5SDimitry Andric     /// has not be used) + join point for cancel/normal exits.
15880b57cec5SDimitry Andric     void exit(CodeGenFunction &CGF) {
15890b57cec5SDimitry Andric       if (getExitBlock().isValid()) {
15900b57cec5SDimitry Andric         assert(CGF.getOMPCancelDestination(Stack.back().Kind).isValid());
15910b57cec5SDimitry Andric         bool HaveIP = CGF.HaveInsertPoint();
15920b57cec5SDimitry Andric         if (!Stack.back().HasBeenEmitted) {
15930b57cec5SDimitry Andric           if (HaveIP)
15940b57cec5SDimitry Andric             CGF.EmitBranchThroughCleanup(Stack.back().ContBlock);
15950b57cec5SDimitry Andric           CGF.EmitBlock(Stack.back().ExitBlock.getBlock());
15960b57cec5SDimitry Andric           CGF.EmitBranchThroughCleanup(Stack.back().ContBlock);
15970b57cec5SDimitry Andric         }
15980b57cec5SDimitry Andric         CGF.EmitBlock(Stack.back().ContBlock.getBlock());
15990b57cec5SDimitry Andric         if (!HaveIP) {
16000b57cec5SDimitry Andric           CGF.Builder.CreateUnreachable();
16010b57cec5SDimitry Andric           CGF.Builder.ClearInsertionPoint();
16020b57cec5SDimitry Andric         }
16030b57cec5SDimitry Andric       }
16040b57cec5SDimitry Andric       Stack.pop_back();
16050b57cec5SDimitry Andric     }
16060b57cec5SDimitry Andric   };
16070b57cec5SDimitry Andric   OpenMPCancelExitStack OMPCancelStack;
16080b57cec5SDimitry Andric 
1609fe6060f1SDimitry Andric   /// Lower the Likelihood knowledge about the \p Cond via llvm.expect intrin.
1610fe6060f1SDimitry Andric   llvm::Value *emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond,
1611fe6060f1SDimitry Andric                                                     Stmt::Likelihood LH);
1612e8d8bef9SDimitry Andric 
16130b57cec5SDimitry Andric   CodeGenPGO PGO;
16140b57cec5SDimitry Andric 
16151db9f3b2SDimitry Andric   /// Bitmap used by MC/DC to track condition outcomes of a boolean expression.
16161db9f3b2SDimitry Andric   Address MCDCCondBitmapAddr = Address::invalid();
16171db9f3b2SDimitry Andric 
16180b57cec5SDimitry Andric   /// Calculate branch weights appropriate for PGO data
1619e8d8bef9SDimitry Andric   llvm::MDNode *createProfileWeights(uint64_t TrueCount,
1620e8d8bef9SDimitry Andric                                      uint64_t FalseCount) const;
1621e8d8bef9SDimitry Andric   llvm::MDNode *createProfileWeights(ArrayRef<uint64_t> Weights) const;
16220b57cec5SDimitry Andric   llvm::MDNode *createProfileWeightsForLoop(const Stmt *Cond,
1623e8d8bef9SDimitry Andric                                             uint64_t LoopCount) const;
1624e8d8bef9SDimitry Andric 
16250b57cec5SDimitry Andric public:
16260b57cec5SDimitry Andric   /// Increment the profiler's counter for the given statement by \p StepV.
16270b57cec5SDimitry Andric   /// If \p StepV is null, the default increment is 1.
16280b57cec5SDimitry Andric   void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) {
1629e8d8bef9SDimitry Andric     if (CGM.getCodeGenOpts().hasProfileClangInstr() &&
1630bdd1243dSDimitry Andric         !CurFn->hasFnAttribute(llvm::Attribute::NoProfile) &&
16310fca6ea1SDimitry Andric         !CurFn->hasFnAttribute(llvm::Attribute::SkipProfile)) {
16320fca6ea1SDimitry Andric       auto AL = ApplyDebugLocation::CreateArtificial(*this);
16330fca6ea1SDimitry Andric       PGO.emitCounterSetOrIncrement(Builder, S, StepV);
16340fca6ea1SDimitry Andric     }
16350b57cec5SDimitry Andric     PGO.setCurrentStmt(S);
16360b57cec5SDimitry Andric   }
16370b57cec5SDimitry Andric 
16381db9f3b2SDimitry Andric   bool isMCDCCoverageEnabled() const {
16391db9f3b2SDimitry Andric     return (CGM.getCodeGenOpts().hasProfileClangInstr() &&
16401db9f3b2SDimitry Andric             CGM.getCodeGenOpts().MCDCCoverage &&
16411db9f3b2SDimitry Andric             !CurFn->hasFnAttribute(llvm::Attribute::NoProfile));
16421db9f3b2SDimitry Andric   }
16431db9f3b2SDimitry Andric 
16441db9f3b2SDimitry Andric   /// Allocate a temp value on the stack that MCDC can use to track condition
16451db9f3b2SDimitry Andric   /// results.
16461db9f3b2SDimitry Andric   void maybeCreateMCDCCondBitmap() {
16471db9f3b2SDimitry Andric     if (isMCDCCoverageEnabled()) {
16481db9f3b2SDimitry Andric       PGO.emitMCDCParameters(Builder);
16491db9f3b2SDimitry Andric       MCDCCondBitmapAddr =
16501db9f3b2SDimitry Andric           CreateIRTemp(getContext().UnsignedIntTy, "mcdc.addr");
16511db9f3b2SDimitry Andric     }
16521db9f3b2SDimitry Andric   }
16531db9f3b2SDimitry Andric 
16541db9f3b2SDimitry Andric   bool isBinaryLogicalOp(const Expr *E) const {
16551db9f3b2SDimitry Andric     const BinaryOperator *BOp = dyn_cast<BinaryOperator>(E->IgnoreParens());
16561db9f3b2SDimitry Andric     return (BOp && BOp->isLogicalOp());
16571db9f3b2SDimitry Andric   }
16581db9f3b2SDimitry Andric 
16591db9f3b2SDimitry Andric   /// Zero-init the MCDC temp value.
16601db9f3b2SDimitry Andric   void maybeResetMCDCCondBitmap(const Expr *E) {
16611db9f3b2SDimitry Andric     if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) {
16621db9f3b2SDimitry Andric       PGO.emitMCDCCondBitmapReset(Builder, E, MCDCCondBitmapAddr);
16631db9f3b2SDimitry Andric       PGO.setCurrentStmt(E);
16641db9f3b2SDimitry Andric     }
16651db9f3b2SDimitry Andric   }
16661db9f3b2SDimitry Andric 
16671db9f3b2SDimitry Andric   /// Increment the profiler's counter for the given expression by \p StepV.
16681db9f3b2SDimitry Andric   /// If \p StepV is null, the default increment is 1.
16691db9f3b2SDimitry Andric   void maybeUpdateMCDCTestVectorBitmap(const Expr *E) {
16701db9f3b2SDimitry Andric     if (isMCDCCoverageEnabled() && isBinaryLogicalOp(E)) {
16710fca6ea1SDimitry Andric       PGO.emitMCDCTestVectorBitmapUpdate(Builder, E, MCDCCondBitmapAddr, *this);
16721db9f3b2SDimitry Andric       PGO.setCurrentStmt(E);
16731db9f3b2SDimitry Andric     }
16741db9f3b2SDimitry Andric   }
16751db9f3b2SDimitry Andric 
16761db9f3b2SDimitry Andric   /// Update the MCDC temp value with the condition's evaluated result.
16771db9f3b2SDimitry Andric   void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val) {
16781db9f3b2SDimitry Andric     if (isMCDCCoverageEnabled()) {
16790fca6ea1SDimitry Andric       PGO.emitMCDCCondBitmapUpdate(Builder, E, MCDCCondBitmapAddr, Val, *this);
16801db9f3b2SDimitry Andric       PGO.setCurrentStmt(E);
16811db9f3b2SDimitry Andric     }
16821db9f3b2SDimitry Andric   }
16831db9f3b2SDimitry Andric 
16840b57cec5SDimitry Andric   /// Get the profiler's count for the given statement.
16850b57cec5SDimitry Andric   uint64_t getProfileCount(const Stmt *S) {
168681ad6265SDimitry Andric     return PGO.getStmtCount(S).value_or(0);
16870b57cec5SDimitry Andric   }
16880b57cec5SDimitry Andric 
16890b57cec5SDimitry Andric   /// Set the profiler's current count.
16900b57cec5SDimitry Andric   void setCurrentProfileCount(uint64_t Count) {
16910b57cec5SDimitry Andric     PGO.setCurrentRegionCount(Count);
16920b57cec5SDimitry Andric   }
16930b57cec5SDimitry Andric 
16940b57cec5SDimitry Andric   /// Get the profiler's current count. This is generally the count for the most
16950b57cec5SDimitry Andric   /// recently incremented counter.
16960b57cec5SDimitry Andric   uint64_t getCurrentProfileCount() {
16970b57cec5SDimitry Andric     return PGO.getCurrentRegionCount();
16980b57cec5SDimitry Andric   }
16990b57cec5SDimitry Andric 
17000b57cec5SDimitry Andric private:
17010b57cec5SDimitry Andric 
17020b57cec5SDimitry Andric   /// SwitchInsn - This is nearest current switch instruction. It is null if
17030b57cec5SDimitry Andric   /// current context is not in a switch.
17040b57cec5SDimitry Andric   llvm::SwitchInst *SwitchInsn = nullptr;
17050b57cec5SDimitry Andric   /// The branch weights of SwitchInsn when doing instrumentation based PGO.
17060b57cec5SDimitry Andric   SmallVector<uint64_t, 16> *SwitchWeights = nullptr;
17070b57cec5SDimitry Andric 
1708e8d8bef9SDimitry Andric   /// The likelihood attributes of the SwitchCase.
1709e8d8bef9SDimitry Andric   SmallVector<Stmt::Likelihood, 16> *SwitchLikelihood = nullptr;
1710e8d8bef9SDimitry Andric 
17110b57cec5SDimitry Andric   /// CaseRangeBlock - This block holds if condition check for last case
17120b57cec5SDimitry Andric   /// statement range in current switch instruction.
17130b57cec5SDimitry Andric   llvm::BasicBlock *CaseRangeBlock = nullptr;
17140b57cec5SDimitry Andric 
17150b57cec5SDimitry Andric   /// OpaqueLValues - Keeps track of the current set of opaque value
17160b57cec5SDimitry Andric   /// expressions.
17170b57cec5SDimitry Andric   llvm::DenseMap<const OpaqueValueExpr *, LValue> OpaqueLValues;
17180b57cec5SDimitry Andric   llvm::DenseMap<const OpaqueValueExpr *, RValue> OpaqueRValues;
17190b57cec5SDimitry Andric 
17200b57cec5SDimitry Andric   // VLASizeMap - This keeps track of the associated size for each VLA type.
17210b57cec5SDimitry Andric   // We track this by the size expression rather than the type itself because
17220b57cec5SDimitry Andric   // in certain situations, like a const qualifier applied to an VLA typedef,
17230b57cec5SDimitry Andric   // multiple VLA types can share the same size expression.
17240b57cec5SDimitry Andric   // FIXME: Maybe this could be a stack of maps that is pushed/popped as we
17250b57cec5SDimitry Andric   // enter/leave scopes.
17260b57cec5SDimitry Andric   llvm::DenseMap<const Expr*, llvm::Value*> VLASizeMap;
17270b57cec5SDimitry Andric 
17280b57cec5SDimitry Andric   /// A block containing a single 'unreachable' instruction.  Created
17290b57cec5SDimitry Andric   /// lazily by getUnreachableBlock().
17300b57cec5SDimitry Andric   llvm::BasicBlock *UnreachableBlock = nullptr;
17310b57cec5SDimitry Andric 
17320b57cec5SDimitry Andric   /// Counts of the number return expressions in the function.
17330b57cec5SDimitry Andric   unsigned NumReturnExprs = 0;
17340b57cec5SDimitry Andric 
17350b57cec5SDimitry Andric   /// Count the number of simple (constant) return expressions in the function.
17360b57cec5SDimitry Andric   unsigned NumSimpleReturnExprs = 0;
17370b57cec5SDimitry Andric 
17380b57cec5SDimitry Andric   /// The last regular (non-return) debug location (breakpoint) in the function.
17390b57cec5SDimitry Andric   SourceLocation LastStopPoint;
17400b57cec5SDimitry Andric 
17410b57cec5SDimitry Andric public:
17420b57cec5SDimitry Andric   /// Source location information about the default argument or member
17430b57cec5SDimitry Andric   /// initializer expression we're evaluating, if any.
17440b57cec5SDimitry Andric   CurrentSourceLocExprScope CurSourceLocExprScope;
17450b57cec5SDimitry Andric   using SourceLocExprScopeGuard =
17460b57cec5SDimitry Andric       CurrentSourceLocExprScope::SourceLocExprScopeGuard;
17470b57cec5SDimitry Andric 
17480b57cec5SDimitry Andric   /// A scope within which we are constructing the fields of an object which
17490b57cec5SDimitry Andric   /// might use a CXXDefaultInitExpr. This stashes away a 'this' value to use
17500b57cec5SDimitry Andric   /// if we need to evaluate a CXXDefaultInitExpr within the evaluation.
17510b57cec5SDimitry Andric   class FieldConstructionScope {
17520b57cec5SDimitry Andric   public:
17530b57cec5SDimitry Andric     FieldConstructionScope(CodeGenFunction &CGF, Address This)
17540b57cec5SDimitry Andric         : CGF(CGF), OldCXXDefaultInitExprThis(CGF.CXXDefaultInitExprThis) {
17550b57cec5SDimitry Andric       CGF.CXXDefaultInitExprThis = This;
17560b57cec5SDimitry Andric     }
17570b57cec5SDimitry Andric     ~FieldConstructionScope() {
17580b57cec5SDimitry Andric       CGF.CXXDefaultInitExprThis = OldCXXDefaultInitExprThis;
17590b57cec5SDimitry Andric     }
17600b57cec5SDimitry Andric 
17610b57cec5SDimitry Andric   private:
17620b57cec5SDimitry Andric     CodeGenFunction &CGF;
17630b57cec5SDimitry Andric     Address OldCXXDefaultInitExprThis;
17640b57cec5SDimitry Andric   };
17650b57cec5SDimitry Andric 
17660b57cec5SDimitry Andric   /// The scope of a CXXDefaultInitExpr. Within this scope, the value of 'this'
17670b57cec5SDimitry Andric   /// is overridden to be the object under construction.
17680b57cec5SDimitry Andric   class CXXDefaultInitExprScope  {
17690b57cec5SDimitry Andric   public:
17700b57cec5SDimitry Andric     CXXDefaultInitExprScope(CodeGenFunction &CGF, const CXXDefaultInitExpr *E)
17710b57cec5SDimitry Andric         : CGF(CGF), OldCXXThisValue(CGF.CXXThisValue),
17720b57cec5SDimitry Andric           OldCXXThisAlignment(CGF.CXXThisAlignment),
17730b57cec5SDimitry Andric           SourceLocScope(E, CGF.CurSourceLocExprScope) {
17740fca6ea1SDimitry Andric       CGF.CXXThisValue = CGF.CXXDefaultInitExprThis.getBasePointer();
17750b57cec5SDimitry Andric       CGF.CXXThisAlignment = CGF.CXXDefaultInitExprThis.getAlignment();
17760b57cec5SDimitry Andric     }
17770b57cec5SDimitry Andric     ~CXXDefaultInitExprScope() {
17780b57cec5SDimitry Andric       CGF.CXXThisValue = OldCXXThisValue;
17790b57cec5SDimitry Andric       CGF.CXXThisAlignment = OldCXXThisAlignment;
17800b57cec5SDimitry Andric     }
17810b57cec5SDimitry Andric 
17820b57cec5SDimitry Andric   public:
17830b57cec5SDimitry Andric     CodeGenFunction &CGF;
17840b57cec5SDimitry Andric     llvm::Value *OldCXXThisValue;
17850b57cec5SDimitry Andric     CharUnits OldCXXThisAlignment;
17860b57cec5SDimitry Andric     SourceLocExprScopeGuard SourceLocScope;
17870b57cec5SDimitry Andric   };
17880b57cec5SDimitry Andric 
17890b57cec5SDimitry Andric   struct CXXDefaultArgExprScope : SourceLocExprScopeGuard {
17900b57cec5SDimitry Andric     CXXDefaultArgExprScope(CodeGenFunction &CGF, const CXXDefaultArgExpr *E)
17910b57cec5SDimitry Andric         : SourceLocExprScopeGuard(E, CGF.CurSourceLocExprScope) {}
17920b57cec5SDimitry Andric   };
17930b57cec5SDimitry Andric 
17940b57cec5SDimitry Andric   /// The scope of an ArrayInitLoopExpr. Within this scope, the value of the
17950b57cec5SDimitry Andric   /// current loop index is overridden.
17960b57cec5SDimitry Andric   class ArrayInitLoopExprScope {
17970b57cec5SDimitry Andric   public:
17980b57cec5SDimitry Andric     ArrayInitLoopExprScope(CodeGenFunction &CGF, llvm::Value *Index)
17990b57cec5SDimitry Andric       : CGF(CGF), OldArrayInitIndex(CGF.ArrayInitIndex) {
18000b57cec5SDimitry Andric       CGF.ArrayInitIndex = Index;
18010b57cec5SDimitry Andric     }
18020b57cec5SDimitry Andric     ~ArrayInitLoopExprScope() {
18030b57cec5SDimitry Andric       CGF.ArrayInitIndex = OldArrayInitIndex;
18040b57cec5SDimitry Andric     }
18050b57cec5SDimitry Andric 
18060b57cec5SDimitry Andric   private:
18070b57cec5SDimitry Andric     CodeGenFunction &CGF;
18080b57cec5SDimitry Andric     llvm::Value *OldArrayInitIndex;
18090b57cec5SDimitry Andric   };
18100b57cec5SDimitry Andric 
18110b57cec5SDimitry Andric   class InlinedInheritingConstructorScope {
18120b57cec5SDimitry Andric   public:
18130b57cec5SDimitry Andric     InlinedInheritingConstructorScope(CodeGenFunction &CGF, GlobalDecl GD)
18140b57cec5SDimitry Andric         : CGF(CGF), OldCurGD(CGF.CurGD), OldCurFuncDecl(CGF.CurFuncDecl),
18150b57cec5SDimitry Andric           OldCurCodeDecl(CGF.CurCodeDecl),
18160b57cec5SDimitry Andric           OldCXXABIThisDecl(CGF.CXXABIThisDecl),
18170b57cec5SDimitry Andric           OldCXXABIThisValue(CGF.CXXABIThisValue),
18180b57cec5SDimitry Andric           OldCXXThisValue(CGF.CXXThisValue),
18190b57cec5SDimitry Andric           OldCXXABIThisAlignment(CGF.CXXABIThisAlignment),
18200b57cec5SDimitry Andric           OldCXXThisAlignment(CGF.CXXThisAlignment),
18210b57cec5SDimitry Andric           OldReturnValue(CGF.ReturnValue), OldFnRetTy(CGF.FnRetTy),
18220b57cec5SDimitry Andric           OldCXXInheritedCtorInitExprArgs(
18230b57cec5SDimitry Andric               std::move(CGF.CXXInheritedCtorInitExprArgs)) {
18240b57cec5SDimitry Andric       CGF.CurGD = GD;
18250b57cec5SDimitry Andric       CGF.CurFuncDecl = CGF.CurCodeDecl =
18260b57cec5SDimitry Andric           cast<CXXConstructorDecl>(GD.getDecl());
18270b57cec5SDimitry Andric       CGF.CXXABIThisDecl = nullptr;
18280b57cec5SDimitry Andric       CGF.CXXABIThisValue = nullptr;
18290b57cec5SDimitry Andric       CGF.CXXThisValue = nullptr;
18300b57cec5SDimitry Andric       CGF.CXXABIThisAlignment = CharUnits();
18310b57cec5SDimitry Andric       CGF.CXXThisAlignment = CharUnits();
18320b57cec5SDimitry Andric       CGF.ReturnValue = Address::invalid();
18330b57cec5SDimitry Andric       CGF.FnRetTy = QualType();
18340b57cec5SDimitry Andric       CGF.CXXInheritedCtorInitExprArgs.clear();
18350b57cec5SDimitry Andric     }
18360b57cec5SDimitry Andric     ~InlinedInheritingConstructorScope() {
18370b57cec5SDimitry Andric       CGF.CurGD = OldCurGD;
18380b57cec5SDimitry Andric       CGF.CurFuncDecl = OldCurFuncDecl;
18390b57cec5SDimitry Andric       CGF.CurCodeDecl = OldCurCodeDecl;
18400b57cec5SDimitry Andric       CGF.CXXABIThisDecl = OldCXXABIThisDecl;
18410b57cec5SDimitry Andric       CGF.CXXABIThisValue = OldCXXABIThisValue;
18420b57cec5SDimitry Andric       CGF.CXXThisValue = OldCXXThisValue;
18430b57cec5SDimitry Andric       CGF.CXXABIThisAlignment = OldCXXABIThisAlignment;
18440b57cec5SDimitry Andric       CGF.CXXThisAlignment = OldCXXThisAlignment;
18450b57cec5SDimitry Andric       CGF.ReturnValue = OldReturnValue;
18460b57cec5SDimitry Andric       CGF.FnRetTy = OldFnRetTy;
18470b57cec5SDimitry Andric       CGF.CXXInheritedCtorInitExprArgs =
18480b57cec5SDimitry Andric           std::move(OldCXXInheritedCtorInitExprArgs);
18490b57cec5SDimitry Andric     }
18500b57cec5SDimitry Andric 
18510b57cec5SDimitry Andric   private:
18520b57cec5SDimitry Andric     CodeGenFunction &CGF;
18530b57cec5SDimitry Andric     GlobalDecl OldCurGD;
18540b57cec5SDimitry Andric     const Decl *OldCurFuncDecl;
18550b57cec5SDimitry Andric     const Decl *OldCurCodeDecl;
18560b57cec5SDimitry Andric     ImplicitParamDecl *OldCXXABIThisDecl;
18570b57cec5SDimitry Andric     llvm::Value *OldCXXABIThisValue;
18580b57cec5SDimitry Andric     llvm::Value *OldCXXThisValue;
18590b57cec5SDimitry Andric     CharUnits OldCXXABIThisAlignment;
18600b57cec5SDimitry Andric     CharUnits OldCXXThisAlignment;
18610b57cec5SDimitry Andric     Address OldReturnValue;
18620b57cec5SDimitry Andric     QualType OldFnRetTy;
18630b57cec5SDimitry Andric     CallArgList OldCXXInheritedCtorInitExprArgs;
18640b57cec5SDimitry Andric   };
18650b57cec5SDimitry Andric 
18665ffd83dbSDimitry Andric   // Helper class for the OpenMP IR Builder. Allows reusability of code used for
18675ffd83dbSDimitry Andric   // region body, and finalization codegen callbacks. This will class will also
18685ffd83dbSDimitry Andric   // contain privatization functions used by the privatization call backs
18695ffd83dbSDimitry Andric   //
18705ffd83dbSDimitry Andric   // TODO: this is temporary class for things that are being moved out of
18715ffd83dbSDimitry Andric   // CGOpenMPRuntime, new versions of current CodeGenFunction methods, or
18725ffd83dbSDimitry Andric   // utility function for use with the OMPBuilder. Once that move to use the
18735ffd83dbSDimitry Andric   // OMPBuilder is done, everything here will either become part of CodeGenFunc.
18745ffd83dbSDimitry Andric   // directly, or a new helper class that will contain functions used by both
18755ffd83dbSDimitry Andric   // this and the OMPBuilder
18765ffd83dbSDimitry Andric 
18775ffd83dbSDimitry Andric   struct OMPBuilderCBHelpers {
18785ffd83dbSDimitry Andric 
18795ffd83dbSDimitry Andric     OMPBuilderCBHelpers() = delete;
18805ffd83dbSDimitry Andric     OMPBuilderCBHelpers(const OMPBuilderCBHelpers &) = delete;
18815ffd83dbSDimitry Andric     OMPBuilderCBHelpers &operator=(const OMPBuilderCBHelpers &) = delete;
18825ffd83dbSDimitry Andric 
18835ffd83dbSDimitry Andric     using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
18845ffd83dbSDimitry Andric 
18855ffd83dbSDimitry Andric     /// Cleanup action for allocate support.
18865ffd83dbSDimitry Andric     class OMPAllocateCleanupTy final : public EHScopeStack::Cleanup {
18875ffd83dbSDimitry Andric 
18885ffd83dbSDimitry Andric     private:
18895ffd83dbSDimitry Andric       llvm::CallInst *RTLFnCI;
18905ffd83dbSDimitry Andric 
18915ffd83dbSDimitry Andric     public:
18925ffd83dbSDimitry Andric       OMPAllocateCleanupTy(llvm::CallInst *RLFnCI) : RTLFnCI(RLFnCI) {
18935ffd83dbSDimitry Andric         RLFnCI->removeFromParent();
18945ffd83dbSDimitry Andric       }
18955ffd83dbSDimitry Andric 
18965ffd83dbSDimitry Andric       void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
18975ffd83dbSDimitry Andric         if (!CGF.HaveInsertPoint())
18985ffd83dbSDimitry Andric           return;
18995ffd83dbSDimitry Andric         CGF.Builder.Insert(RTLFnCI);
19005ffd83dbSDimitry Andric       }
19015ffd83dbSDimitry Andric     };
19025ffd83dbSDimitry Andric 
19035ffd83dbSDimitry Andric     /// Returns address of the threadprivate variable for the current
19045ffd83dbSDimitry Andric     /// thread. This Also create any necessary OMP runtime calls.
19055ffd83dbSDimitry Andric     ///
19065ffd83dbSDimitry Andric     /// \param VD VarDecl for Threadprivate variable.
19075ffd83dbSDimitry Andric     /// \param VDAddr Address of the Vardecl
19085ffd83dbSDimitry Andric     /// \param Loc  The location where the barrier directive was encountered
19095ffd83dbSDimitry Andric     static Address getAddrOfThreadPrivate(CodeGenFunction &CGF,
19105ffd83dbSDimitry Andric                                           const VarDecl *VD, Address VDAddr,
19115ffd83dbSDimitry Andric                                           SourceLocation Loc);
19125ffd83dbSDimitry Andric 
19135ffd83dbSDimitry Andric     /// Gets the OpenMP-specific address of the local variable /p VD.
19145ffd83dbSDimitry Andric     static Address getAddressOfLocalVariable(CodeGenFunction &CGF,
19155ffd83dbSDimitry Andric                                              const VarDecl *VD);
19165ffd83dbSDimitry Andric     /// Get the platform-specific name separator.
19175ffd83dbSDimitry Andric     /// \param Parts different parts of the final name that needs separation
19185ffd83dbSDimitry Andric     /// \param FirstSeparator First separator used between the initial two
19195ffd83dbSDimitry Andric     ///        parts of the name.
19205ffd83dbSDimitry Andric     /// \param Separator separator used between all of the rest consecutinve
19215ffd83dbSDimitry Andric     ///        parts of the name
19225ffd83dbSDimitry Andric     static std::string getNameWithSeparators(ArrayRef<StringRef> Parts,
19235ffd83dbSDimitry Andric                                              StringRef FirstSeparator = ".",
19245ffd83dbSDimitry Andric                                              StringRef Separator = ".");
19255ffd83dbSDimitry Andric     /// Emit the Finalization for an OMP region
19265ffd83dbSDimitry Andric     /// \param CGF	The Codegen function this belongs to
19275ffd83dbSDimitry Andric     /// \param IP	Insertion point for generating the finalization code.
19285ffd83dbSDimitry Andric     static void FinalizeOMPRegion(CodeGenFunction &CGF, InsertPointTy IP) {
19295ffd83dbSDimitry Andric       CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
19305ffd83dbSDimitry Andric       assert(IP.getBlock()->end() != IP.getPoint() &&
19315ffd83dbSDimitry Andric              "OpenMP IR Builder should cause terminated block!");
19325ffd83dbSDimitry Andric 
19335ffd83dbSDimitry Andric       llvm::BasicBlock *IPBB = IP.getBlock();
19345ffd83dbSDimitry Andric       llvm::BasicBlock *DestBB = IPBB->getUniqueSuccessor();
19355ffd83dbSDimitry Andric       assert(DestBB && "Finalization block should have one successor!");
19365ffd83dbSDimitry Andric 
19375ffd83dbSDimitry Andric       // erase and replace with cleanup branch.
19385ffd83dbSDimitry Andric       IPBB->getTerminator()->eraseFromParent();
19395ffd83dbSDimitry Andric       CGF.Builder.SetInsertPoint(IPBB);
19405ffd83dbSDimitry Andric       CodeGenFunction::JumpDest Dest = CGF.getJumpDestInCurrentScope(DestBB);
19415ffd83dbSDimitry Andric       CGF.EmitBranchThroughCleanup(Dest);
19425ffd83dbSDimitry Andric     }
19435ffd83dbSDimitry Andric 
19445ffd83dbSDimitry Andric     /// Emit the body of an OMP region
19455ffd83dbSDimitry Andric     /// \param CGF	          The Codegen function this belongs to
19465ffd83dbSDimitry Andric     /// \param RegionBodyStmt The body statement for the OpenMP region being
19475ffd83dbSDimitry Andric     ///                       generated
194881ad6265SDimitry Andric     /// \param AllocaIP       Where to insert alloca instructions
194981ad6265SDimitry Andric     /// \param CodeGenIP      Where to insert the region code
195081ad6265SDimitry Andric     /// \param RegionName     Name to be used for new blocks
195181ad6265SDimitry Andric     static void EmitOMPInlinedRegionBody(CodeGenFunction &CGF,
19525ffd83dbSDimitry Andric                                          const Stmt *RegionBodyStmt,
195381ad6265SDimitry Andric                                          InsertPointTy AllocaIP,
19545ffd83dbSDimitry Andric                                          InsertPointTy CodeGenIP,
195581ad6265SDimitry Andric                                          Twine RegionName);
19565ffd83dbSDimitry Andric 
1957349cc55cSDimitry Andric     static void EmitCaptureStmt(CodeGenFunction &CGF, InsertPointTy CodeGenIP,
1958349cc55cSDimitry Andric                                 llvm::BasicBlock &FiniBB, llvm::Function *Fn,
1959349cc55cSDimitry Andric                                 ArrayRef<llvm::Value *> Args) {
1960349cc55cSDimitry Andric       llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock();
1961349cc55cSDimitry Andric       if (llvm::Instruction *CodeGenIPBBTI = CodeGenIPBB->getTerminator())
1962349cc55cSDimitry Andric         CodeGenIPBBTI->eraseFromParent();
1963349cc55cSDimitry Andric 
1964349cc55cSDimitry Andric       CGF.Builder.SetInsertPoint(CodeGenIPBB);
1965349cc55cSDimitry Andric 
1966349cc55cSDimitry Andric       if (Fn->doesNotThrow())
1967349cc55cSDimitry Andric         CGF.EmitNounwindRuntimeCall(Fn, Args);
1968349cc55cSDimitry Andric       else
1969349cc55cSDimitry Andric         CGF.EmitRuntimeCall(Fn, Args);
1970349cc55cSDimitry Andric 
1971349cc55cSDimitry Andric       if (CGF.Builder.saveIP().isSet())
1972349cc55cSDimitry Andric         CGF.Builder.CreateBr(&FiniBB);
1973349cc55cSDimitry Andric     }
1974349cc55cSDimitry Andric 
197581ad6265SDimitry Andric     /// Emit the body of an OMP region that will be outlined in
197681ad6265SDimitry Andric     /// OpenMPIRBuilder::finalize().
197781ad6265SDimitry Andric     /// \param CGF	          The Codegen function this belongs to
197881ad6265SDimitry Andric     /// \param RegionBodyStmt The body statement for the OpenMP region being
197981ad6265SDimitry Andric     ///                       generated
198081ad6265SDimitry Andric     /// \param AllocaIP       Where to insert alloca instructions
198181ad6265SDimitry Andric     /// \param CodeGenIP      Where to insert the region code
198281ad6265SDimitry Andric     /// \param RegionName     Name to be used for new blocks
198381ad6265SDimitry Andric     static void EmitOMPOutlinedRegionBody(CodeGenFunction &CGF,
198481ad6265SDimitry Andric                                           const Stmt *RegionBodyStmt,
198581ad6265SDimitry Andric                                           InsertPointTy AllocaIP,
198681ad6265SDimitry Andric                                           InsertPointTy CodeGenIP,
198781ad6265SDimitry Andric                                           Twine RegionName);
198881ad6265SDimitry Andric 
19895ffd83dbSDimitry Andric     /// RAII for preserving necessary info during Outlined region body codegen.
19905ffd83dbSDimitry Andric     class OutlinedRegionBodyRAII {
19915ffd83dbSDimitry Andric 
19925ffd83dbSDimitry Andric       llvm::AssertingVH<llvm::Instruction> OldAllocaIP;
19935ffd83dbSDimitry Andric       CodeGenFunction::JumpDest OldReturnBlock;
19945ffd83dbSDimitry Andric       CodeGenFunction &CGF;
19955ffd83dbSDimitry Andric 
19965ffd83dbSDimitry Andric     public:
19975ffd83dbSDimitry Andric       OutlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP,
19985ffd83dbSDimitry Andric                              llvm::BasicBlock &RetBB)
19995ffd83dbSDimitry Andric           : CGF(cgf) {
20005ffd83dbSDimitry Andric         assert(AllocaIP.isSet() &&
20015ffd83dbSDimitry Andric                "Must specify Insertion point for allocas of outlined function");
20025ffd83dbSDimitry Andric         OldAllocaIP = CGF.AllocaInsertPt;
20035ffd83dbSDimitry Andric         CGF.AllocaInsertPt = &*AllocaIP.getPoint();
20045ffd83dbSDimitry Andric 
20055ffd83dbSDimitry Andric         OldReturnBlock = CGF.ReturnBlock;
20065ffd83dbSDimitry Andric         CGF.ReturnBlock = CGF.getJumpDestInCurrentScope(&RetBB);
20075ffd83dbSDimitry Andric       }
20085ffd83dbSDimitry Andric 
20095ffd83dbSDimitry Andric       ~OutlinedRegionBodyRAII() {
20105ffd83dbSDimitry Andric         CGF.AllocaInsertPt = OldAllocaIP;
20115ffd83dbSDimitry Andric         CGF.ReturnBlock = OldReturnBlock;
20125ffd83dbSDimitry Andric       }
20135ffd83dbSDimitry Andric     };
20145ffd83dbSDimitry Andric 
20155ffd83dbSDimitry Andric     /// RAII for preserving necessary info during inlined region body codegen.
20165ffd83dbSDimitry Andric     class InlinedRegionBodyRAII {
20175ffd83dbSDimitry Andric 
20185ffd83dbSDimitry Andric       llvm::AssertingVH<llvm::Instruction> OldAllocaIP;
20195ffd83dbSDimitry Andric       CodeGenFunction &CGF;
20205ffd83dbSDimitry Andric 
20215ffd83dbSDimitry Andric     public:
20225ffd83dbSDimitry Andric       InlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP,
20235ffd83dbSDimitry Andric                             llvm::BasicBlock &FiniBB)
20245ffd83dbSDimitry Andric           : CGF(cgf) {
20255ffd83dbSDimitry Andric         // Alloca insertion block should be in the entry block of the containing
20265ffd83dbSDimitry Andric         // function so it expects an empty AllocaIP in which case will reuse the
20275ffd83dbSDimitry Andric         // old alloca insertion point, or a new AllocaIP in the same block as
20285ffd83dbSDimitry Andric         // the old one
20295ffd83dbSDimitry Andric         assert((!AllocaIP.isSet() ||
20305ffd83dbSDimitry Andric                 CGF.AllocaInsertPt->getParent() == AllocaIP.getBlock()) &&
20315ffd83dbSDimitry Andric                "Insertion point should be in the entry block of containing "
20325ffd83dbSDimitry Andric                "function!");
20335ffd83dbSDimitry Andric         OldAllocaIP = CGF.AllocaInsertPt;
20345ffd83dbSDimitry Andric         if (AllocaIP.isSet())
20355ffd83dbSDimitry Andric           CGF.AllocaInsertPt = &*AllocaIP.getPoint();
20365ffd83dbSDimitry Andric 
20375ffd83dbSDimitry Andric         // TODO: Remove the call, after making sure the counter is not used by
20385ffd83dbSDimitry Andric         //       the EHStack.
20395ffd83dbSDimitry Andric         // Since this is an inlined region, it should not modify the
20405ffd83dbSDimitry Andric         // ReturnBlock, and should reuse the one for the enclosing outlined
20415ffd83dbSDimitry Andric         // region. So, the JumpDest being return by the function is discarded
20425ffd83dbSDimitry Andric         (void)CGF.getJumpDestInCurrentScope(&FiniBB);
20435ffd83dbSDimitry Andric       }
20445ffd83dbSDimitry Andric 
20455ffd83dbSDimitry Andric       ~InlinedRegionBodyRAII() { CGF.AllocaInsertPt = OldAllocaIP; }
20465ffd83dbSDimitry Andric     };
20475ffd83dbSDimitry Andric   };
20485ffd83dbSDimitry Andric 
20490b57cec5SDimitry Andric private:
20500b57cec5SDimitry Andric   /// CXXThisDecl - When generating code for a C++ member function,
20510b57cec5SDimitry Andric   /// this will hold the implicit 'this' declaration.
20520b57cec5SDimitry Andric   ImplicitParamDecl *CXXABIThisDecl = nullptr;
20530b57cec5SDimitry Andric   llvm::Value *CXXABIThisValue = nullptr;
20540b57cec5SDimitry Andric   llvm::Value *CXXThisValue = nullptr;
20550b57cec5SDimitry Andric   CharUnits CXXABIThisAlignment;
20560b57cec5SDimitry Andric   CharUnits CXXThisAlignment;
20570b57cec5SDimitry Andric 
20580b57cec5SDimitry Andric   /// The value of 'this' to use when evaluating CXXDefaultInitExprs within
20590b57cec5SDimitry Andric   /// this expression.
20600b57cec5SDimitry Andric   Address CXXDefaultInitExprThis = Address::invalid();
20610b57cec5SDimitry Andric 
20620b57cec5SDimitry Andric   /// The current array initialization index when evaluating an
20630b57cec5SDimitry Andric   /// ArrayInitIndexExpr within an ArrayInitLoopExpr.
20640b57cec5SDimitry Andric   llvm::Value *ArrayInitIndex = nullptr;
20650b57cec5SDimitry Andric 
20660b57cec5SDimitry Andric   /// The values of function arguments to use when evaluating
20670b57cec5SDimitry Andric   /// CXXInheritedCtorInitExprs within this context.
20680b57cec5SDimitry Andric   CallArgList CXXInheritedCtorInitExprArgs;
20690b57cec5SDimitry Andric 
20700b57cec5SDimitry Andric   /// CXXStructorImplicitParamDecl - When generating code for a constructor or
20710b57cec5SDimitry Andric   /// destructor, this will hold the implicit argument (e.g. VTT).
20720b57cec5SDimitry Andric   ImplicitParamDecl *CXXStructorImplicitParamDecl = nullptr;
20730b57cec5SDimitry Andric   llvm::Value *CXXStructorImplicitParamValue = nullptr;
20740b57cec5SDimitry Andric 
20750b57cec5SDimitry Andric   /// OutermostConditional - Points to the outermost active
20760b57cec5SDimitry Andric   /// conditional control.  This is used so that we know if a
20770b57cec5SDimitry Andric   /// temporary should be destroyed conditionally.
20780b57cec5SDimitry Andric   ConditionalEvaluation *OutermostConditional = nullptr;
20790b57cec5SDimitry Andric 
20800b57cec5SDimitry Andric   /// The current lexical scope.
20810b57cec5SDimitry Andric   LexicalScope *CurLexicalScope = nullptr;
20820b57cec5SDimitry Andric 
20830b57cec5SDimitry Andric   /// The current source location that should be used for exception
20840b57cec5SDimitry Andric   /// handling code.
20850b57cec5SDimitry Andric   SourceLocation CurEHLocation;
20860b57cec5SDimitry Andric 
20870b57cec5SDimitry Andric   /// BlockByrefInfos - For each __block variable, contains
20880b57cec5SDimitry Andric   /// information about the layout of the variable.
20890b57cec5SDimitry Andric   llvm::DenseMap<const ValueDecl *, BlockByrefInfo> BlockByrefInfos;
20900b57cec5SDimitry Andric 
20910b57cec5SDimitry Andric   /// Used by -fsanitize=nullability-return to determine whether the return
20920b57cec5SDimitry Andric   /// value can be checked.
20930b57cec5SDimitry Andric   llvm::Value *RetValNullabilityPrecondition = nullptr;
20940b57cec5SDimitry Andric 
20950b57cec5SDimitry Andric   /// Check if -fsanitize=nullability-return instrumentation is required for
20960b57cec5SDimitry Andric   /// this function.
20970b57cec5SDimitry Andric   bool requiresReturnValueNullabilityCheck() const {
20980b57cec5SDimitry Andric     return RetValNullabilityPrecondition;
20990b57cec5SDimitry Andric   }
21000b57cec5SDimitry Andric 
21010b57cec5SDimitry Andric   /// Used to store precise source locations for return statements by the
21020b57cec5SDimitry Andric   /// runtime return value checks.
21030b57cec5SDimitry Andric   Address ReturnLocation = Address::invalid();
21040b57cec5SDimitry Andric 
21050b57cec5SDimitry Andric   /// Check if the return value of this function requires sanitization.
2106480093f4SDimitry Andric   bool requiresReturnValueCheck() const;
21070b57cec5SDimitry Andric 
21088a4dda33SDimitry Andric   bool isInAllocaArgument(CGCXXABI &ABI, QualType Ty);
21098a4dda33SDimitry Andric   bool hasInAllocaArg(const CXXMethodDecl *MD);
21108a4dda33SDimitry Andric 
21110b57cec5SDimitry Andric   llvm::BasicBlock *TerminateLandingPad = nullptr;
21120b57cec5SDimitry Andric   llvm::BasicBlock *TerminateHandler = nullptr;
2113e8d8bef9SDimitry Andric   llvm::SmallVector<llvm::BasicBlock *, 2> TrapBBs;
21140b57cec5SDimitry Andric 
21150b57cec5SDimitry Andric   /// Terminate funclets keyed by parent funclet pad.
21160b57cec5SDimitry Andric   llvm::MapVector<llvm::Value *, llvm::BasicBlock *> TerminateFunclets;
21170b57cec5SDimitry Andric 
21180b57cec5SDimitry Andric   /// Largest vector width used in ths function. Will be used to create a
21190b57cec5SDimitry Andric   /// function attribute.
21200b57cec5SDimitry Andric   unsigned LargestVectorWidth = 0;
21210b57cec5SDimitry Andric 
2122fe6060f1SDimitry Andric   /// True if we need emit the life-time markers. This is initially set in
2123fe6060f1SDimitry Andric   /// the constructor, but could be overwritten to true if this is a coroutine.
2124fe6060f1SDimitry Andric   bool ShouldEmitLifetimeMarkers;
21250b57cec5SDimitry Andric 
21260b57cec5SDimitry Andric   /// Add OpenCL kernel arg metadata and the kernel attribute metadata to
21270b57cec5SDimitry Andric   /// the function metadata.
212881ad6265SDimitry Andric   void EmitKernelMetadata(const FunctionDecl *FD, llvm::Function *Fn);
21290b57cec5SDimitry Andric 
21300b57cec5SDimitry Andric public:
21310b57cec5SDimitry Andric   CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext=false);
21320b57cec5SDimitry Andric   ~CodeGenFunction();
21330b57cec5SDimitry Andric 
21340b57cec5SDimitry Andric   CodeGenTypes &getTypes() const { return CGM.getTypes(); }
21350b57cec5SDimitry Andric   ASTContext &getContext() const { return CGM.getContext(); }
21360b57cec5SDimitry Andric   CGDebugInfo *getDebugInfo() {
21370b57cec5SDimitry Andric     if (DisableDebugInfo)
21380b57cec5SDimitry Andric       return nullptr;
21390b57cec5SDimitry Andric     return DebugInfo;
21400b57cec5SDimitry Andric   }
21410b57cec5SDimitry Andric   void disableDebugInfo() { DisableDebugInfo = true; }
21420b57cec5SDimitry Andric   void enableDebugInfo() { DisableDebugInfo = false; }
21430b57cec5SDimitry Andric 
21440b57cec5SDimitry Andric   bool shouldUseFusedARCCalls() {
21450b57cec5SDimitry Andric     return CGM.getCodeGenOpts().OptimizationLevel == 0;
21460b57cec5SDimitry Andric   }
21470b57cec5SDimitry Andric 
21480b57cec5SDimitry Andric   const LangOptions &getLangOpts() const { return CGM.getLangOpts(); }
21490b57cec5SDimitry Andric 
21500b57cec5SDimitry Andric   /// Returns a pointer to the function's exception object and selector slot,
21510b57cec5SDimitry Andric   /// which is assigned in every landing pad.
21520b57cec5SDimitry Andric   Address getExceptionSlot();
21530b57cec5SDimitry Andric   Address getEHSelectorSlot();
21540b57cec5SDimitry Andric 
21550b57cec5SDimitry Andric   /// Returns the contents of the function's exception object and selector
21560b57cec5SDimitry Andric   /// slots.
21570b57cec5SDimitry Andric   llvm::Value *getExceptionFromSlot();
21580b57cec5SDimitry Andric   llvm::Value *getSelectorFromSlot();
21590b57cec5SDimitry Andric 
21600fca6ea1SDimitry Andric   RawAddress getNormalCleanupDestSlot();
21610b57cec5SDimitry Andric 
21620b57cec5SDimitry Andric   llvm::BasicBlock *getUnreachableBlock() {
21630b57cec5SDimitry Andric     if (!UnreachableBlock) {
21640b57cec5SDimitry Andric       UnreachableBlock = createBasicBlock("unreachable");
21650b57cec5SDimitry Andric       new llvm::UnreachableInst(getLLVMContext(), UnreachableBlock);
21660b57cec5SDimitry Andric     }
21670b57cec5SDimitry Andric     return UnreachableBlock;
21680b57cec5SDimitry Andric   }
21690b57cec5SDimitry Andric 
21700b57cec5SDimitry Andric   llvm::BasicBlock *getInvokeDest() {
21710b57cec5SDimitry Andric     if (!EHStack.requiresLandingPad()) return nullptr;
21720b57cec5SDimitry Andric     return getInvokeDestImpl();
21730b57cec5SDimitry Andric   }
21740b57cec5SDimitry Andric 
2175bdd1243dSDimitry Andric   bool currentFunctionUsesSEHTry() const { return !!CurSEHParent; }
21760b57cec5SDimitry Andric 
21770b57cec5SDimitry Andric   const TargetInfo &getTarget() const { return Target; }
21780b57cec5SDimitry Andric   llvm::LLVMContext &getLLVMContext() { return CGM.getLLVMContext(); }
21790b57cec5SDimitry Andric   const TargetCodeGenInfo &getTargetHooks() const {
21800b57cec5SDimitry Andric     return CGM.getTargetCodeGenInfo();
21810b57cec5SDimitry Andric   }
21820b57cec5SDimitry Andric 
21830b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
21840b57cec5SDimitry Andric   //                                  Cleanups
21850b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
21860b57cec5SDimitry Andric 
21870b57cec5SDimitry Andric   typedef void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty);
21880b57cec5SDimitry Andric 
21890b57cec5SDimitry Andric   void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
21900b57cec5SDimitry Andric                                         Address arrayEndPointer,
21910b57cec5SDimitry Andric                                         QualType elementType,
21920b57cec5SDimitry Andric                                         CharUnits elementAlignment,
21930b57cec5SDimitry Andric                                         Destroyer *destroyer);
21940b57cec5SDimitry Andric   void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin,
21950b57cec5SDimitry Andric                                       llvm::Value *arrayEnd,
21960b57cec5SDimitry Andric                                       QualType elementType,
21970b57cec5SDimitry Andric                                       CharUnits elementAlignment,
21980b57cec5SDimitry Andric                                       Destroyer *destroyer);
21990b57cec5SDimitry Andric 
22000b57cec5SDimitry Andric   void pushDestroy(QualType::DestructionKind dtorKind,
22010b57cec5SDimitry Andric                    Address addr, QualType type);
22020b57cec5SDimitry Andric   void pushEHDestroy(QualType::DestructionKind dtorKind,
22030b57cec5SDimitry Andric                      Address addr, QualType type);
22040b57cec5SDimitry Andric   void pushDestroy(CleanupKind kind, Address addr, QualType type,
22050b57cec5SDimitry Andric                    Destroyer *destroyer, bool useEHCleanupForArray);
22060fca6ea1SDimitry Andric   void pushDestroyAndDeferDeactivation(QualType::DestructionKind dtorKind,
22070fca6ea1SDimitry Andric                                        Address addr, QualType type);
22080fca6ea1SDimitry Andric   void pushDestroyAndDeferDeactivation(CleanupKind cleanupKind, Address addr,
22090fca6ea1SDimitry Andric                                        QualType type, Destroyer *destroyer,
22100fca6ea1SDimitry Andric                                        bool useEHCleanupForArray);
22110b57cec5SDimitry Andric   void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr,
22120b57cec5SDimitry Andric                                    QualType type, Destroyer *destroyer,
22130b57cec5SDimitry Andric                                    bool useEHCleanupForArray);
22140b57cec5SDimitry Andric   void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete,
22150b57cec5SDimitry Andric                                    llvm::Value *CompletePtr,
22160b57cec5SDimitry Andric                                    QualType ElementType);
22170b57cec5SDimitry Andric   void pushStackRestore(CleanupKind kind, Address SPMem);
221806c3fb27SDimitry Andric   void pushKmpcAllocFree(CleanupKind Kind,
221906c3fb27SDimitry Andric                          std::pair<llvm::Value *, llvm::Value *> AddrSizePair);
22200b57cec5SDimitry Andric   void emitDestroy(Address addr, QualType type, Destroyer *destroyer,
22210b57cec5SDimitry Andric                    bool useEHCleanupForArray);
22220b57cec5SDimitry Andric   llvm::Function *generateDestroyHelper(Address addr, QualType type,
22230b57cec5SDimitry Andric                                         Destroyer *destroyer,
22240b57cec5SDimitry Andric                                         bool useEHCleanupForArray,
22250b57cec5SDimitry Andric                                         const VarDecl *VD);
22260b57cec5SDimitry Andric   void emitArrayDestroy(llvm::Value *begin, llvm::Value *end,
22270b57cec5SDimitry Andric                         QualType elementType, CharUnits elementAlign,
22280b57cec5SDimitry Andric                         Destroyer *destroyer,
22290b57cec5SDimitry Andric                         bool checkZeroLength, bool useEHCleanup);
22300b57cec5SDimitry Andric 
22310b57cec5SDimitry Andric   Destroyer *getDestroyer(QualType::DestructionKind destructionKind);
22320b57cec5SDimitry Andric 
22330b57cec5SDimitry Andric   /// Determines whether an EH cleanup is required to destroy a type
22340b57cec5SDimitry Andric   /// with the given destruction kind.
22350b57cec5SDimitry Andric   bool needsEHCleanup(QualType::DestructionKind kind) {
22360b57cec5SDimitry Andric     switch (kind) {
22370b57cec5SDimitry Andric     case QualType::DK_none:
22380b57cec5SDimitry Andric       return false;
22390b57cec5SDimitry Andric     case QualType::DK_cxx_destructor:
22400b57cec5SDimitry Andric     case QualType::DK_objc_weak_lifetime:
22410b57cec5SDimitry Andric     case QualType::DK_nontrivial_c_struct:
22420b57cec5SDimitry Andric       return getLangOpts().Exceptions;
22430b57cec5SDimitry Andric     case QualType::DK_objc_strong_lifetime:
22440b57cec5SDimitry Andric       return getLangOpts().Exceptions &&
22450b57cec5SDimitry Andric              CGM.getCodeGenOpts().ObjCAutoRefCountExceptions;
22460b57cec5SDimitry Andric     }
22470b57cec5SDimitry Andric     llvm_unreachable("bad destruction kind");
22480b57cec5SDimitry Andric   }
22490b57cec5SDimitry Andric 
22500b57cec5SDimitry Andric   CleanupKind getCleanupKind(QualType::DestructionKind kind) {
22510b57cec5SDimitry Andric     return (needsEHCleanup(kind) ? NormalAndEHCleanup : NormalCleanup);
22520b57cec5SDimitry Andric   }
22530b57cec5SDimitry Andric 
22540b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
22550b57cec5SDimitry Andric   //                                  Objective-C
22560b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
22570b57cec5SDimitry Andric 
22580b57cec5SDimitry Andric   void GenerateObjCMethod(const ObjCMethodDecl *OMD);
22590b57cec5SDimitry Andric 
22600b57cec5SDimitry Andric   void StartObjCMethod(const ObjCMethodDecl *MD, const ObjCContainerDecl *CD);
22610b57cec5SDimitry Andric 
22620b57cec5SDimitry Andric   /// GenerateObjCGetter - Synthesize an Objective-C property getter function.
22630b57cec5SDimitry Andric   void GenerateObjCGetter(ObjCImplementationDecl *IMP,
22640b57cec5SDimitry Andric                           const ObjCPropertyImplDecl *PID);
22650b57cec5SDimitry Andric   void generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
22660b57cec5SDimitry Andric                               const ObjCPropertyImplDecl *propImpl,
22670b57cec5SDimitry Andric                               const ObjCMethodDecl *GetterMothodDecl,
22680b57cec5SDimitry Andric                               llvm::Constant *AtomicHelperFn);
22690b57cec5SDimitry Andric 
22700b57cec5SDimitry Andric   void GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
22710b57cec5SDimitry Andric                                   ObjCMethodDecl *MD, bool ctor);
22720b57cec5SDimitry Andric 
22730b57cec5SDimitry Andric   /// GenerateObjCSetter - Synthesize an Objective-C property setter function
22740b57cec5SDimitry Andric   /// for the given property.
22750b57cec5SDimitry Andric   void GenerateObjCSetter(ObjCImplementationDecl *IMP,
22760b57cec5SDimitry Andric                           const ObjCPropertyImplDecl *PID);
22770b57cec5SDimitry Andric   void generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
22780b57cec5SDimitry Andric                               const ObjCPropertyImplDecl *propImpl,
22790b57cec5SDimitry Andric                               llvm::Constant *AtomicHelperFn);
22800b57cec5SDimitry Andric 
22810b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
22820b57cec5SDimitry Andric   //                                  Block Bits
22830b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
22840b57cec5SDimitry Andric 
22850b57cec5SDimitry Andric   /// Emit block literal.
22860b57cec5SDimitry Andric   /// \return an LLVM value which is a pointer to a struct which contains
22870b57cec5SDimitry Andric   /// information about the block, including the block invoke function, the
22880b57cec5SDimitry Andric   /// captured variables, etc.
22890b57cec5SDimitry Andric   llvm::Value *EmitBlockLiteral(const BlockExpr *);
22900b57cec5SDimitry Andric 
22910b57cec5SDimitry Andric   llvm::Function *GenerateBlockFunction(GlobalDecl GD,
22920b57cec5SDimitry Andric                                         const CGBlockInfo &Info,
22930b57cec5SDimitry Andric                                         const DeclMapTy &ldm,
22940b57cec5SDimitry Andric                                         bool IsLambdaConversionToBlock,
22950b57cec5SDimitry Andric                                         bool BuildGlobalBlock);
22960b57cec5SDimitry Andric 
22970b57cec5SDimitry Andric   /// Check if \p T is a C++ class that has a destructor that can throw.
22980b57cec5SDimitry Andric   static bool cxxDestructorCanThrow(QualType T);
22990b57cec5SDimitry Andric 
23000b57cec5SDimitry Andric   llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo);
23010b57cec5SDimitry Andric   llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo);
23020b57cec5SDimitry Andric   llvm::Constant *GenerateObjCAtomicSetterCopyHelperFunction(
23030b57cec5SDimitry Andric                                              const ObjCPropertyImplDecl *PID);
23040b57cec5SDimitry Andric   llvm::Constant *GenerateObjCAtomicGetterCopyHelperFunction(
23050b57cec5SDimitry Andric                                              const ObjCPropertyImplDecl *PID);
23060b57cec5SDimitry Andric   llvm::Value *EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty);
23070b57cec5SDimitry Andric 
23080b57cec5SDimitry Andric   void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags,
23090b57cec5SDimitry Andric                          bool CanThrow);
23100b57cec5SDimitry Andric 
23110b57cec5SDimitry Andric   class AutoVarEmission;
23120b57cec5SDimitry Andric 
23130b57cec5SDimitry Andric   void emitByrefStructureInit(const AutoVarEmission &emission);
23140b57cec5SDimitry Andric 
23150b57cec5SDimitry Andric   /// Enter a cleanup to destroy a __block variable.  Note that this
23160b57cec5SDimitry Andric   /// cleanup should be a no-op if the variable hasn't left the stack
23170b57cec5SDimitry Andric   /// yet; if a cleanup is required for the variable itself, that needs
23180b57cec5SDimitry Andric   /// to be done externally.
23190b57cec5SDimitry Andric   ///
23200b57cec5SDimitry Andric   /// \param Kind Cleanup kind.
23210b57cec5SDimitry Andric   ///
23220b57cec5SDimitry Andric   /// \param Addr When \p LoadBlockVarAddr is false, the address of the __block
23230b57cec5SDimitry Andric   /// structure that will be passed to _Block_object_dispose. When
23240b57cec5SDimitry Andric   /// \p LoadBlockVarAddr is true, the address of the field of the block
23250b57cec5SDimitry Andric   /// structure that holds the address of the __block structure.
23260b57cec5SDimitry Andric   ///
23270b57cec5SDimitry Andric   /// \param Flags The flag that will be passed to _Block_object_dispose.
23280b57cec5SDimitry Andric   ///
23290b57cec5SDimitry Andric   /// \param LoadBlockVarAddr Indicates whether we need to emit a load from
23300b57cec5SDimitry Andric   /// \p Addr to get the address of the __block structure.
23310b57cec5SDimitry Andric   void enterByrefCleanup(CleanupKind Kind, Address Addr, BlockFieldFlags Flags,
23320b57cec5SDimitry Andric                          bool LoadBlockVarAddr, bool CanThrow);
23330b57cec5SDimitry Andric 
23340b57cec5SDimitry Andric   void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum,
23350b57cec5SDimitry Andric                                 llvm::Value *ptr);
23360b57cec5SDimitry Andric 
23370b57cec5SDimitry Andric   Address LoadBlockStruct();
23380b57cec5SDimitry Andric   Address GetAddrOfBlockDecl(const VarDecl *var);
23390b57cec5SDimitry Andric 
23400b57cec5SDimitry Andric   /// BuildBlockByrefAddress - Computes the location of the
23410b57cec5SDimitry Andric   /// data in a variable which is declared as __block.
23420b57cec5SDimitry Andric   Address emitBlockByrefAddress(Address baseAddr, const VarDecl *V,
23430b57cec5SDimitry Andric                                 bool followForward = true);
23440b57cec5SDimitry Andric   Address emitBlockByrefAddress(Address baseAddr,
23450b57cec5SDimitry Andric                                 const BlockByrefInfo &info,
23460b57cec5SDimitry Andric                                 bool followForward,
23470b57cec5SDimitry Andric                                 const llvm::Twine &name);
23480b57cec5SDimitry Andric 
23490b57cec5SDimitry Andric   const BlockByrefInfo &getBlockByrefInfo(const VarDecl *var);
23500b57cec5SDimitry Andric 
23510b57cec5SDimitry Andric   QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args);
23520b57cec5SDimitry Andric 
23530b57cec5SDimitry Andric   void GenerateCode(GlobalDecl GD, llvm::Function *Fn,
23540b57cec5SDimitry Andric                     const CGFunctionInfo &FnInfo);
23550b57cec5SDimitry Andric 
23560b57cec5SDimitry Andric   /// Annotate the function with an attribute that disables TSan checking at
23570b57cec5SDimitry Andric   /// runtime.
23580b57cec5SDimitry Andric   void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn);
23590b57cec5SDimitry Andric 
23600b57cec5SDimitry Andric   /// Emit code for the start of a function.
23610b57cec5SDimitry Andric   /// \param Loc       The location to be associated with the function.
23620b57cec5SDimitry Andric   /// \param StartLoc  The location of the function body.
23630b57cec5SDimitry Andric   void StartFunction(GlobalDecl GD,
23640b57cec5SDimitry Andric                      QualType RetTy,
23650b57cec5SDimitry Andric                      llvm::Function *Fn,
23660b57cec5SDimitry Andric                      const CGFunctionInfo &FnInfo,
23670b57cec5SDimitry Andric                      const FunctionArgList &Args,
23680b57cec5SDimitry Andric                      SourceLocation Loc = SourceLocation(),
23690b57cec5SDimitry Andric                      SourceLocation StartLoc = SourceLocation());
23700b57cec5SDimitry Andric 
23710b57cec5SDimitry Andric   static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor);
23720b57cec5SDimitry Andric 
23730b57cec5SDimitry Andric   void EmitConstructorBody(FunctionArgList &Args);
23740b57cec5SDimitry Andric   void EmitDestructorBody(FunctionArgList &Args);
23750b57cec5SDimitry Andric   void emitImplicitAssignmentOperatorBody(FunctionArgList &Args);
23760b57cec5SDimitry Andric   void EmitFunctionBody(const Stmt *Body);
23770b57cec5SDimitry Andric   void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S);
23780b57cec5SDimitry Andric 
23790b57cec5SDimitry Andric   void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator,
23808a4dda33SDimitry Andric                                   CallArgList &CallArgs,
23818a4dda33SDimitry Andric                                   const CGFunctionInfo *CallOpFnInfo = nullptr,
23828a4dda33SDimitry Andric                                   llvm::Constant *CallOpFn = nullptr);
23830b57cec5SDimitry Andric   void EmitLambdaBlockInvokeBody();
23840b57cec5SDimitry Andric   void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD);
23858a4dda33SDimitry Andric   void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD,
23868a4dda33SDimitry Andric                                       CallArgList &CallArgs);
23878a4dda33SDimitry Andric   void EmitLambdaInAllocaImplFn(const CXXMethodDecl *CallOp,
23888a4dda33SDimitry Andric                                 const CGFunctionInfo **ImplFnInfo,
23898a4dda33SDimitry Andric                                 llvm::Function **ImplFn);
23908a4dda33SDimitry Andric   void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD);
23910b57cec5SDimitry Andric   void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV) {
23920b57cec5SDimitry Andric     EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
23930b57cec5SDimitry Andric   }
23940b57cec5SDimitry Andric   void EmitAsanPrologueOrEpilogue(bool Prologue);
23950b57cec5SDimitry Andric 
23960b57cec5SDimitry Andric   /// Emit the unified return block, trying to avoid its emission when
23970b57cec5SDimitry Andric   /// possible.
23980b57cec5SDimitry Andric   /// \return The debug location of the user written return statement if the
2399bdd1243dSDimitry Andric   /// return block is avoided.
24000b57cec5SDimitry Andric   llvm::DebugLoc EmitReturnBlock();
24010b57cec5SDimitry Andric 
24020b57cec5SDimitry Andric   /// FinishFunction - Complete IR generation of the current function. It is
24030b57cec5SDimitry Andric   /// legal to call this function even if there is no current insertion point.
24040b57cec5SDimitry Andric   void FinishFunction(SourceLocation EndLoc=SourceLocation());
24050b57cec5SDimitry Andric 
24060b57cec5SDimitry Andric   void StartThunk(llvm::Function *Fn, GlobalDecl GD,
24070b57cec5SDimitry Andric                   const CGFunctionInfo &FnInfo, bool IsUnprototyped);
24080b57cec5SDimitry Andric 
24090b57cec5SDimitry Andric   void EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
24100b57cec5SDimitry Andric                                  const ThunkInfo *Thunk, bool IsUnprototyped);
24110b57cec5SDimitry Andric 
24120b57cec5SDimitry Andric   void FinishThunk();
24130b57cec5SDimitry Andric 
24140b57cec5SDimitry Andric   /// Emit a musttail call for a thunk with a potentially adjusted this pointer.
24150b57cec5SDimitry Andric   void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr,
24160b57cec5SDimitry Andric                          llvm::FunctionCallee Callee);
24170b57cec5SDimitry Andric 
24180b57cec5SDimitry Andric   /// Generate a thunk for the given method.
24190b57cec5SDimitry Andric   void generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo,
24200b57cec5SDimitry Andric                      GlobalDecl GD, const ThunkInfo &Thunk,
24210b57cec5SDimitry Andric                      bool IsUnprototyped);
24220b57cec5SDimitry Andric 
24230b57cec5SDimitry Andric   llvm::Function *GenerateVarArgsThunk(llvm::Function *Fn,
24240b57cec5SDimitry Andric                                        const CGFunctionInfo &FnInfo,
24250b57cec5SDimitry Andric                                        GlobalDecl GD, const ThunkInfo &Thunk);
24260b57cec5SDimitry Andric 
24270b57cec5SDimitry Andric   void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type,
24280b57cec5SDimitry Andric                         FunctionArgList &Args);
24290b57cec5SDimitry Andric 
24300b57cec5SDimitry Andric   void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init);
24310b57cec5SDimitry Andric 
24320b57cec5SDimitry Andric   /// Struct with all information about dynamic [sub]class needed to set vptr.
24330b57cec5SDimitry Andric   struct VPtr {
24340b57cec5SDimitry Andric     BaseSubobject Base;
24350b57cec5SDimitry Andric     const CXXRecordDecl *NearestVBase;
24360b57cec5SDimitry Andric     CharUnits OffsetFromNearestVBase;
24370b57cec5SDimitry Andric     const CXXRecordDecl *VTableClass;
24380b57cec5SDimitry Andric   };
24390b57cec5SDimitry Andric 
24400b57cec5SDimitry Andric   /// Initialize the vtable pointer of the given subobject.
24410b57cec5SDimitry Andric   void InitializeVTablePointer(const VPtr &vptr);
24420b57cec5SDimitry Andric 
24430b57cec5SDimitry Andric   typedef llvm::SmallVector<VPtr, 4> VPtrsVector;
24440b57cec5SDimitry Andric 
24450b57cec5SDimitry Andric   typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
24460b57cec5SDimitry Andric   VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass);
24470b57cec5SDimitry Andric 
24480b57cec5SDimitry Andric   void getVTablePointers(BaseSubobject Base, const CXXRecordDecl *NearestVBase,
24490b57cec5SDimitry Andric                          CharUnits OffsetFromNearestVBase,
24500b57cec5SDimitry Andric                          bool BaseIsNonVirtualPrimaryBase,
24510b57cec5SDimitry Andric                          const CXXRecordDecl *VTableClass,
24520b57cec5SDimitry Andric                          VisitedVirtualBasesSetTy &VBases, VPtrsVector &vptrs);
24530b57cec5SDimitry Andric 
24540b57cec5SDimitry Andric   void InitializeVTablePointers(const CXXRecordDecl *ClassDecl);
24550b57cec5SDimitry Andric 
24560fca6ea1SDimitry Andric   // VTableTrapMode - whether we guarantee that loading the
24570fca6ea1SDimitry Andric   // vtable is guaranteed to trap on authentication failure,
24580fca6ea1SDimitry Andric   // even if the resulting vtable pointer is unused.
24590fca6ea1SDimitry Andric   enum class VTableAuthMode {
24600fca6ea1SDimitry Andric     Authenticate,
24610fca6ea1SDimitry Andric     MustTrap,
24620fca6ea1SDimitry Andric     UnsafeUbsanStrip // Should only be used for Vptr UBSan check
24630fca6ea1SDimitry Andric   };
24640b57cec5SDimitry Andric   /// GetVTablePtr - Return the Value of the vtable pointer member pointed
24650b57cec5SDimitry Andric   /// to by This.
24660fca6ea1SDimitry Andric   llvm::Value *
24670fca6ea1SDimitry Andric   GetVTablePtr(Address This, llvm::Type *VTableTy,
24680fca6ea1SDimitry Andric                const CXXRecordDecl *VTableClass,
24690fca6ea1SDimitry Andric                VTableAuthMode AuthMode = VTableAuthMode::Authenticate);
24700b57cec5SDimitry Andric 
24710b57cec5SDimitry Andric   enum CFITypeCheckKind {
24720b57cec5SDimitry Andric     CFITCK_VCall,
24730b57cec5SDimitry Andric     CFITCK_NVCall,
24740b57cec5SDimitry Andric     CFITCK_DerivedCast,
24750b57cec5SDimitry Andric     CFITCK_UnrelatedCast,
24760b57cec5SDimitry Andric     CFITCK_ICall,
24770b57cec5SDimitry Andric     CFITCK_NVMFCall,
24780b57cec5SDimitry Andric     CFITCK_VMFCall,
24790b57cec5SDimitry Andric   };
24800b57cec5SDimitry Andric 
24810b57cec5SDimitry Andric   /// Derived is the presumed address of an object of type T after a
24820b57cec5SDimitry Andric   /// cast. If T is a polymorphic class type, emit a check that the virtual
24830b57cec5SDimitry Andric   /// table for Derived belongs to a class derived from T.
248481ad6265SDimitry Andric   void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull,
248581ad6265SDimitry Andric                                  CFITypeCheckKind TCK, SourceLocation Loc);
24860b57cec5SDimitry Andric 
24870b57cec5SDimitry Andric   /// EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
24880b57cec5SDimitry Andric   /// If vptr CFI is enabled, emit a check that VTable is valid.
24890b57cec5SDimitry Andric   void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable,
24900b57cec5SDimitry Andric                                  CFITypeCheckKind TCK, SourceLocation Loc);
24910b57cec5SDimitry Andric 
24920b57cec5SDimitry Andric   /// EmitVTablePtrCheck - Emit a check that VTable is a valid virtual table for
24930b57cec5SDimitry Andric   /// RD using llvm.type.test.
24940b57cec5SDimitry Andric   void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable,
24950b57cec5SDimitry Andric                           CFITypeCheckKind TCK, SourceLocation Loc);
24960b57cec5SDimitry Andric 
24970b57cec5SDimitry Andric   /// If whole-program virtual table optimization is enabled, emit an assumption
24980b57cec5SDimitry Andric   /// that VTable is a member of RD's type identifier. Or, if vptr CFI is
24990b57cec5SDimitry Andric   /// enabled, emit a check that VTable is a member of RD's type identifier.
25000b57cec5SDimitry Andric   void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD,
25010b57cec5SDimitry Andric                                     llvm::Value *VTable, SourceLocation Loc);
25020b57cec5SDimitry Andric 
25030b57cec5SDimitry Andric   /// Returns whether we should perform a type checked load when loading a
25040b57cec5SDimitry Andric   /// virtual function for virtual calls to members of RD. This is generally
25050b57cec5SDimitry Andric   /// true when both vcall CFI and whole-program-vtables are enabled.
25060b57cec5SDimitry Andric   bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD);
25070b57cec5SDimitry Andric 
25080b57cec5SDimitry Andric   /// Emit a type checked load from the given vtable.
250981ad6265SDimitry Andric   llvm::Value *EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD,
251081ad6265SDimitry Andric                                          llvm::Value *VTable,
251181ad6265SDimitry Andric                                          llvm::Type *VTableTy,
25120b57cec5SDimitry Andric                                          uint64_t VTableByteOffset);
25130b57cec5SDimitry Andric 
25140b57cec5SDimitry Andric   /// EnterDtorCleanups - Enter the cleanups necessary to complete the
25150b57cec5SDimitry Andric   /// given phase of destruction for a destructor.  The end result
25160b57cec5SDimitry Andric   /// should call destructors on members and base classes in reverse
25170b57cec5SDimitry Andric   /// order of their construction.
25180b57cec5SDimitry Andric   void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type);
25190b57cec5SDimitry Andric 
25200b57cec5SDimitry Andric   /// ShouldInstrumentFunction - Return true if the current function should be
25210b57cec5SDimitry Andric   /// instrumented with __cyg_profile_func_* calls
25220b57cec5SDimitry Andric   bool ShouldInstrumentFunction();
25230b57cec5SDimitry Andric 
2524349cc55cSDimitry Andric   /// ShouldSkipSanitizerInstrumentation - Return true if the current function
2525349cc55cSDimitry Andric   /// should not be instrumented with sanitizers.
2526349cc55cSDimitry Andric   bool ShouldSkipSanitizerInstrumentation();
2527349cc55cSDimitry Andric 
25280b57cec5SDimitry Andric   /// ShouldXRayInstrument - Return true if the current function should be
25290b57cec5SDimitry Andric   /// instrumented with XRay nop sleds.
25300b57cec5SDimitry Andric   bool ShouldXRayInstrumentFunction() const;
25310b57cec5SDimitry Andric 
25320b57cec5SDimitry Andric   /// AlwaysEmitXRayCustomEvents - Return true if we must unconditionally emit
25330b57cec5SDimitry Andric   /// XRay custom event handling calls.
25340b57cec5SDimitry Andric   bool AlwaysEmitXRayCustomEvents() const;
25350b57cec5SDimitry Andric 
25360b57cec5SDimitry Andric   /// AlwaysEmitXRayTypedEvents - Return true if clang must unconditionally emit
25370b57cec5SDimitry Andric   /// XRay typed event handling calls.
25380b57cec5SDimitry Andric   bool AlwaysEmitXRayTypedEvents() const;
25390b57cec5SDimitry Andric 
254006c3fb27SDimitry Andric   /// Return a type hash constant for a function instrumented by
254106c3fb27SDimitry Andric   /// -fsanitize=function.
254206c3fb27SDimitry Andric   llvm::ConstantInt *getUBSanFunctionTypeHash(QualType T) const;
25430b57cec5SDimitry Andric 
25440b57cec5SDimitry Andric   /// EmitFunctionProlog - Emit the target specific LLVM code to load the
25450b57cec5SDimitry Andric   /// arguments for the given function. This is also responsible for naming the
25460b57cec5SDimitry Andric   /// LLVM function arguments.
25470b57cec5SDimitry Andric   void EmitFunctionProlog(const CGFunctionInfo &FI,
25480b57cec5SDimitry Andric                           llvm::Function *Fn,
25490b57cec5SDimitry Andric                           const FunctionArgList &Args);
25500b57cec5SDimitry Andric 
25510b57cec5SDimitry Andric   /// EmitFunctionEpilog - Emit the target specific LLVM code to return the
25520b57cec5SDimitry Andric   /// given temporary.
25530b57cec5SDimitry Andric   void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc,
25540b57cec5SDimitry Andric                           SourceLocation EndLoc);
25550b57cec5SDimitry Andric 
25560b57cec5SDimitry Andric   /// Emit a test that checks if the return value \p RV is nonnull.
25570b57cec5SDimitry Andric   void EmitReturnValueCheck(llvm::Value *RV);
25580b57cec5SDimitry Andric 
25590b57cec5SDimitry Andric   /// EmitStartEHSpec - Emit the start of the exception spec.
25600b57cec5SDimitry Andric   void EmitStartEHSpec(const Decl *D);
25610b57cec5SDimitry Andric 
25620b57cec5SDimitry Andric   /// EmitEndEHSpec - Emit the end of the exception spec.
25630b57cec5SDimitry Andric   void EmitEndEHSpec(const Decl *D);
25640b57cec5SDimitry Andric 
25650b57cec5SDimitry Andric   /// getTerminateLandingPad - Return a landing pad that just calls terminate.
25660b57cec5SDimitry Andric   llvm::BasicBlock *getTerminateLandingPad();
25670b57cec5SDimitry Andric 
25680b57cec5SDimitry Andric   /// getTerminateLandingPad - Return a cleanup funclet that just calls
25690b57cec5SDimitry Andric   /// terminate.
25700b57cec5SDimitry Andric   llvm::BasicBlock *getTerminateFunclet();
25710b57cec5SDimitry Andric 
25720b57cec5SDimitry Andric   /// getTerminateHandler - Return a handler (not a landing pad, just
25730b57cec5SDimitry Andric   /// a catch handler) that just calls terminate.  This is used when
25740b57cec5SDimitry Andric   /// a terminate scope encloses a try.
25750b57cec5SDimitry Andric   llvm::BasicBlock *getTerminateHandler();
25760b57cec5SDimitry Andric 
25770b57cec5SDimitry Andric   llvm::Type *ConvertTypeForMem(QualType T);
25780b57cec5SDimitry Andric   llvm::Type *ConvertType(QualType T);
25790fca6ea1SDimitry Andric   llvm::Type *convertTypeForLoadStore(QualType ASTTy,
25800fca6ea1SDimitry Andric                                       llvm::Type *LLVMTy = nullptr);
25810b57cec5SDimitry Andric   llvm::Type *ConvertType(const TypeDecl *T) {
25820b57cec5SDimitry Andric     return ConvertType(getContext().getTypeDeclType(T));
25830b57cec5SDimitry Andric   }
25840b57cec5SDimitry Andric 
25850b57cec5SDimitry Andric   /// LoadObjCSelf - Load the value of self. This function is only valid while
25860b57cec5SDimitry Andric   /// generating code for an Objective-C method.
25870b57cec5SDimitry Andric   llvm::Value *LoadObjCSelf();
25880b57cec5SDimitry Andric 
25890b57cec5SDimitry Andric   /// TypeOfSelfObject - Return type of object that this self represents.
25900b57cec5SDimitry Andric   QualType TypeOfSelfObject();
25910b57cec5SDimitry Andric 
25920b57cec5SDimitry Andric   /// getEvaluationKind - Return the TypeEvaluationKind of QualType \c T.
25930b57cec5SDimitry Andric   static TypeEvaluationKind getEvaluationKind(QualType T);
25940b57cec5SDimitry Andric 
25950b57cec5SDimitry Andric   static bool hasScalarEvaluationKind(QualType T) {
25960b57cec5SDimitry Andric     return getEvaluationKind(T) == TEK_Scalar;
25970b57cec5SDimitry Andric   }
25980b57cec5SDimitry Andric 
25990b57cec5SDimitry Andric   static bool hasAggregateEvaluationKind(QualType T) {
26000b57cec5SDimitry Andric     return getEvaluationKind(T) == TEK_Aggregate;
26010b57cec5SDimitry Andric   }
26020b57cec5SDimitry Andric 
26030b57cec5SDimitry Andric   /// createBasicBlock - Create an LLVM basic block.
26040b57cec5SDimitry Andric   llvm::BasicBlock *createBasicBlock(const Twine &name = "",
26050b57cec5SDimitry Andric                                      llvm::Function *parent = nullptr,
26060b57cec5SDimitry Andric                                      llvm::BasicBlock *before = nullptr) {
26070b57cec5SDimitry Andric     return llvm::BasicBlock::Create(getLLVMContext(), name, parent, before);
26080b57cec5SDimitry Andric   }
26090b57cec5SDimitry Andric 
26100b57cec5SDimitry Andric   /// getBasicBlockForLabel - Return the LLVM basicblock that the specified
26110b57cec5SDimitry Andric   /// label maps to.
26120b57cec5SDimitry Andric   JumpDest getJumpDestForLabel(const LabelDecl *S);
26130b57cec5SDimitry Andric 
26140b57cec5SDimitry Andric   /// SimplifyForwardingBlocks - If the given basic block is only a branch to
26150b57cec5SDimitry Andric   /// another basic block, simplify it. This assumes that no other code could
26160b57cec5SDimitry Andric   /// potentially reference the basic block.
26170b57cec5SDimitry Andric   void SimplifyForwardingBlocks(llvm::BasicBlock *BB);
26180b57cec5SDimitry Andric 
26190b57cec5SDimitry Andric   /// EmitBlock - Emit the given block \arg BB and set it as the insert point,
26200b57cec5SDimitry Andric   /// adding a fall-through branch from the current insert block if
26210b57cec5SDimitry Andric   /// necessary. It is legal to call this function even if there is no current
26220b57cec5SDimitry Andric   /// insertion point.
26230b57cec5SDimitry Andric   ///
26240b57cec5SDimitry Andric   /// IsFinished - If true, indicates that the caller has finished emitting
26250b57cec5SDimitry Andric   /// branches to the given block and does not expect to emit code into it. This
26260b57cec5SDimitry Andric   /// means the block can be ignored if it is unreachable.
26270b57cec5SDimitry Andric   void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false);
26280b57cec5SDimitry Andric 
26290b57cec5SDimitry Andric   /// EmitBlockAfterUses - Emit the given block somewhere hopefully
26300b57cec5SDimitry Andric   /// near its uses, and leave the insertion point in it.
26310b57cec5SDimitry Andric   void EmitBlockAfterUses(llvm::BasicBlock *BB);
26320b57cec5SDimitry Andric 
26330b57cec5SDimitry Andric   /// EmitBranch - Emit a branch to the specified basic block from the current
26340b57cec5SDimitry Andric   /// insert block, taking care to avoid creation of branches from dummy
26350b57cec5SDimitry Andric   /// blocks. It is legal to call this function even if there is no current
26360b57cec5SDimitry Andric   /// insertion point.
26370b57cec5SDimitry Andric   ///
26380b57cec5SDimitry Andric   /// This function clears the current insertion point. The caller should follow
26390b57cec5SDimitry Andric   /// calls to this function with calls to Emit*Block prior to generation new
26400b57cec5SDimitry Andric   /// code.
26410b57cec5SDimitry Andric   void EmitBranch(llvm::BasicBlock *Block);
26420b57cec5SDimitry Andric 
26430b57cec5SDimitry Andric   /// HaveInsertPoint - True if an insertion point is defined. If not, this
26440b57cec5SDimitry Andric   /// indicates that the current code being emitted is unreachable.
26450b57cec5SDimitry Andric   bool HaveInsertPoint() const {
26460b57cec5SDimitry Andric     return Builder.GetInsertBlock() != nullptr;
26470b57cec5SDimitry Andric   }
26480b57cec5SDimitry Andric 
26490b57cec5SDimitry Andric   /// EnsureInsertPoint - Ensure that an insertion point is defined so that
26500b57cec5SDimitry Andric   /// emitted IR has a place to go. Note that by definition, if this function
26510b57cec5SDimitry Andric   /// creates a block then that block is unreachable; callers may do better to
26520b57cec5SDimitry Andric   /// detect when no insertion point is defined and simply skip IR generation.
26530b57cec5SDimitry Andric   void EnsureInsertPoint() {
26540b57cec5SDimitry Andric     if (!HaveInsertPoint())
26550b57cec5SDimitry Andric       EmitBlock(createBasicBlock());
26560b57cec5SDimitry Andric   }
26570b57cec5SDimitry Andric 
26580b57cec5SDimitry Andric   /// ErrorUnsupported - Print out an error that codegen doesn't support the
26590b57cec5SDimitry Andric   /// specified stmt yet.
26600b57cec5SDimitry Andric   void ErrorUnsupported(const Stmt *S, const char *Type);
26610b57cec5SDimitry Andric 
26620b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
26630b57cec5SDimitry Andric   //                                  Helpers
26640b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
26650b57cec5SDimitry Andric 
26660fca6ea1SDimitry Andric   Address mergeAddressesInConditionalExpr(Address LHS, Address RHS,
26670fca6ea1SDimitry Andric                                           llvm::BasicBlock *LHSBlock,
26680fca6ea1SDimitry Andric                                           llvm::BasicBlock *RHSBlock,
26690fca6ea1SDimitry Andric                                           llvm::BasicBlock *MergeBlock,
26700fca6ea1SDimitry Andric                                           QualType MergedType) {
26710fca6ea1SDimitry Andric     Builder.SetInsertPoint(MergeBlock);
26720fca6ea1SDimitry Andric     llvm::PHINode *PtrPhi = Builder.CreatePHI(LHS.getType(), 2, "cond");
26730fca6ea1SDimitry Andric     PtrPhi->addIncoming(LHS.getBasePointer(), LHSBlock);
26740fca6ea1SDimitry Andric     PtrPhi->addIncoming(RHS.getBasePointer(), RHSBlock);
26750fca6ea1SDimitry Andric     LHS.replaceBasePointer(PtrPhi);
26760fca6ea1SDimitry Andric     LHS.setAlignment(std::min(LHS.getAlignment(), RHS.getAlignment()));
26770fca6ea1SDimitry Andric     return LHS;
26780fca6ea1SDimitry Andric   }
26790fca6ea1SDimitry Andric 
26800fca6ea1SDimitry Andric   /// Construct an address with the natural alignment of T. If a pointer to T
26810fca6ea1SDimitry Andric   /// is expected to be signed, the pointer passed to this function must have
26820fca6ea1SDimitry Andric   /// been signed, and the returned Address will have the pointer authentication
26830fca6ea1SDimitry Andric   /// information needed to authenticate the signed pointer.
26840fca6ea1SDimitry Andric   Address makeNaturalAddressForPointer(
26850fca6ea1SDimitry Andric       llvm::Value *Ptr, QualType T, CharUnits Alignment = CharUnits::Zero(),
26860fca6ea1SDimitry Andric       bool ForPointeeType = false, LValueBaseInfo *BaseInfo = nullptr,
26870fca6ea1SDimitry Andric       TBAAAccessInfo *TBAAInfo = nullptr,
26880fca6ea1SDimitry Andric       KnownNonNull_t IsKnownNonNull = NotKnownNonNull) {
26890fca6ea1SDimitry Andric     if (Alignment.isZero())
26900fca6ea1SDimitry Andric       Alignment =
26910fca6ea1SDimitry Andric           CGM.getNaturalTypeAlignment(T, BaseInfo, TBAAInfo, ForPointeeType);
26920fca6ea1SDimitry Andric     return Address(Ptr, ConvertTypeForMem(T), Alignment,
26930fca6ea1SDimitry Andric                    CGM.getPointerAuthInfoForPointeeType(T), /*Offset=*/nullptr,
26940fca6ea1SDimitry Andric                    IsKnownNonNull);
26950fca6ea1SDimitry Andric   }
26960fca6ea1SDimitry Andric 
26970b57cec5SDimitry Andric   LValue MakeAddrLValue(Address Addr, QualType T,
26980b57cec5SDimitry Andric                         AlignmentSource Source = AlignmentSource::Type) {
26990fca6ea1SDimitry Andric     return MakeAddrLValue(Addr, T, LValueBaseInfo(Source),
27000b57cec5SDimitry Andric                           CGM.getTBAAAccessInfo(T));
27010b57cec5SDimitry Andric   }
27020b57cec5SDimitry Andric 
27030b57cec5SDimitry Andric   LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo,
27040b57cec5SDimitry Andric                         TBAAAccessInfo TBAAInfo) {
27050b57cec5SDimitry Andric     return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, TBAAInfo);
27060b57cec5SDimitry Andric   }
27070b57cec5SDimitry Andric 
27080b57cec5SDimitry Andric   LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment,
27090b57cec5SDimitry Andric                         AlignmentSource Source = AlignmentSource::Type) {
27100fca6ea1SDimitry Andric     return MakeAddrLValue(makeNaturalAddressForPointer(V, T, Alignment), T,
27110fca6ea1SDimitry Andric                           LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T));
27120fca6ea1SDimitry Andric   }
27130fca6ea1SDimitry Andric 
27140fca6ea1SDimitry Andric   /// Same as MakeAddrLValue above except that the pointer is known to be
27150fca6ea1SDimitry Andric   /// unsigned.
27160fca6ea1SDimitry Andric   LValue MakeRawAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment,
27170fca6ea1SDimitry Andric                            AlignmentSource Source = AlignmentSource::Type) {
27180eae32dcSDimitry Andric     Address Addr(V, ConvertTypeForMem(T), Alignment);
27190eae32dcSDimitry Andric     return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source),
27200eae32dcSDimitry Andric                             CGM.getTBAAAccessInfo(T));
27210b57cec5SDimitry Andric   }
27220b57cec5SDimitry Andric 
27230eae32dcSDimitry Andric   LValue
27240eae32dcSDimitry Andric   MakeAddrLValueWithoutTBAA(Address Addr, QualType T,
27250eae32dcSDimitry Andric                             AlignmentSource Source = AlignmentSource::Type) {
27260eae32dcSDimitry Andric     return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source),
27270eae32dcSDimitry Andric                             TBAAAccessInfo());
27280b57cec5SDimitry Andric   }
27290b57cec5SDimitry Andric 
27300fca6ea1SDimitry Andric   /// Given a value of type T* that may not be to a complete object, construct
27310fca6ea1SDimitry Andric   /// an l-value with the natural pointee alignment of T.
27320b57cec5SDimitry Andric   LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T);
27330fca6ea1SDimitry Andric 
27340fca6ea1SDimitry Andric   LValue
27350fca6ea1SDimitry Andric   MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T,
27360fca6ea1SDimitry Andric                              KnownNonNull_t IsKnownNonNull = NotKnownNonNull);
27370fca6ea1SDimitry Andric 
27380fca6ea1SDimitry Andric   /// Same as MakeNaturalAlignPointeeAddrLValue except that the pointer is known
27390fca6ea1SDimitry Andric   /// to be unsigned.
27400fca6ea1SDimitry Andric   LValue MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, QualType T);
27410fca6ea1SDimitry Andric 
27420fca6ea1SDimitry Andric   LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T);
27430b57cec5SDimitry Andric 
27440b57cec5SDimitry Andric   Address EmitLoadOfReference(LValue RefLVal,
27450b57cec5SDimitry Andric                               LValueBaseInfo *PointeeBaseInfo = nullptr,
27460b57cec5SDimitry Andric                               TBAAAccessInfo *PointeeTBAAInfo = nullptr);
27470b57cec5SDimitry Andric   LValue EmitLoadOfReferenceLValue(LValue RefLVal);
27480b57cec5SDimitry Andric   LValue EmitLoadOfReferenceLValue(Address RefAddr, QualType RefTy,
27490b57cec5SDimitry Andric                                    AlignmentSource Source =
27500b57cec5SDimitry Andric                                        AlignmentSource::Type) {
27510b57cec5SDimitry Andric     LValue RefLVal = MakeAddrLValue(RefAddr, RefTy, LValueBaseInfo(Source),
27520b57cec5SDimitry Andric                                     CGM.getTBAAAccessInfo(RefTy));
27530b57cec5SDimitry Andric     return EmitLoadOfReferenceLValue(RefLVal);
27540b57cec5SDimitry Andric   }
27550b57cec5SDimitry Andric 
275681ad6265SDimitry Andric   /// Load a pointer with type \p PtrTy stored at address \p Ptr.
275781ad6265SDimitry Andric   /// Note that \p PtrTy is the type of the loaded pointer, not the addresses
275881ad6265SDimitry Andric   /// it is loaded from.
27590b57cec5SDimitry Andric   Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy,
27600b57cec5SDimitry Andric                             LValueBaseInfo *BaseInfo = nullptr,
27610b57cec5SDimitry Andric                             TBAAAccessInfo *TBAAInfo = nullptr);
27620b57cec5SDimitry Andric   LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy);
27630b57cec5SDimitry Andric 
27640fca6ea1SDimitry Andric private:
27650fca6ea1SDimitry Andric   struct AllocaTracker {
27660fca6ea1SDimitry Andric     void Add(llvm::AllocaInst *I) { Allocas.push_back(I); }
27670fca6ea1SDimitry Andric     llvm::SmallVector<llvm::AllocaInst *> Take() { return std::move(Allocas); }
27680fca6ea1SDimitry Andric 
27690fca6ea1SDimitry Andric   private:
27700fca6ea1SDimitry Andric     llvm::SmallVector<llvm::AllocaInst *> Allocas;
27710fca6ea1SDimitry Andric   };
27720fca6ea1SDimitry Andric   AllocaTracker *Allocas = nullptr;
27730fca6ea1SDimitry Andric 
27740fca6ea1SDimitry Andric public:
27750fca6ea1SDimitry Andric   // Captures all the allocas created during the scope of its RAII object.
27760fca6ea1SDimitry Andric   struct AllocaTrackerRAII {
27770fca6ea1SDimitry Andric     AllocaTrackerRAII(CodeGenFunction &CGF)
27780fca6ea1SDimitry Andric         : CGF(CGF), OldTracker(CGF.Allocas) {
27790fca6ea1SDimitry Andric       CGF.Allocas = &Tracker;
27800fca6ea1SDimitry Andric     }
27810fca6ea1SDimitry Andric     ~AllocaTrackerRAII() { CGF.Allocas = OldTracker; }
27820fca6ea1SDimitry Andric 
27830fca6ea1SDimitry Andric     llvm::SmallVector<llvm::AllocaInst *> Take() { return Tracker.Take(); }
27840fca6ea1SDimitry Andric 
27850fca6ea1SDimitry Andric   private:
27860fca6ea1SDimitry Andric     CodeGenFunction &CGF;
27870fca6ea1SDimitry Andric     AllocaTracker *OldTracker;
27880fca6ea1SDimitry Andric     AllocaTracker Tracker;
27890fca6ea1SDimitry Andric   };
27900fca6ea1SDimitry Andric 
27910b57cec5SDimitry Andric   /// CreateTempAlloca - This creates an alloca and inserts it into the entry
27920b57cec5SDimitry Andric   /// block if \p ArraySize is nullptr, otherwise inserts it at the current
27930b57cec5SDimitry Andric   /// insertion point of the builder. The caller is responsible for setting an
27940b57cec5SDimitry Andric   /// appropriate alignment on
27950b57cec5SDimitry Andric   /// the alloca.
27960b57cec5SDimitry Andric   ///
27970b57cec5SDimitry Andric   /// \p ArraySize is the number of array elements to be allocated if it
27980b57cec5SDimitry Andric   ///    is not nullptr.
27990b57cec5SDimitry Andric   ///
28000b57cec5SDimitry Andric   /// LangAS::Default is the address space of pointers to local variables and
28010b57cec5SDimitry Andric   /// temporaries, as exposed in the source language. In certain
28020b57cec5SDimitry Andric   /// configurations, this is not the same as the alloca address space, and a
28030b57cec5SDimitry Andric   /// cast is needed to lift the pointer from the alloca AS into
28040b57cec5SDimitry Andric   /// LangAS::Default. This can happen when the target uses a restricted
28050b57cec5SDimitry Andric   /// address space for the stack but the source language requires
28060b57cec5SDimitry Andric   /// LangAS::Default to be a generic address space. The latter condition is
28070b57cec5SDimitry Andric   /// common for most programming languages; OpenCL is an exception in that
28080b57cec5SDimitry Andric   /// LangAS::Default is the private address space, which naturally maps
28090b57cec5SDimitry Andric   /// to the stack.
28100b57cec5SDimitry Andric   ///
28110b57cec5SDimitry Andric   /// Because the address of a temporary is often exposed to the program in
28120b57cec5SDimitry Andric   /// various ways, this function will perform the cast. The original alloca
28130b57cec5SDimitry Andric   /// instruction is returned through \p Alloca if it is not nullptr.
28140b57cec5SDimitry Andric   ///
28150b57cec5SDimitry Andric   /// The cast is not performaed in CreateTempAllocaWithoutCast. This is
28160b57cec5SDimitry Andric   /// more efficient if the caller knows that the address will not be exposed.
28170b57cec5SDimitry Andric   llvm::AllocaInst *CreateTempAlloca(llvm::Type *Ty, const Twine &Name = "tmp",
28180b57cec5SDimitry Andric                                      llvm::Value *ArraySize = nullptr);
28190fca6ea1SDimitry Andric   RawAddress CreateTempAlloca(llvm::Type *Ty, CharUnits align,
28200b57cec5SDimitry Andric                               const Twine &Name = "tmp",
28210b57cec5SDimitry Andric                               llvm::Value *ArraySize = nullptr,
28220fca6ea1SDimitry Andric                               RawAddress *Alloca = nullptr);
28230fca6ea1SDimitry Andric   RawAddress CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align,
28240b57cec5SDimitry Andric                                          const Twine &Name = "tmp",
28250b57cec5SDimitry Andric                                          llvm::Value *ArraySize = nullptr);
28260b57cec5SDimitry Andric 
28270b57cec5SDimitry Andric   /// CreateDefaultAlignedTempAlloca - This creates an alloca with the
28280b57cec5SDimitry Andric   /// default ABI alignment of the given LLVM type.
28290b57cec5SDimitry Andric   ///
28300b57cec5SDimitry Andric   /// IMPORTANT NOTE: This is *not* generally the right alignment for
28310b57cec5SDimitry Andric   /// any given AST type that happens to have been lowered to the
28320b57cec5SDimitry Andric   /// given IR type.  This should only ever be used for function-local,
28330b57cec5SDimitry Andric   /// IR-driven manipulations like saving and restoring a value.  Do
28340b57cec5SDimitry Andric   /// not hand this address off to arbitrary IRGen routines, and especially
28350b57cec5SDimitry Andric   /// do not pass it as an argument to a function that might expect a
28360b57cec5SDimitry Andric   /// properly ABI-aligned value.
28370fca6ea1SDimitry Andric   RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty,
28380b57cec5SDimitry Andric                                           const Twine &Name = "tmp");
28390b57cec5SDimitry Andric 
28400b57cec5SDimitry Andric   /// CreateIRTemp - Create a temporary IR object of the given type, with
28410b57cec5SDimitry Andric   /// appropriate alignment. This routine should only be used when an temporary
28420b57cec5SDimitry Andric   /// value needs to be stored into an alloca (for example, to avoid explicit
28430b57cec5SDimitry Andric   /// PHI construction), but the type is the IR type, not the type appropriate
28440b57cec5SDimitry Andric   /// for storing in memory.
28450b57cec5SDimitry Andric   ///
28460b57cec5SDimitry Andric   /// That is, this is exactly equivalent to CreateMemTemp, but calling
28470b57cec5SDimitry Andric   /// ConvertType instead of ConvertTypeForMem.
28480fca6ea1SDimitry Andric   RawAddress CreateIRTemp(QualType T, const Twine &Name = "tmp");
28490b57cec5SDimitry Andric 
28500b57cec5SDimitry Andric   /// CreateMemTemp - Create a temporary memory object of the given type, with
28510b57cec5SDimitry Andric   /// appropriate alignmen and cast it to the default address space. Returns
28520b57cec5SDimitry Andric   /// the original alloca instruction by \p Alloca if it is not nullptr.
28530fca6ea1SDimitry Andric   RawAddress CreateMemTemp(QualType T, const Twine &Name = "tmp",
28540fca6ea1SDimitry Andric                            RawAddress *Alloca = nullptr);
28550fca6ea1SDimitry Andric   RawAddress CreateMemTemp(QualType T, CharUnits Align,
28560fca6ea1SDimitry Andric                            const Twine &Name = "tmp",
28570fca6ea1SDimitry Andric                            RawAddress *Alloca = nullptr);
28580b57cec5SDimitry Andric 
28590b57cec5SDimitry Andric   /// CreateMemTemp - Create a temporary memory object of the given type, with
28600b57cec5SDimitry Andric   /// appropriate alignmen without casting it to the default address space.
28610fca6ea1SDimitry Andric   RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name = "tmp");
28620fca6ea1SDimitry Andric   RawAddress CreateMemTempWithoutCast(QualType T, CharUnits Align,
28630b57cec5SDimitry Andric                                       const Twine &Name = "tmp");
28640b57cec5SDimitry Andric 
28650b57cec5SDimitry Andric   /// CreateAggTemp - Create a temporary memory object for the given
28660b57cec5SDimitry Andric   /// aggregate type.
28675ffd83dbSDimitry Andric   AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp",
28680fca6ea1SDimitry Andric                              RawAddress *Alloca = nullptr) {
28690fca6ea1SDimitry Andric     return AggValueSlot::forAddr(
28700fca6ea1SDimitry Andric         CreateMemTemp(T, Name, Alloca), T.getQualifiers(),
28710fca6ea1SDimitry Andric         AggValueSlot::IsNotDestructed, AggValueSlot::DoesNotNeedGCBarriers,
28720fca6ea1SDimitry Andric         AggValueSlot::IsNotAliased, AggValueSlot::DoesNotOverlap);
28730b57cec5SDimitry Andric   }
28740b57cec5SDimitry Andric 
28750b57cec5SDimitry Andric   /// EvaluateExprAsBool - Perform the usual unary conversions on the specified
28760b57cec5SDimitry Andric   /// expression and compare the result against zero, returning an Int1Ty value.
28770b57cec5SDimitry Andric   llvm::Value *EvaluateExprAsBool(const Expr *E);
28780b57cec5SDimitry Andric 
28790fca6ea1SDimitry Andric   /// Retrieve the implicit cast expression of the rhs in a binary operator
28800fca6ea1SDimitry Andric   /// expression by passing pointers to Value and QualType
28810fca6ea1SDimitry Andric   /// This is used for implicit bitfield conversion checks, which
28820fca6ea1SDimitry Andric   /// must compare with the value before potential truncation.
28830fca6ea1SDimitry Andric   llvm::Value *EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator *E,
28840fca6ea1SDimitry Andric                                                      llvm::Value **Previous,
28850fca6ea1SDimitry Andric                                                      QualType *SrcType);
28860fca6ea1SDimitry Andric 
28870fca6ea1SDimitry Andric   /// Emit a check that an [implicit] conversion of a bitfield. It is not UB,
28880fca6ea1SDimitry Andric   /// so we use the value after conversion.
28890fca6ea1SDimitry Andric   void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType,
28900fca6ea1SDimitry Andric                                    llvm::Value *Dst, QualType DstType,
28910fca6ea1SDimitry Andric                                    const CGBitFieldInfo &Info,
28920fca6ea1SDimitry Andric                                    SourceLocation Loc);
28930fca6ea1SDimitry Andric 
28940b57cec5SDimitry Andric   /// EmitIgnoredExpr - Emit an expression in a context which ignores the result.
28950b57cec5SDimitry Andric   void EmitIgnoredExpr(const Expr *E);
28960b57cec5SDimitry Andric 
28970b57cec5SDimitry Andric   /// EmitAnyExpr - Emit code to compute the specified expression which can have
28980b57cec5SDimitry Andric   /// any type.  The result is returned as an RValue struct.  If this is an
28990b57cec5SDimitry Andric   /// aggregate expression, the aggloc/agglocvolatile arguments indicate where
29000b57cec5SDimitry Andric   /// the result should be returned.
29010b57cec5SDimitry Andric   ///
29020b57cec5SDimitry Andric   /// \param ignoreResult True if the resulting value isn't used.
29030b57cec5SDimitry Andric   RValue EmitAnyExpr(const Expr *E,
29040b57cec5SDimitry Andric                      AggValueSlot aggSlot = AggValueSlot::ignored(),
29050b57cec5SDimitry Andric                      bool ignoreResult = false);
29060b57cec5SDimitry Andric 
29070b57cec5SDimitry Andric   // EmitVAListRef - Emit a "reference" to a va_list; this is either the address
29080b57cec5SDimitry Andric   // or the value of the expression, depending on how va_list is defined.
29090b57cec5SDimitry Andric   Address EmitVAListRef(const Expr *E);
29100b57cec5SDimitry Andric 
29110b57cec5SDimitry Andric   /// Emit a "reference" to a __builtin_ms_va_list; this is
29120b57cec5SDimitry Andric   /// always the value of the expression, because a __builtin_ms_va_list is a
29130b57cec5SDimitry Andric   /// pointer to a char.
29140b57cec5SDimitry Andric   Address EmitMSVAListRef(const Expr *E);
29150b57cec5SDimitry Andric 
29160b57cec5SDimitry Andric   /// EmitAnyExprToTemp - Similarly to EmitAnyExpr(), however, the result will
29170b57cec5SDimitry Andric   /// always be accessible even if no aggregate location is provided.
29180b57cec5SDimitry Andric   RValue EmitAnyExprToTemp(const Expr *E);
29190b57cec5SDimitry Andric 
29200b57cec5SDimitry Andric   /// EmitAnyExprToMem - Emits the code necessary to evaluate an
29210b57cec5SDimitry Andric   /// arbitrary expression into the given memory location.
29220b57cec5SDimitry Andric   void EmitAnyExprToMem(const Expr *E, Address Location,
29230b57cec5SDimitry Andric                         Qualifiers Quals, bool IsInitializer);
29240b57cec5SDimitry Andric 
29250b57cec5SDimitry Andric   void EmitAnyExprToExn(const Expr *E, Address Addr);
29260b57cec5SDimitry Andric 
29270b57cec5SDimitry Andric   /// EmitExprAsInit - Emits the code necessary to initialize a
29280b57cec5SDimitry Andric   /// location in memory with the given initializer.
29290b57cec5SDimitry Andric   void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue,
29300b57cec5SDimitry Andric                       bool capturedByInit);
29310b57cec5SDimitry Andric 
29320b57cec5SDimitry Andric   /// hasVolatileMember - returns true if aggregate type has a volatile
29330b57cec5SDimitry Andric   /// member.
29340b57cec5SDimitry Andric   bool hasVolatileMember(QualType T) {
29350b57cec5SDimitry Andric     if (const RecordType *RT = T->getAs<RecordType>()) {
29360b57cec5SDimitry Andric       const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
29370b57cec5SDimitry Andric       return RD->hasVolatileMember();
29380b57cec5SDimitry Andric     }
29390b57cec5SDimitry Andric     return false;
29400b57cec5SDimitry Andric   }
29410b57cec5SDimitry Andric 
29420b57cec5SDimitry Andric   /// Determine whether a return value slot may overlap some other object.
29430b57cec5SDimitry Andric   AggValueSlot::Overlap_t getOverlapForReturnValue() {
29440b57cec5SDimitry Andric     // FIXME: Assuming no overlap here breaks guaranteed copy elision for base
29450b57cec5SDimitry Andric     // class subobjects. These cases may need to be revisited depending on the
29460b57cec5SDimitry Andric     // resolution of the relevant core issue.
29470b57cec5SDimitry Andric     return AggValueSlot::DoesNotOverlap;
29480b57cec5SDimitry Andric   }
29490b57cec5SDimitry Andric 
29500b57cec5SDimitry Andric   /// Determine whether a field initialization may overlap some other object.
29510b57cec5SDimitry Andric   AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD);
29520b57cec5SDimitry Andric 
29530b57cec5SDimitry Andric   /// Determine whether a base class initialization may overlap some other
29540b57cec5SDimitry Andric   /// object.
29550b57cec5SDimitry Andric   AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *RD,
29560b57cec5SDimitry Andric                                                 const CXXRecordDecl *BaseRD,
29570b57cec5SDimitry Andric                                                 bool IsVirtual);
29580b57cec5SDimitry Andric 
29590b57cec5SDimitry Andric   /// Emit an aggregate assignment.
29600b57cec5SDimitry Andric   void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy) {
29610b57cec5SDimitry Andric     bool IsVolatile = hasVolatileMember(EltTy);
29620b57cec5SDimitry Andric     EmitAggregateCopy(Dest, Src, EltTy, AggValueSlot::MayOverlap, IsVolatile);
29630b57cec5SDimitry Andric   }
29640b57cec5SDimitry Andric 
29650b57cec5SDimitry Andric   void EmitAggregateCopyCtor(LValue Dest, LValue Src,
29660b57cec5SDimitry Andric                              AggValueSlot::Overlap_t MayOverlap) {
29670b57cec5SDimitry Andric     EmitAggregateCopy(Dest, Src, Src.getType(), MayOverlap);
29680b57cec5SDimitry Andric   }
29690b57cec5SDimitry Andric 
29700b57cec5SDimitry Andric   /// EmitAggregateCopy - Emit an aggregate copy.
29710b57cec5SDimitry Andric   ///
29720b57cec5SDimitry Andric   /// \param isVolatile \c true iff either the source or the destination is
29730b57cec5SDimitry Andric   ///        volatile.
29740b57cec5SDimitry Andric   /// \param MayOverlap Whether the tail padding of the destination might be
29750b57cec5SDimitry Andric   ///        occupied by some other object. More efficient code can often be
29760b57cec5SDimitry Andric   ///        generated if not.
29770b57cec5SDimitry Andric   void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy,
29780b57cec5SDimitry Andric                          AggValueSlot::Overlap_t MayOverlap,
29790b57cec5SDimitry Andric                          bool isVolatile = false);
29800b57cec5SDimitry Andric 
29810b57cec5SDimitry Andric   /// GetAddrOfLocalVar - Return the address of a local variable.
29820b57cec5SDimitry Andric   Address GetAddrOfLocalVar(const VarDecl *VD) {
29830b57cec5SDimitry Andric     auto it = LocalDeclMap.find(VD);
29840b57cec5SDimitry Andric     assert(it != LocalDeclMap.end() &&
29850b57cec5SDimitry Andric            "Invalid argument to GetAddrOfLocalVar(), no decl!");
29860b57cec5SDimitry Andric     return it->second;
29870b57cec5SDimitry Andric   }
29880b57cec5SDimitry Andric 
29890b57cec5SDimitry Andric   /// Given an opaque value expression, return its LValue mapping if it exists,
29900b57cec5SDimitry Andric   /// otherwise create one.
29910b57cec5SDimitry Andric   LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e);
29920b57cec5SDimitry Andric 
29930b57cec5SDimitry Andric   /// Given an opaque value expression, return its RValue mapping if it exists,
29940b57cec5SDimitry Andric   /// otherwise create one.
29950b57cec5SDimitry Andric   RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e);
29960b57cec5SDimitry Andric 
29970b57cec5SDimitry Andric   /// Get the index of the current ArrayInitLoopExpr, if any.
29980b57cec5SDimitry Andric   llvm::Value *getArrayInitIndex() { return ArrayInitIndex; }
29990b57cec5SDimitry Andric 
30000b57cec5SDimitry Andric   /// getAccessedFieldNo - Given an encoded value and a result number, return
30010b57cec5SDimitry Andric   /// the input field number being accessed.
30020b57cec5SDimitry Andric   static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts);
30030b57cec5SDimitry Andric 
30040b57cec5SDimitry Andric   llvm::BlockAddress *GetAddrOfLabel(const LabelDecl *L);
30050b57cec5SDimitry Andric   llvm::BasicBlock *GetIndirectGotoBlock();
30060b57cec5SDimitry Andric 
30070b57cec5SDimitry Andric   /// Check if \p E is a C++ "this" pointer wrapped in value-preserving casts.
30080b57cec5SDimitry Andric   static bool IsWrappedCXXThis(const Expr *E);
30090b57cec5SDimitry Andric 
30100b57cec5SDimitry Andric   /// EmitNullInitialization - Generate code to set a value of the given type to
30110b57cec5SDimitry Andric   /// null, If the type contains data member pointers, they will be initialized
30120b57cec5SDimitry Andric   /// to -1 in accordance with the Itanium C++ ABI.
30130b57cec5SDimitry Andric   void EmitNullInitialization(Address DestPtr, QualType Ty);
30140b57cec5SDimitry Andric 
30150b57cec5SDimitry Andric   /// Emits a call to an LLVM variable-argument intrinsic, either
30160b57cec5SDimitry Andric   /// \c llvm.va_start or \c llvm.va_end.
30170b57cec5SDimitry Andric   /// \param ArgValue A reference to the \c va_list as emitted by either
30180b57cec5SDimitry Andric   /// \c EmitVAListRef or \c EmitMSVAListRef.
30190b57cec5SDimitry Andric   /// \param IsStart If \c true, emits a call to \c llvm.va_start; otherwise,
30200b57cec5SDimitry Andric   /// calls \c llvm.va_end.
30210b57cec5SDimitry Andric   llvm::Value *EmitVAStartEnd(llvm::Value *ArgValue, bool IsStart);
30220b57cec5SDimitry Andric 
30230b57cec5SDimitry Andric   /// Generate code to get an argument from the passed in pointer
30240b57cec5SDimitry Andric   /// and update it accordingly.
30250b57cec5SDimitry Andric   /// \param VE The \c VAArgExpr for which to generate code.
30260b57cec5SDimitry Andric   /// \param VAListAddr Receives a reference to the \c va_list as emitted by
30270b57cec5SDimitry Andric   /// either \c EmitVAListRef or \c EmitMSVAListRef.
30280b57cec5SDimitry Andric   /// \returns A pointer to the argument.
30290b57cec5SDimitry Andric   // FIXME: We should be able to get rid of this method and use the va_arg
30300b57cec5SDimitry Andric   // instruction in LLVM instead once it works well enough.
30310fca6ea1SDimitry Andric   RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr,
30320fca6ea1SDimitry Andric                    AggValueSlot Slot = AggValueSlot::ignored());
30330b57cec5SDimitry Andric 
30340b57cec5SDimitry Andric   /// emitArrayLength - Compute the length of an array, even if it's a
30350b57cec5SDimitry Andric   /// VLA, and drill down to the base element type.
30360b57cec5SDimitry Andric   llvm::Value *emitArrayLength(const ArrayType *arrayType,
30370b57cec5SDimitry Andric                                QualType &baseType,
30380b57cec5SDimitry Andric                                Address &addr);
30390b57cec5SDimitry Andric 
30400b57cec5SDimitry Andric   /// EmitVLASize - Capture all the sizes for the VLA expressions in
30410b57cec5SDimitry Andric   /// the given variably-modified type and store them in the VLASizeMap.
30420b57cec5SDimitry Andric   ///
30430b57cec5SDimitry Andric   /// This function can be called with a null (unreachable) insert point.
30440b57cec5SDimitry Andric   void EmitVariablyModifiedType(QualType Ty);
30450b57cec5SDimitry Andric 
30460b57cec5SDimitry Andric   struct VlaSizePair {
30470b57cec5SDimitry Andric     llvm::Value *NumElts;
30480b57cec5SDimitry Andric     QualType Type;
30490b57cec5SDimitry Andric 
30500b57cec5SDimitry Andric     VlaSizePair(llvm::Value *NE, QualType T) : NumElts(NE), Type(T) {}
30510b57cec5SDimitry Andric   };
30520b57cec5SDimitry Andric 
30530b57cec5SDimitry Andric   /// Return the number of elements for a single dimension
30540b57cec5SDimitry Andric   /// for the given array type.
30550b57cec5SDimitry Andric   VlaSizePair getVLAElements1D(const VariableArrayType *vla);
30560b57cec5SDimitry Andric   VlaSizePair getVLAElements1D(QualType vla);
30570b57cec5SDimitry Andric 
30580b57cec5SDimitry Andric   /// Returns an LLVM value that corresponds to the size,
30590b57cec5SDimitry Andric   /// in non-variably-sized elements, of a variable length array type,
30600b57cec5SDimitry Andric   /// plus that largest non-variably-sized element type.  Assumes that
30610b57cec5SDimitry Andric   /// the type has already been emitted with EmitVariablyModifiedType.
30620b57cec5SDimitry Andric   VlaSizePair getVLASize(const VariableArrayType *vla);
30630b57cec5SDimitry Andric   VlaSizePair getVLASize(QualType vla);
30640b57cec5SDimitry Andric 
30650b57cec5SDimitry Andric   /// LoadCXXThis - Load the value of 'this'. This function is only valid while
30660b57cec5SDimitry Andric   /// generating code for an C++ member function.
30670b57cec5SDimitry Andric   llvm::Value *LoadCXXThis() {
30680b57cec5SDimitry Andric     assert(CXXThisValue && "no 'this' value for this function");
30690b57cec5SDimitry Andric     return CXXThisValue;
30700b57cec5SDimitry Andric   }
30710b57cec5SDimitry Andric   Address LoadCXXThisAddress();
30720b57cec5SDimitry Andric 
30730b57cec5SDimitry Andric   /// LoadCXXVTT - Load the VTT parameter to base constructors/destructors have
30740b57cec5SDimitry Andric   /// virtual bases.
30750b57cec5SDimitry Andric   // FIXME: Every place that calls LoadCXXVTT is something
30760b57cec5SDimitry Andric   // that needs to be abstracted properly.
30770b57cec5SDimitry Andric   llvm::Value *LoadCXXVTT() {
30780b57cec5SDimitry Andric     assert(CXXStructorImplicitParamValue && "no VTT value for this function");
30790b57cec5SDimitry Andric     return CXXStructorImplicitParamValue;
30800b57cec5SDimitry Andric   }
30810b57cec5SDimitry Andric 
30820b57cec5SDimitry Andric   /// GetAddressOfBaseOfCompleteClass - Convert the given pointer to a
30830b57cec5SDimitry Andric   /// complete class to the given direct base.
30840b57cec5SDimitry Andric   Address
30850b57cec5SDimitry Andric   GetAddressOfDirectBaseInCompleteClass(Address Value,
30860b57cec5SDimitry Andric                                         const CXXRecordDecl *Derived,
30870b57cec5SDimitry Andric                                         const CXXRecordDecl *Base,
30880b57cec5SDimitry Andric                                         bool BaseIsVirtual);
30890b57cec5SDimitry Andric 
30900b57cec5SDimitry Andric   static bool ShouldNullCheckClassCastValue(const CastExpr *Cast);
30910b57cec5SDimitry Andric 
30920b57cec5SDimitry Andric   /// GetAddressOfBaseClass - This function will add the necessary delta to the
30930b57cec5SDimitry Andric   /// load of 'this' and returns address of the base class.
30940b57cec5SDimitry Andric   Address GetAddressOfBaseClass(Address Value,
30950b57cec5SDimitry Andric                                 const CXXRecordDecl *Derived,
30960b57cec5SDimitry Andric                                 CastExpr::path_const_iterator PathBegin,
30970b57cec5SDimitry Andric                                 CastExpr::path_const_iterator PathEnd,
30980b57cec5SDimitry Andric                                 bool NullCheckValue, SourceLocation Loc);
30990b57cec5SDimitry Andric 
31000b57cec5SDimitry Andric   Address GetAddressOfDerivedClass(Address Value,
31010b57cec5SDimitry Andric                                    const CXXRecordDecl *Derived,
31020b57cec5SDimitry Andric                                    CastExpr::path_const_iterator PathBegin,
31030b57cec5SDimitry Andric                                    CastExpr::path_const_iterator PathEnd,
31040b57cec5SDimitry Andric                                    bool NullCheckValue);
31050b57cec5SDimitry Andric 
31060b57cec5SDimitry Andric   /// GetVTTParameter - Return the VTT parameter that should be passed to a
31070b57cec5SDimitry Andric   /// base constructor/destructor with virtual bases.
31080b57cec5SDimitry Andric   /// FIXME: VTTs are Itanium ABI-specific, so the definition should move
31090b57cec5SDimitry Andric   /// to ItaniumCXXABI.cpp together with all the references to VTT.
31100b57cec5SDimitry Andric   llvm::Value *GetVTTParameter(GlobalDecl GD, bool ForVirtualBase,
31110b57cec5SDimitry Andric                                bool Delegating);
31120b57cec5SDimitry Andric 
31130b57cec5SDimitry Andric   void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
31140b57cec5SDimitry Andric                                       CXXCtorType CtorType,
31150b57cec5SDimitry Andric                                       const FunctionArgList &Args,
31160b57cec5SDimitry Andric                                       SourceLocation Loc);
31170b57cec5SDimitry Andric   // It's important not to confuse this and the previous function. Delegating
31180b57cec5SDimitry Andric   // constructors are the C++0x feature. The constructor delegate optimization
31190b57cec5SDimitry Andric   // is used to reduce duplication in the base and complete consturctors where
31200b57cec5SDimitry Andric   // they are substantially the same.
31210b57cec5SDimitry Andric   void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor,
31220b57cec5SDimitry Andric                                         const FunctionArgList &Args);
31230b57cec5SDimitry Andric 
31240b57cec5SDimitry Andric   /// Emit a call to an inheriting constructor (that is, one that invokes a
31250b57cec5SDimitry Andric   /// constructor inherited from a base class) by inlining its definition. This
31260b57cec5SDimitry Andric   /// is necessary if the ABI does not support forwarding the arguments to the
31270b57cec5SDimitry Andric   /// base class constructor (because they're variadic or similar).
31280b57cec5SDimitry Andric   void EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor,
31290b57cec5SDimitry Andric                                                CXXCtorType CtorType,
31300b57cec5SDimitry Andric                                                bool ForVirtualBase,
31310b57cec5SDimitry Andric                                                bool Delegating,
31320b57cec5SDimitry Andric                                                CallArgList &Args);
31330b57cec5SDimitry Andric 
31340b57cec5SDimitry Andric   /// Emit a call to a constructor inherited from a base class, passing the
31350b57cec5SDimitry Andric   /// current constructor's arguments along unmodified (without even making
31360b57cec5SDimitry Andric   /// a copy).
31370b57cec5SDimitry Andric   void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D,
31380b57cec5SDimitry Andric                                        bool ForVirtualBase, Address This,
31390b57cec5SDimitry Andric                                        bool InheritedFromVBase,
31400b57cec5SDimitry Andric                                        const CXXInheritedCtorInitExpr *E);
31410b57cec5SDimitry Andric 
31420b57cec5SDimitry Andric   void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
31430b57cec5SDimitry Andric                               bool ForVirtualBase, bool Delegating,
31440b57cec5SDimitry Andric                               AggValueSlot ThisAVS, const CXXConstructExpr *E);
31450b57cec5SDimitry Andric 
31460b57cec5SDimitry Andric   void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
31470b57cec5SDimitry Andric                               bool ForVirtualBase, bool Delegating,
31480b57cec5SDimitry Andric                               Address This, CallArgList &Args,
31490b57cec5SDimitry Andric                               AggValueSlot::Overlap_t Overlap,
31500b57cec5SDimitry Andric                               SourceLocation Loc, bool NewPointerIsChecked);
31510b57cec5SDimitry Andric 
3152bdd1243dSDimitry Andric   /// Emit assumption load for all bases. Requires to be called only on
31530b57cec5SDimitry Andric   /// most-derived class and not under construction of the object.
31540b57cec5SDimitry Andric   void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This);
31550b57cec5SDimitry Andric 
31560b57cec5SDimitry Andric   /// Emit assumption that vptr load == global vtable.
31570b57cec5SDimitry Andric   void EmitVTableAssumptionLoad(const VPtr &vptr, Address This);
31580b57cec5SDimitry Andric 
31590b57cec5SDimitry Andric   void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
31600b57cec5SDimitry Andric                                       Address This, Address Src,
31610b57cec5SDimitry Andric                                       const CXXConstructExpr *E);
31620b57cec5SDimitry Andric 
31630b57cec5SDimitry Andric   void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
31640b57cec5SDimitry Andric                                   const ArrayType *ArrayTy,
31650b57cec5SDimitry Andric                                   Address ArrayPtr,
31660b57cec5SDimitry Andric                                   const CXXConstructExpr *E,
31670b57cec5SDimitry Andric                                   bool NewPointerIsChecked,
31680b57cec5SDimitry Andric                                   bool ZeroInitialization = false);
31690b57cec5SDimitry Andric 
31700b57cec5SDimitry Andric   void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
31710b57cec5SDimitry Andric                                   llvm::Value *NumElements,
31720b57cec5SDimitry Andric                                   Address ArrayPtr,
31730b57cec5SDimitry Andric                                   const CXXConstructExpr *E,
31740b57cec5SDimitry Andric                                   bool NewPointerIsChecked,
31750b57cec5SDimitry Andric                                   bool ZeroInitialization = false);
31760b57cec5SDimitry Andric 
31770b57cec5SDimitry Andric   static Destroyer destroyCXXObject;
31780b57cec5SDimitry Andric 
31790b57cec5SDimitry Andric   void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type,
31800b57cec5SDimitry Andric                              bool ForVirtualBase, bool Delegating, Address This,
31810b57cec5SDimitry Andric                              QualType ThisTy);
31820b57cec5SDimitry Andric 
31830b57cec5SDimitry Andric   void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType,
31840b57cec5SDimitry Andric                                llvm::Type *ElementTy, Address NewPtr,
31850b57cec5SDimitry Andric                                llvm::Value *NumElements,
31860b57cec5SDimitry Andric                                llvm::Value *AllocSizeWithoutCookie);
31870b57cec5SDimitry Andric 
31880b57cec5SDimitry Andric   void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType,
31890b57cec5SDimitry Andric                         Address Ptr);
31900b57cec5SDimitry Andric 
3191fe6060f1SDimitry Andric   void EmitSehCppScopeBegin();
3192fe6060f1SDimitry Andric   void EmitSehCppScopeEnd();
3193fe6060f1SDimitry Andric   void EmitSehTryScopeBegin();
3194fe6060f1SDimitry Andric   void EmitSehTryScopeEnd();
3195fe6060f1SDimitry Andric 
3196fe6060f1SDimitry Andric   llvm::Value *EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr);
31970b57cec5SDimitry Andric   void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr);
31980b57cec5SDimitry Andric 
31990b57cec5SDimitry Andric   llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E);
32000b57cec5SDimitry Andric   void EmitCXXDeleteExpr(const CXXDeleteExpr *E);
32010b57cec5SDimitry Andric 
32020b57cec5SDimitry Andric   void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr,
32030b57cec5SDimitry Andric                       QualType DeleteTy, llvm::Value *NumElements = nullptr,
32040b57cec5SDimitry Andric                       CharUnits CookieSize = CharUnits());
32050b57cec5SDimitry Andric 
32060b57cec5SDimitry Andric   RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type,
32070b57cec5SDimitry Andric                                   const CallExpr *TheCallExpr, bool IsDelete);
32080b57cec5SDimitry Andric 
32090b57cec5SDimitry Andric   llvm::Value *EmitCXXTypeidExpr(const CXXTypeidExpr *E);
32100b57cec5SDimitry Andric   llvm::Value *EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE);
32110b57cec5SDimitry Andric   Address EmitCXXUuidofExpr(const CXXUuidofExpr *E);
32120b57cec5SDimitry Andric 
32130b57cec5SDimitry Andric   /// Situations in which we might emit a check for the suitability of a
32145ffd83dbSDimitry Andric   /// pointer or glvalue. Needs to be kept in sync with ubsan_handlers.cpp in
32155ffd83dbSDimitry Andric   /// compiler-rt.
32160b57cec5SDimitry Andric   enum TypeCheckKind {
32170b57cec5SDimitry Andric     /// Checking the operand of a load. Must be suitably sized and aligned.
32180b57cec5SDimitry Andric     TCK_Load,
32190b57cec5SDimitry Andric     /// Checking the destination of a store. Must be suitably sized and aligned.
32200b57cec5SDimitry Andric     TCK_Store,
32210b57cec5SDimitry Andric     /// Checking the bound value in a reference binding. Must be suitably sized
32220b57cec5SDimitry Andric     /// and aligned, but is not required to refer to an object (until the
32230b57cec5SDimitry Andric     /// reference is used), per core issue 453.
32240b57cec5SDimitry Andric     TCK_ReferenceBinding,
32250b57cec5SDimitry Andric     /// Checking the object expression in a non-static data member access. Must
32260b57cec5SDimitry Andric     /// be an object within its lifetime.
32270b57cec5SDimitry Andric     TCK_MemberAccess,
32280b57cec5SDimitry Andric     /// Checking the 'this' pointer for a call to a non-static member function.
32290b57cec5SDimitry Andric     /// Must be an object within its lifetime.
32300b57cec5SDimitry Andric     TCK_MemberCall,
32310b57cec5SDimitry Andric     /// Checking the 'this' pointer for a constructor call.
32320b57cec5SDimitry Andric     TCK_ConstructorCall,
32330b57cec5SDimitry Andric     /// Checking the operand of a static_cast to a derived pointer type. Must be
32340b57cec5SDimitry Andric     /// null or an object within its lifetime.
32350b57cec5SDimitry Andric     TCK_DowncastPointer,
32360b57cec5SDimitry Andric     /// Checking the operand of a static_cast to a derived reference type. Must
32370b57cec5SDimitry Andric     /// be an object within its lifetime.
32380b57cec5SDimitry Andric     TCK_DowncastReference,
32390b57cec5SDimitry Andric     /// Checking the operand of a cast to a base object. Must be suitably sized
32400b57cec5SDimitry Andric     /// and aligned.
32410b57cec5SDimitry Andric     TCK_Upcast,
32420b57cec5SDimitry Andric     /// Checking the operand of a cast to a virtual base object. Must be an
32430b57cec5SDimitry Andric     /// object within its lifetime.
32440b57cec5SDimitry Andric     TCK_UpcastToVirtualBase,
32450b57cec5SDimitry Andric     /// Checking the value assigned to a _Nonnull pointer. Must not be null.
32460b57cec5SDimitry Andric     TCK_NonnullAssign,
32470b57cec5SDimitry Andric     /// Checking the operand of a dynamic_cast or a typeid expression.  Must be
32480b57cec5SDimitry Andric     /// null or an object within its lifetime.
32490b57cec5SDimitry Andric     TCK_DynamicOperation
32500b57cec5SDimitry Andric   };
32510b57cec5SDimitry Andric 
32520b57cec5SDimitry Andric   /// Determine whether the pointer type check \p TCK permits null pointers.
32530b57cec5SDimitry Andric   static bool isNullPointerAllowed(TypeCheckKind TCK);
32540b57cec5SDimitry Andric 
32550b57cec5SDimitry Andric   /// Determine whether the pointer type check \p TCK requires a vptr check.
32560b57cec5SDimitry Andric   static bool isVptrCheckRequired(TypeCheckKind TCK, QualType Ty);
32570b57cec5SDimitry Andric 
32580b57cec5SDimitry Andric   /// Whether any type-checking sanitizers are enabled. If \c false,
32590b57cec5SDimitry Andric   /// calls to EmitTypeCheck can be skipped.
32600b57cec5SDimitry Andric   bool sanitizePerformTypeCheck() const;
32610b57cec5SDimitry Andric 
32620fca6ea1SDimitry Andric   void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV,
32630fca6ea1SDimitry Andric                      QualType Type, SanitizerSet SkippedChecks = SanitizerSet(),
32640fca6ea1SDimitry Andric                      llvm::Value *ArraySize = nullptr) {
32650fca6ea1SDimitry Andric     if (!sanitizePerformTypeCheck())
32660fca6ea1SDimitry Andric       return;
32670fca6ea1SDimitry Andric     EmitTypeCheck(TCK, Loc, LV.emitRawPointer(*this), Type, LV.getAlignment(),
32680fca6ea1SDimitry Andric                   SkippedChecks, ArraySize);
32690fca6ea1SDimitry Andric   }
32700fca6ea1SDimitry Andric 
32710fca6ea1SDimitry Andric   void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, Address Addr,
32720fca6ea1SDimitry Andric                      QualType Type, CharUnits Alignment = CharUnits::Zero(),
32730fca6ea1SDimitry Andric                      SanitizerSet SkippedChecks = SanitizerSet(),
32740fca6ea1SDimitry Andric                      llvm::Value *ArraySize = nullptr) {
32750fca6ea1SDimitry Andric     if (!sanitizePerformTypeCheck())
32760fca6ea1SDimitry Andric       return;
32770fca6ea1SDimitry Andric     EmitTypeCheck(TCK, Loc, Addr.emitRawPointer(*this), Type, Alignment,
32780fca6ea1SDimitry Andric                   SkippedChecks, ArraySize);
32790fca6ea1SDimitry Andric   }
32800fca6ea1SDimitry Andric 
32810b57cec5SDimitry Andric   /// Emit a check that \p V is the address of storage of the
32820b57cec5SDimitry Andric   /// appropriate size and alignment for an object of type \p Type
32830b57cec5SDimitry Andric   /// (or if ArraySize is provided, for an array of that bound).
32840b57cec5SDimitry Andric   void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V,
32850b57cec5SDimitry Andric                      QualType Type, CharUnits Alignment = CharUnits::Zero(),
32860b57cec5SDimitry Andric                      SanitizerSet SkippedChecks = SanitizerSet(),
32870b57cec5SDimitry Andric                      llvm::Value *ArraySize = nullptr);
32880b57cec5SDimitry Andric 
32890b57cec5SDimitry Andric   /// Emit a check that \p Base points into an array object, which
32900b57cec5SDimitry Andric   /// we can access at index \p Index. \p Accessed should be \c false if we
32910b57cec5SDimitry Andric   /// this expression is used as an lvalue, for instance in "&Arr[Idx]".
32920b57cec5SDimitry Andric   void EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index,
32930b57cec5SDimitry Andric                        QualType IndexType, bool Accessed);
3294297eecfbSDimitry Andric   void EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
3295297eecfbSDimitry Andric                            llvm::Value *Index, QualType IndexType,
3296297eecfbSDimitry Andric                            QualType IndexedType, bool Accessed);
3297297eecfbSDimitry Andric 
32980fca6ea1SDimitry Andric   // Find a struct's flexible array member and get its offset. It may be
32990fca6ea1SDimitry Andric   // embedded inside multiple sub-structs, but must still be the last field.
33000fca6ea1SDimitry Andric   const FieldDecl *
33010fca6ea1SDimitry Andric   FindFlexibleArrayMemberFieldAndOffset(ASTContext &Ctx, const RecordDecl *RD,
33020fca6ea1SDimitry Andric                                         const FieldDecl *FAMDecl,
3303297eecfbSDimitry Andric                                         uint64_t &Offset);
3304297eecfbSDimitry Andric 
3305297eecfbSDimitry Andric   /// Find the FieldDecl specified in a FAM's "counted_by" attribute. Returns
3306297eecfbSDimitry Andric   /// \p nullptr if either the attribute or the field doesn't exist.
3307297eecfbSDimitry Andric   const FieldDecl *FindCountedByField(const FieldDecl *FD);
3308297eecfbSDimitry Andric 
3309297eecfbSDimitry Andric   /// Build an expression accessing the "counted_by" field.
3310297eecfbSDimitry Andric   llvm::Value *EmitCountedByFieldExpr(const Expr *Base,
3311297eecfbSDimitry Andric                                       const FieldDecl *FAMDecl,
3312297eecfbSDimitry Andric                                       const FieldDecl *CountDecl);
33130b57cec5SDimitry Andric 
33140b57cec5SDimitry Andric   llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
33150b57cec5SDimitry Andric                                        bool isInc, bool isPre);
33160b57cec5SDimitry Andric   ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
33170b57cec5SDimitry Andric                                          bool isInc, bool isPre);
33180b57cec5SDimitry Andric 
33190b57cec5SDimitry Andric   /// Converts Location to a DebugLoc, if debug information is enabled.
33200b57cec5SDimitry Andric   llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location);
33210b57cec5SDimitry Andric 
33220b57cec5SDimitry Andric   /// Get the record field index as represented in debug info.
33230b57cec5SDimitry Andric   unsigned getDebugInfoFIndex(const RecordDecl *Rec, unsigned FieldIndex);
33240b57cec5SDimitry Andric 
33250b57cec5SDimitry Andric 
33260b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
33270b57cec5SDimitry Andric   //                            Declaration Emission
33280b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
33290b57cec5SDimitry Andric 
33300b57cec5SDimitry Andric   /// EmitDecl - Emit a declaration.
33310b57cec5SDimitry Andric   ///
33320b57cec5SDimitry Andric   /// This function can be called with a null (unreachable) insert point.
33330b57cec5SDimitry Andric   void EmitDecl(const Decl &D);
33340b57cec5SDimitry Andric 
33350b57cec5SDimitry Andric   /// EmitVarDecl - Emit a local variable declaration.
33360b57cec5SDimitry Andric   ///
33370b57cec5SDimitry Andric   /// This function can be called with a null (unreachable) insert point.
33380b57cec5SDimitry Andric   void EmitVarDecl(const VarDecl &D);
33390b57cec5SDimitry Andric 
33400b57cec5SDimitry Andric   void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue,
33410b57cec5SDimitry Andric                       bool capturedByInit);
33420b57cec5SDimitry Andric 
33430b57cec5SDimitry Andric   typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D,
33440b57cec5SDimitry Andric                              llvm::Value *Address);
33450b57cec5SDimitry Andric 
33460b57cec5SDimitry Andric   /// Determine whether the given initializer is trivial in the sense
33470b57cec5SDimitry Andric   /// that it requires no code to be generated.
33480b57cec5SDimitry Andric   bool isTrivialInitializer(const Expr *Init);
33490b57cec5SDimitry Andric 
33500b57cec5SDimitry Andric   /// EmitAutoVarDecl - Emit an auto variable declaration.
33510b57cec5SDimitry Andric   ///
33520b57cec5SDimitry Andric   /// This function can be called with a null (unreachable) insert point.
33530b57cec5SDimitry Andric   void EmitAutoVarDecl(const VarDecl &D);
33540b57cec5SDimitry Andric 
33550b57cec5SDimitry Andric   class AutoVarEmission {
33560b57cec5SDimitry Andric     friend class CodeGenFunction;
33570b57cec5SDimitry Andric 
33580b57cec5SDimitry Andric     const VarDecl *Variable;
33590b57cec5SDimitry Andric 
33600b57cec5SDimitry Andric     /// The address of the alloca for languages with explicit address space
33610b57cec5SDimitry Andric     /// (e.g. OpenCL) or alloca casted to generic pointer for address space
33620b57cec5SDimitry Andric     /// agnostic languages (e.g. C++). Invalid if the variable was emitted
33630b57cec5SDimitry Andric     /// as a global constant.
33640b57cec5SDimitry Andric     Address Addr;
33650b57cec5SDimitry Andric 
33660b57cec5SDimitry Andric     llvm::Value *NRVOFlag;
33670b57cec5SDimitry Andric 
33680b57cec5SDimitry Andric     /// True if the variable is a __block variable that is captured by an
33690b57cec5SDimitry Andric     /// escaping block.
33700b57cec5SDimitry Andric     bool IsEscapingByRef;
33710b57cec5SDimitry Andric 
33720b57cec5SDimitry Andric     /// True if the variable is of aggregate type and has a constant
33730b57cec5SDimitry Andric     /// initializer.
33740b57cec5SDimitry Andric     bool IsConstantAggregate;
33750b57cec5SDimitry Andric 
33760b57cec5SDimitry Andric     /// Non-null if we should use lifetime annotations.
33770b57cec5SDimitry Andric     llvm::Value *SizeForLifetimeMarkers;
33780b57cec5SDimitry Andric 
33790b57cec5SDimitry Andric     /// Address with original alloca instruction. Invalid if the variable was
33800b57cec5SDimitry Andric     /// emitted as a global constant.
33810fca6ea1SDimitry Andric     RawAddress AllocaAddr;
33820b57cec5SDimitry Andric 
33830b57cec5SDimitry Andric     struct Invalid {};
33840b57cec5SDimitry Andric     AutoVarEmission(Invalid)
33850b57cec5SDimitry Andric         : Variable(nullptr), Addr(Address::invalid()),
33860fca6ea1SDimitry Andric           AllocaAddr(RawAddress::invalid()) {}
33870b57cec5SDimitry Andric 
33880b57cec5SDimitry Andric     AutoVarEmission(const VarDecl &variable)
33890b57cec5SDimitry Andric         : Variable(&variable), Addr(Address::invalid()), NRVOFlag(nullptr),
33900b57cec5SDimitry Andric           IsEscapingByRef(false), IsConstantAggregate(false),
33910fca6ea1SDimitry Andric           SizeForLifetimeMarkers(nullptr), AllocaAddr(RawAddress::invalid()) {}
33920b57cec5SDimitry Andric 
33930b57cec5SDimitry Andric     bool wasEmittedAsGlobal() const { return !Addr.isValid(); }
33940b57cec5SDimitry Andric 
33950b57cec5SDimitry Andric   public:
33960b57cec5SDimitry Andric     static AutoVarEmission invalid() { return AutoVarEmission(Invalid()); }
33970b57cec5SDimitry Andric 
33980b57cec5SDimitry Andric     bool useLifetimeMarkers() const {
33990b57cec5SDimitry Andric       return SizeForLifetimeMarkers != nullptr;
34000b57cec5SDimitry Andric     }
34010b57cec5SDimitry Andric     llvm::Value *getSizeForLifetimeMarkers() const {
34020b57cec5SDimitry Andric       assert(useLifetimeMarkers());
34030b57cec5SDimitry Andric       return SizeForLifetimeMarkers;
34040b57cec5SDimitry Andric     }
34050b57cec5SDimitry Andric 
34060b57cec5SDimitry Andric     /// Returns the raw, allocated address, which is not necessarily
34070b57cec5SDimitry Andric     /// the address of the object itself. It is casted to default
34080b57cec5SDimitry Andric     /// address space for address space agnostic languages.
34090b57cec5SDimitry Andric     Address getAllocatedAddress() const {
34100b57cec5SDimitry Andric       return Addr;
34110b57cec5SDimitry Andric     }
34120b57cec5SDimitry Andric 
34130b57cec5SDimitry Andric     /// Returns the address for the original alloca instruction.
34140fca6ea1SDimitry Andric     RawAddress getOriginalAllocatedAddress() const { return AllocaAddr; }
34150b57cec5SDimitry Andric 
34160b57cec5SDimitry Andric     /// Returns the address of the object within this declaration.
34170b57cec5SDimitry Andric     /// Note that this does not chase the forwarding pointer for
34180b57cec5SDimitry Andric     /// __block decls.
34190b57cec5SDimitry Andric     Address getObjectAddress(CodeGenFunction &CGF) const {
34200b57cec5SDimitry Andric       if (!IsEscapingByRef) return Addr;
34210b57cec5SDimitry Andric 
34220b57cec5SDimitry Andric       return CGF.emitBlockByrefAddress(Addr, Variable, /*forward*/ false);
34230b57cec5SDimitry Andric     }
34240b57cec5SDimitry Andric   };
34250b57cec5SDimitry Andric   AutoVarEmission EmitAutoVarAlloca(const VarDecl &var);
34260b57cec5SDimitry Andric   void EmitAutoVarInit(const AutoVarEmission &emission);
34270b57cec5SDimitry Andric   void EmitAutoVarCleanups(const AutoVarEmission &emission);
34280b57cec5SDimitry Andric   void emitAutoVarTypeCleanup(const AutoVarEmission &emission,
34290b57cec5SDimitry Andric                               QualType::DestructionKind dtorKind);
34300b57cec5SDimitry Andric 
34310b57cec5SDimitry Andric   /// Emits the alloca and debug information for the size expressions for each
34320b57cec5SDimitry Andric   /// dimension of an array. It registers the association of its (1-dimensional)
34330b57cec5SDimitry Andric   /// QualTypes and size expression's debug node, so that CGDebugInfo can
34340b57cec5SDimitry Andric   /// reference this node when creating the DISubrange object to describe the
34350b57cec5SDimitry Andric   /// array types.
34360b57cec5SDimitry Andric   void EmitAndRegisterVariableArrayDimensions(CGDebugInfo *DI,
34370b57cec5SDimitry Andric                                               const VarDecl &D,
34380b57cec5SDimitry Andric                                               bool EmitDebugInfo);
34390b57cec5SDimitry Andric 
34400b57cec5SDimitry Andric   void EmitStaticVarDecl(const VarDecl &D,
34410b57cec5SDimitry Andric                          llvm::GlobalValue::LinkageTypes Linkage);
34420b57cec5SDimitry Andric 
34430b57cec5SDimitry Andric   class ParamValue {
34440fca6ea1SDimitry Andric     union {
34450fca6ea1SDimitry Andric       Address Addr;
34460b57cec5SDimitry Andric       llvm::Value *Value;
34470fca6ea1SDimitry Andric     };
34480fca6ea1SDimitry Andric 
34490fca6ea1SDimitry Andric     bool IsIndirect;
34500fca6ea1SDimitry Andric 
34510fca6ea1SDimitry Andric     ParamValue(llvm::Value *V) : Value(V), IsIndirect(false) {}
34520fca6ea1SDimitry Andric     ParamValue(Address A) : Addr(A), IsIndirect(true) {}
34530fca6ea1SDimitry Andric 
34540b57cec5SDimitry Andric   public:
34550b57cec5SDimitry Andric     static ParamValue forDirect(llvm::Value *value) {
34560fca6ea1SDimitry Andric       return ParamValue(value);
34570b57cec5SDimitry Andric     }
34580b57cec5SDimitry Andric     static ParamValue forIndirect(Address addr) {
34590b57cec5SDimitry Andric       assert(!addr.getAlignment().isZero());
34600fca6ea1SDimitry Andric       return ParamValue(addr);
34610b57cec5SDimitry Andric     }
34620b57cec5SDimitry Andric 
34630fca6ea1SDimitry Andric     bool isIndirect() const { return IsIndirect; }
34640fca6ea1SDimitry Andric     llvm::Value *getAnyValue() const {
34650fca6ea1SDimitry Andric       if (!isIndirect())
34660fca6ea1SDimitry Andric         return Value;
34670fca6ea1SDimitry Andric       assert(!Addr.hasOffset() && "unexpected offset");
34680fca6ea1SDimitry Andric       return Addr.getBasePointer();
34690fca6ea1SDimitry Andric     }
34700b57cec5SDimitry Andric 
34710b57cec5SDimitry Andric     llvm::Value *getDirectValue() const {
34720b57cec5SDimitry Andric       assert(!isIndirect());
34730b57cec5SDimitry Andric       return Value;
34740b57cec5SDimitry Andric     }
34750b57cec5SDimitry Andric 
34760b57cec5SDimitry Andric     Address getIndirectAddress() const {
34770b57cec5SDimitry Andric       assert(isIndirect());
34780fca6ea1SDimitry Andric       return Addr;
34790b57cec5SDimitry Andric     }
34800b57cec5SDimitry Andric   };
34810b57cec5SDimitry Andric 
34820b57cec5SDimitry Andric   /// EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
34830b57cec5SDimitry Andric   void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo);
34840b57cec5SDimitry Andric 
34850b57cec5SDimitry Andric   /// protectFromPeepholes - Protect a value that we're intending to
34860b57cec5SDimitry Andric   /// store to the side, but which will probably be used later, from
34870b57cec5SDimitry Andric   /// aggressive peepholing optimizations that might delete it.
34880b57cec5SDimitry Andric   ///
34890b57cec5SDimitry Andric   /// Pass the result to unprotectFromPeepholes to declare that
34900b57cec5SDimitry Andric   /// protection is no longer required.
34910b57cec5SDimitry Andric   ///
34920b57cec5SDimitry Andric   /// There's no particular reason why this shouldn't apply to
34930b57cec5SDimitry Andric   /// l-values, it's just that no existing peepholes work on pointers.
34940b57cec5SDimitry Andric   PeepholeProtection protectFromPeepholes(RValue rvalue);
34950b57cec5SDimitry Andric   void unprotectFromPeepholes(PeepholeProtection protection);
34960b57cec5SDimitry Andric 
34975ffd83dbSDimitry Andric   void emitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType Ty,
34980b57cec5SDimitry Andric                                     SourceLocation Loc,
34990b57cec5SDimitry Andric                                     SourceLocation AssumptionLoc,
35000b57cec5SDimitry Andric                                     llvm::Value *Alignment,
35010b57cec5SDimitry Andric                                     llvm::Value *OffsetValue,
35020b57cec5SDimitry Andric                                     llvm::Value *TheCheck,
35030b57cec5SDimitry Andric                                     llvm::Instruction *Assumption);
35040b57cec5SDimitry Andric 
35055ffd83dbSDimitry Andric   void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty,
35060b57cec5SDimitry Andric                                SourceLocation Loc, SourceLocation AssumptionLoc,
35070b57cec5SDimitry Andric                                llvm::Value *Alignment,
35080b57cec5SDimitry Andric                                llvm::Value *OffsetValue = nullptr);
35090b57cec5SDimitry Andric 
35105ffd83dbSDimitry Andric   void emitAlignmentAssumption(llvm::Value *PtrValue, const Expr *E,
35115ffd83dbSDimitry Andric                                SourceLocation AssumptionLoc,
35125ffd83dbSDimitry Andric                                llvm::Value *Alignment,
35130b57cec5SDimitry Andric                                llvm::Value *OffsetValue = nullptr);
35140b57cec5SDimitry Andric 
35150b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
35160b57cec5SDimitry Andric   //                             Statement Emission
35170b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
35180b57cec5SDimitry Andric 
35190b57cec5SDimitry Andric   /// EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.
35200b57cec5SDimitry Andric   void EmitStopPoint(const Stmt *S);
35210b57cec5SDimitry Andric 
35220b57cec5SDimitry Andric   /// EmitStmt - Emit the code for the statement \arg S. It is legal to call
35230b57cec5SDimitry Andric   /// this function even if there is no current insertion point.
35240b57cec5SDimitry Andric   ///
35250b57cec5SDimitry Andric   /// This function may clear the current insertion point; callers should use
35260b57cec5SDimitry Andric   /// EnsureInsertPoint if they wish to subsequently generate code without first
35270b57cec5SDimitry Andric   /// calling EmitBlock, EmitBranch, or EmitStmt.
3528bdd1243dSDimitry Andric   void EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs = std::nullopt);
35290b57cec5SDimitry Andric 
35300b57cec5SDimitry Andric   /// EmitSimpleStmt - Try to emit a "simple" statement which does not
35310b57cec5SDimitry Andric   /// necessarily require an insertion point or debug information; typically
35320b57cec5SDimitry Andric   /// because the statement amounts to a jump or a container of other
35330b57cec5SDimitry Andric   /// statements.
35340b57cec5SDimitry Andric   ///
35350b57cec5SDimitry Andric   /// \return True if the statement was handled.
3536e8d8bef9SDimitry Andric   bool EmitSimpleStmt(const Stmt *S, ArrayRef<const Attr *> Attrs);
35370b57cec5SDimitry Andric 
35380b57cec5SDimitry Andric   Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false,
35390b57cec5SDimitry Andric                            AggValueSlot AVS = AggValueSlot::ignored());
35400b57cec5SDimitry Andric   Address EmitCompoundStmtWithoutScope(const CompoundStmt &S,
35410b57cec5SDimitry Andric                                        bool GetLast = false,
35420b57cec5SDimitry Andric                                        AggValueSlot AVS =
35430b57cec5SDimitry Andric                                                 AggValueSlot::ignored());
35440b57cec5SDimitry Andric 
35450b57cec5SDimitry Andric   /// EmitLabel - Emit the block for the given label. It is legal to call this
35460b57cec5SDimitry Andric   /// function even if there is no current insertion point.
35470b57cec5SDimitry Andric   void EmitLabel(const LabelDecl *D); // helper for EmitLabelStmt.
35480b57cec5SDimitry Andric 
35490b57cec5SDimitry Andric   void EmitLabelStmt(const LabelStmt &S);
35500b57cec5SDimitry Andric   void EmitAttributedStmt(const AttributedStmt &S);
35510b57cec5SDimitry Andric   void EmitGotoStmt(const GotoStmt &S);
35520b57cec5SDimitry Andric   void EmitIndirectGotoStmt(const IndirectGotoStmt &S);
35530b57cec5SDimitry Andric   void EmitIfStmt(const IfStmt &S);
35540b57cec5SDimitry Andric 
35550b57cec5SDimitry Andric   void EmitWhileStmt(const WhileStmt &S,
3556bdd1243dSDimitry Andric                      ArrayRef<const Attr *> Attrs = std::nullopt);
3557bdd1243dSDimitry Andric   void EmitDoStmt(const DoStmt &S, ArrayRef<const Attr *> Attrs = std::nullopt);
35580b57cec5SDimitry Andric   void EmitForStmt(const ForStmt &S,
3559bdd1243dSDimitry Andric                    ArrayRef<const Attr *> Attrs = std::nullopt);
35600b57cec5SDimitry Andric   void EmitReturnStmt(const ReturnStmt &S);
35610b57cec5SDimitry Andric   void EmitDeclStmt(const DeclStmt &S);
35620b57cec5SDimitry Andric   void EmitBreakStmt(const BreakStmt &S);
35630b57cec5SDimitry Andric   void EmitContinueStmt(const ContinueStmt &S);
35640b57cec5SDimitry Andric   void EmitSwitchStmt(const SwitchStmt &S);
3565e8d8bef9SDimitry Andric   void EmitDefaultStmt(const DefaultStmt &S, ArrayRef<const Attr *> Attrs);
3566e8d8bef9SDimitry Andric   void EmitCaseStmt(const CaseStmt &S, ArrayRef<const Attr *> Attrs);
3567e8d8bef9SDimitry Andric   void EmitCaseStmtRange(const CaseStmt &S, ArrayRef<const Attr *> Attrs);
35680b57cec5SDimitry Andric   void EmitAsmStmt(const AsmStmt &S);
35690b57cec5SDimitry Andric 
35700b57cec5SDimitry Andric   void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S);
35710b57cec5SDimitry Andric   void EmitObjCAtTryStmt(const ObjCAtTryStmt &S);
35720b57cec5SDimitry Andric   void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S);
35730b57cec5SDimitry Andric   void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S);
35740b57cec5SDimitry Andric   void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S);
35750b57cec5SDimitry Andric 
35760b57cec5SDimitry Andric   void EmitCoroutineBody(const CoroutineBodyStmt &S);
35770b57cec5SDimitry Andric   void EmitCoreturnStmt(const CoreturnStmt &S);
35780b57cec5SDimitry Andric   RValue EmitCoawaitExpr(const CoawaitExpr &E,
35790b57cec5SDimitry Andric                          AggValueSlot aggSlot = AggValueSlot::ignored(),
35800b57cec5SDimitry Andric                          bool ignoreResult = false);
35810b57cec5SDimitry Andric   LValue EmitCoawaitLValue(const CoawaitExpr *E);
35820b57cec5SDimitry Andric   RValue EmitCoyieldExpr(const CoyieldExpr &E,
35830b57cec5SDimitry Andric                          AggValueSlot aggSlot = AggValueSlot::ignored(),
35840b57cec5SDimitry Andric                          bool ignoreResult = false);
35850b57cec5SDimitry Andric   LValue EmitCoyieldLValue(const CoyieldExpr *E);
35860b57cec5SDimitry Andric   RValue EmitCoroutineIntrinsic(const CallExpr *E, unsigned int IID);
35870b57cec5SDimitry Andric 
35880b57cec5SDimitry Andric   void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
35890b57cec5SDimitry Andric   void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
35900b57cec5SDimitry Andric 
35910b57cec5SDimitry Andric   void EmitCXXTryStmt(const CXXTryStmt &S);
35920b57cec5SDimitry Andric   void EmitSEHTryStmt(const SEHTryStmt &S);
35930b57cec5SDimitry Andric   void EmitSEHLeaveStmt(const SEHLeaveStmt &S);
35940b57cec5SDimitry Andric   void EnterSEHTryStmt(const SEHTryStmt &S);
35950b57cec5SDimitry Andric   void ExitSEHTryStmt(const SEHTryStmt &S);
3596fe6060f1SDimitry Andric   void VolatilizeTryBlocks(llvm::BasicBlock *BB,
3597fe6060f1SDimitry Andric                            llvm::SmallPtrSet<llvm::BasicBlock *, 10> &V);
35980b57cec5SDimitry Andric 
35990b57cec5SDimitry Andric   void pushSEHCleanup(CleanupKind kind,
36000b57cec5SDimitry Andric                       llvm::Function *FinallyFunc);
36010b57cec5SDimitry Andric   void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter,
36020b57cec5SDimitry Andric                               const Stmt *OutlinedStmt);
36030b57cec5SDimitry Andric 
36040b57cec5SDimitry Andric   llvm::Function *GenerateSEHFilterFunction(CodeGenFunction &ParentCGF,
36050b57cec5SDimitry Andric                                             const SEHExceptStmt &Except);
36060b57cec5SDimitry Andric 
36070b57cec5SDimitry Andric   llvm::Function *GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF,
36080b57cec5SDimitry Andric                                              const SEHFinallyStmt &Finally);
36090b57cec5SDimitry Andric 
36100b57cec5SDimitry Andric   void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF,
36110b57cec5SDimitry Andric                                 llvm::Value *ParentFP,
36120b57cec5SDimitry Andric                                 llvm::Value *EntryEBP);
36130b57cec5SDimitry Andric   llvm::Value *EmitSEHExceptionCode();
36140b57cec5SDimitry Andric   llvm::Value *EmitSEHExceptionInfo();
36150b57cec5SDimitry Andric   llvm::Value *EmitSEHAbnormalTermination();
36160b57cec5SDimitry Andric 
36170b57cec5SDimitry Andric   /// Emit simple code for OpenMP directives in Simd-only mode.
36180b57cec5SDimitry Andric   void EmitSimpleOMPExecutableDirective(const OMPExecutableDirective &D);
36190b57cec5SDimitry Andric 
36200b57cec5SDimitry Andric   /// Scan the outlined statement for captures from the parent function. For
36210b57cec5SDimitry Andric   /// each capture, mark the capture as escaped and emit a call to
36220b57cec5SDimitry Andric   /// llvm.localrecover. Insert the localrecover result into the LocalDeclMap.
36230b57cec5SDimitry Andric   void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt,
36240b57cec5SDimitry Andric                           bool IsFilter);
36250b57cec5SDimitry Andric 
36260b57cec5SDimitry Andric   /// Recovers the address of a local in a parent function. ParentVar is the
36270b57cec5SDimitry Andric   /// address of the variable used in the immediate parent function. It can
36280b57cec5SDimitry Andric   /// either be an alloca or a call to llvm.localrecover if there are nested
36290b57cec5SDimitry Andric   /// outlined functions. ParentFP is the frame pointer of the outermost parent
36300b57cec5SDimitry Andric   /// frame.
36310b57cec5SDimitry Andric   Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,
36320b57cec5SDimitry Andric                                     Address ParentVar,
36330b57cec5SDimitry Andric                                     llvm::Value *ParentFP);
36340b57cec5SDimitry Andric 
36350b57cec5SDimitry Andric   void EmitCXXForRangeStmt(const CXXForRangeStmt &S,
3636bdd1243dSDimitry Andric                            ArrayRef<const Attr *> Attrs = std::nullopt);
36370b57cec5SDimitry Andric 
36380b57cec5SDimitry Andric   /// Controls insertion of cancellation exit blocks in worksharing constructs.
36390b57cec5SDimitry Andric   class OMPCancelStackRAII {
36400b57cec5SDimitry Andric     CodeGenFunction &CGF;
36410b57cec5SDimitry Andric 
36420b57cec5SDimitry Andric   public:
36430b57cec5SDimitry Andric     OMPCancelStackRAII(CodeGenFunction &CGF, OpenMPDirectiveKind Kind,
36440b57cec5SDimitry Andric                        bool HasCancel)
36450b57cec5SDimitry Andric         : CGF(CGF) {
36460b57cec5SDimitry Andric       CGF.OMPCancelStack.enter(CGF, Kind, HasCancel);
36470b57cec5SDimitry Andric     }
36480b57cec5SDimitry Andric     ~OMPCancelStackRAII() { CGF.OMPCancelStack.exit(CGF); }
36490b57cec5SDimitry Andric   };
36500b57cec5SDimitry Andric 
36510b57cec5SDimitry Andric   /// Returns calculated size of the specified type.
36520b57cec5SDimitry Andric   llvm::Value *getTypeSize(QualType Ty);
36530b57cec5SDimitry Andric   LValue InitCapturedStruct(const CapturedStmt &S);
36540b57cec5SDimitry Andric   llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K);
36550b57cec5SDimitry Andric   llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S);
36560b57cec5SDimitry Andric   Address GenerateCapturedStmtArgument(const CapturedStmt &S);
36575ffd83dbSDimitry Andric   llvm::Function *GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
36585ffd83dbSDimitry Andric                                                      SourceLocation Loc);
36590b57cec5SDimitry Andric   void GenerateOpenMPCapturedVars(const CapturedStmt &S,
36600b57cec5SDimitry Andric                                   SmallVectorImpl<llvm::Value *> &CapturedVars);
36610b57cec5SDimitry Andric   void emitOMPSimpleStore(LValue LVal, RValue RVal, QualType RValTy,
36620b57cec5SDimitry Andric                           SourceLocation Loc);
36630b57cec5SDimitry Andric   /// Perform element by element copying of arrays with type \a
36640b57cec5SDimitry Andric   /// OriginalType from \a SrcAddr to \a DestAddr using copying procedure
36650b57cec5SDimitry Andric   /// generated by \a CopyGen.
36660b57cec5SDimitry Andric   ///
36670b57cec5SDimitry Andric   /// \param DestAddr Address of the destination array.
36680b57cec5SDimitry Andric   /// \param SrcAddr Address of the source array.
36690b57cec5SDimitry Andric   /// \param OriginalType Type of destination and source arrays.
36700b57cec5SDimitry Andric   /// \param CopyGen Copying procedure that copies value of single array element
36710b57cec5SDimitry Andric   /// to another single array element.
36720b57cec5SDimitry Andric   void EmitOMPAggregateAssign(
36730b57cec5SDimitry Andric       Address DestAddr, Address SrcAddr, QualType OriginalType,
36740b57cec5SDimitry Andric       const llvm::function_ref<void(Address, Address)> CopyGen);
36750b57cec5SDimitry Andric   /// Emit proper copying of data from one variable to another.
36760b57cec5SDimitry Andric   ///
36770b57cec5SDimitry Andric   /// \param OriginalType Original type of the copied variables.
36780b57cec5SDimitry Andric   /// \param DestAddr Destination address.
36790b57cec5SDimitry Andric   /// \param SrcAddr Source address.
36800b57cec5SDimitry Andric   /// \param DestVD Destination variable used in \a CopyExpr (for arrays, has
36810b57cec5SDimitry Andric   /// type of the base array element).
36820b57cec5SDimitry Andric   /// \param SrcVD Source variable used in \a CopyExpr (for arrays, has type of
36830b57cec5SDimitry Andric   /// the base array element).
36840b57cec5SDimitry Andric   /// \param Copy Actual copygin expression for copying data from \a SrcVD to \a
36850b57cec5SDimitry Andric   /// DestVD.
36860b57cec5SDimitry Andric   void EmitOMPCopy(QualType OriginalType,
36870b57cec5SDimitry Andric                    Address DestAddr, Address SrcAddr,
36880b57cec5SDimitry Andric                    const VarDecl *DestVD, const VarDecl *SrcVD,
36890b57cec5SDimitry Andric                    const Expr *Copy);
36900b57cec5SDimitry Andric   /// Emit atomic update code for constructs: \a X = \a X \a BO \a E or
36910b57cec5SDimitry Andric   /// \a X = \a E \a BO \a E.
36920b57cec5SDimitry Andric   ///
36930b57cec5SDimitry Andric   /// \param X Value to be updated.
36940b57cec5SDimitry Andric   /// \param E Update value.
36950b57cec5SDimitry Andric   /// \param BO Binary operation for update operation.
36960b57cec5SDimitry Andric   /// \param IsXLHSInRHSPart true if \a X is LHS in RHS part of the update
36970b57cec5SDimitry Andric   /// expression, false otherwise.
36980b57cec5SDimitry Andric   /// \param AO Atomic ordering of the generated atomic instructions.
36990b57cec5SDimitry Andric   /// \param CommonGen Code generator for complex expressions that cannot be
37000b57cec5SDimitry Andric   /// expressed through atomicrmw instruction.
37010b57cec5SDimitry Andric   /// \returns <true, OldAtomicValue> if simple 'atomicrmw' instruction was
37020b57cec5SDimitry Andric   /// generated, <false, RValue::get(nullptr)> otherwise.
37030b57cec5SDimitry Andric   std::pair<bool, RValue> EmitOMPAtomicSimpleUpdateExpr(
37040b57cec5SDimitry Andric       LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart,
37050b57cec5SDimitry Andric       llvm::AtomicOrdering AO, SourceLocation Loc,
37060b57cec5SDimitry Andric       const llvm::function_ref<RValue(RValue)> CommonGen);
37070b57cec5SDimitry Andric   bool EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
37080b57cec5SDimitry Andric                                  OMPPrivateScope &PrivateScope);
37090b57cec5SDimitry Andric   void EmitOMPPrivateClause(const OMPExecutableDirective &D,
37100b57cec5SDimitry Andric                             OMPPrivateScope &PrivateScope);
37110b57cec5SDimitry Andric   void EmitOMPUseDevicePtrClause(
37125ffd83dbSDimitry Andric       const OMPUseDevicePtrClause &C, OMPPrivateScope &PrivateScope,
371306c3fb27SDimitry Andric       const llvm::DenseMap<const ValueDecl *, llvm::Value *>
371406c3fb27SDimitry Andric           CaptureDeviceAddrMap);
37155ffd83dbSDimitry Andric   void EmitOMPUseDeviceAddrClause(
37165ffd83dbSDimitry Andric       const OMPUseDeviceAddrClause &C, OMPPrivateScope &PrivateScope,
371706c3fb27SDimitry Andric       const llvm::DenseMap<const ValueDecl *, llvm::Value *>
371806c3fb27SDimitry Andric           CaptureDeviceAddrMap);
37190b57cec5SDimitry Andric   /// Emit code for copyin clause in \a D directive. The next code is
37200b57cec5SDimitry Andric   /// generated at the start of outlined functions for directives:
37210b57cec5SDimitry Andric   /// \code
37220b57cec5SDimitry Andric   /// threadprivate_var1 = master_threadprivate_var1;
37230b57cec5SDimitry Andric   /// operator=(threadprivate_var2, master_threadprivate_var2);
37240b57cec5SDimitry Andric   /// ...
37250b57cec5SDimitry Andric   /// __kmpc_barrier(&loc, global_tid);
37260b57cec5SDimitry Andric   /// \endcode
37270b57cec5SDimitry Andric   ///
37280b57cec5SDimitry Andric   /// \param D OpenMP directive possibly with 'copyin' clause(s).
37290b57cec5SDimitry Andric   /// \returns true if at least one copyin variable is found, false otherwise.
37300b57cec5SDimitry Andric   bool EmitOMPCopyinClause(const OMPExecutableDirective &D);
37310b57cec5SDimitry Andric   /// Emit initial code for lastprivate variables. If some variable is
37320b57cec5SDimitry Andric   /// not also firstprivate, then the default initialization is used. Otherwise
37330b57cec5SDimitry Andric   /// initialization of this variable is performed by EmitOMPFirstprivateClause
37340b57cec5SDimitry Andric   /// method.
37350b57cec5SDimitry Andric   ///
37360b57cec5SDimitry Andric   /// \param D Directive that may have 'lastprivate' directives.
37370b57cec5SDimitry Andric   /// \param PrivateScope Private scope for capturing lastprivate variables for
37380b57cec5SDimitry Andric   /// proper codegen in internal captured statement.
37390b57cec5SDimitry Andric   ///
37400b57cec5SDimitry Andric   /// \returns true if there is at least one lastprivate variable, false
37410b57cec5SDimitry Andric   /// otherwise.
37420b57cec5SDimitry Andric   bool EmitOMPLastprivateClauseInit(const OMPExecutableDirective &D,
37430b57cec5SDimitry Andric                                     OMPPrivateScope &PrivateScope);
37440b57cec5SDimitry Andric   /// Emit final copying of lastprivate values to original variables at
37450b57cec5SDimitry Andric   /// the end of the worksharing or simd directive.
37460b57cec5SDimitry Andric   ///
37470b57cec5SDimitry Andric   /// \param D Directive that has at least one 'lastprivate' directives.
37480b57cec5SDimitry Andric   /// \param IsLastIterCond Boolean condition that must be set to 'i1 true' if
37490b57cec5SDimitry Andric   /// it is the last iteration of the loop code in associated directive, or to
37500b57cec5SDimitry Andric   /// 'i1 false' otherwise. If this item is nullptr, no final check is required.
37510b57cec5SDimitry Andric   void EmitOMPLastprivateClauseFinal(const OMPExecutableDirective &D,
37520b57cec5SDimitry Andric                                      bool NoFinals,
37530b57cec5SDimitry Andric                                      llvm::Value *IsLastIterCond = nullptr);
37540b57cec5SDimitry Andric   /// Emit initial code for linear clauses.
37550b57cec5SDimitry Andric   void EmitOMPLinearClause(const OMPLoopDirective &D,
37560b57cec5SDimitry Andric                            CodeGenFunction::OMPPrivateScope &PrivateScope);
37570b57cec5SDimitry Andric   /// Emit final code for linear clauses.
37580b57cec5SDimitry Andric   /// \param CondGen Optional conditional code for final part of codegen for
37590b57cec5SDimitry Andric   /// linear clause.
37600b57cec5SDimitry Andric   void EmitOMPLinearClauseFinal(
37610b57cec5SDimitry Andric       const OMPLoopDirective &D,
37620b57cec5SDimitry Andric       const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen);
37630b57cec5SDimitry Andric   /// Emit initial code for reduction variables. Creates reduction copies
37640b57cec5SDimitry Andric   /// and initializes them with the values according to OpenMP standard.
37650b57cec5SDimitry Andric   ///
37660b57cec5SDimitry Andric   /// \param D Directive (possibly) with the 'reduction' clause.
37670b57cec5SDimitry Andric   /// \param PrivateScope Private scope for capturing reduction variables for
37680b57cec5SDimitry Andric   /// proper codegen in internal captured statement.
37690b57cec5SDimitry Andric   ///
37700b57cec5SDimitry Andric   void EmitOMPReductionClauseInit(const OMPExecutableDirective &D,
37715ffd83dbSDimitry Andric                                   OMPPrivateScope &PrivateScope,
37725ffd83dbSDimitry Andric                                   bool ForInscan = false);
37730b57cec5SDimitry Andric   /// Emit final update of reduction values to original variables at
37740b57cec5SDimitry Andric   /// the end of the directive.
37750b57cec5SDimitry Andric   ///
37760b57cec5SDimitry Andric   /// \param D Directive that has at least one 'reduction' directives.
37770b57cec5SDimitry Andric   /// \param ReductionKind The kind of reduction to perform.
37780b57cec5SDimitry Andric   void EmitOMPReductionClauseFinal(const OMPExecutableDirective &D,
37790b57cec5SDimitry Andric                                    const OpenMPDirectiveKind ReductionKind);
37800b57cec5SDimitry Andric   /// Emit initial code for linear variables. Creates private copies
37810b57cec5SDimitry Andric   /// and initializes them with the values according to OpenMP standard.
37820b57cec5SDimitry Andric   ///
37830b57cec5SDimitry Andric   /// \param D Directive (possibly) with the 'linear' clause.
37840b57cec5SDimitry Andric   /// \return true if at least one linear variable is found that should be
37850b57cec5SDimitry Andric   /// initialized with the value of the original variable, false otherwise.
37860b57cec5SDimitry Andric   bool EmitOMPLinearClauseInit(const OMPLoopDirective &D);
37870b57cec5SDimitry Andric 
37880b57cec5SDimitry Andric   typedef const llvm::function_ref<void(CodeGenFunction & /*CGF*/,
37890b57cec5SDimitry Andric                                         llvm::Function * /*OutlinedFn*/,
37900b57cec5SDimitry Andric                                         const OMPTaskDataTy & /*Data*/)>
37910b57cec5SDimitry Andric       TaskGenTy;
37920b57cec5SDimitry Andric   void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S,
37930b57cec5SDimitry Andric                                  const OpenMPDirectiveKind CapturedRegion,
37940b57cec5SDimitry Andric                                  const RegionCodeGenTy &BodyGen,
37950b57cec5SDimitry Andric                                  const TaskGenTy &TaskGen, OMPTaskDataTy &Data);
37960b57cec5SDimitry Andric   struct OMPTargetDataInfo {
37970b57cec5SDimitry Andric     Address BasePointersArray = Address::invalid();
37980b57cec5SDimitry Andric     Address PointersArray = Address::invalid();
37990b57cec5SDimitry Andric     Address SizesArray = Address::invalid();
3800e8d8bef9SDimitry Andric     Address MappersArray = Address::invalid();
38010b57cec5SDimitry Andric     unsigned NumberOfTargetItems = 0;
38020b57cec5SDimitry Andric     explicit OMPTargetDataInfo() = default;
38030b57cec5SDimitry Andric     OMPTargetDataInfo(Address BasePointersArray, Address PointersArray,
3804e8d8bef9SDimitry Andric                       Address SizesArray, Address MappersArray,
3805e8d8bef9SDimitry Andric                       unsigned NumberOfTargetItems)
38060b57cec5SDimitry Andric         : BasePointersArray(BasePointersArray), PointersArray(PointersArray),
3807e8d8bef9SDimitry Andric           SizesArray(SizesArray), MappersArray(MappersArray),
3808e8d8bef9SDimitry Andric           NumberOfTargetItems(NumberOfTargetItems) {}
38090b57cec5SDimitry Andric   };
38100b57cec5SDimitry Andric   void EmitOMPTargetTaskBasedDirective(const OMPExecutableDirective &S,
38110b57cec5SDimitry Andric                                        const RegionCodeGenTy &BodyGen,
38120b57cec5SDimitry Andric                                        OMPTargetDataInfo &InputInfo);
381381ad6265SDimitry Andric   void processInReduction(const OMPExecutableDirective &S,
381481ad6265SDimitry Andric                           OMPTaskDataTy &Data,
381581ad6265SDimitry Andric                           CodeGenFunction &CGF,
381681ad6265SDimitry Andric                           const CapturedStmt *CS,
381781ad6265SDimitry Andric                           OMPPrivateScope &Scope);
3818349cc55cSDimitry Andric   void EmitOMPMetaDirective(const OMPMetaDirective &S);
38190b57cec5SDimitry Andric   void EmitOMPParallelDirective(const OMPParallelDirective &S);
38200b57cec5SDimitry Andric   void EmitOMPSimdDirective(const OMPSimdDirective &S);
3821fe6060f1SDimitry Andric   void EmitOMPTileDirective(const OMPTileDirective &S);
3822fe6060f1SDimitry Andric   void EmitOMPUnrollDirective(const OMPUnrollDirective &S);
38230fca6ea1SDimitry Andric   void EmitOMPReverseDirective(const OMPReverseDirective &S);
38240fca6ea1SDimitry Andric   void EmitOMPInterchangeDirective(const OMPInterchangeDirective &S);
38250b57cec5SDimitry Andric   void EmitOMPForDirective(const OMPForDirective &S);
38260b57cec5SDimitry Andric   void EmitOMPForSimdDirective(const OMPForSimdDirective &S);
38270b57cec5SDimitry Andric   void EmitOMPSectionsDirective(const OMPSectionsDirective &S);
38280b57cec5SDimitry Andric   void EmitOMPSectionDirective(const OMPSectionDirective &S);
38290b57cec5SDimitry Andric   void EmitOMPSingleDirective(const OMPSingleDirective &S);
38300b57cec5SDimitry Andric   void EmitOMPMasterDirective(const OMPMasterDirective &S);
3831fe6060f1SDimitry Andric   void EmitOMPMaskedDirective(const OMPMaskedDirective &S);
38320b57cec5SDimitry Andric   void EmitOMPCriticalDirective(const OMPCriticalDirective &S);
38330b57cec5SDimitry Andric   void EmitOMPParallelForDirective(const OMPParallelForDirective &S);
38340b57cec5SDimitry Andric   void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S);
38350b57cec5SDimitry Andric   void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S);
3836480093f4SDimitry Andric   void EmitOMPParallelMasterDirective(const OMPParallelMasterDirective &S);
38370b57cec5SDimitry Andric   void EmitOMPTaskDirective(const OMPTaskDirective &S);
38380b57cec5SDimitry Andric   void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S);
3839bdd1243dSDimitry Andric   void EmitOMPErrorDirective(const OMPErrorDirective &S);
38400b57cec5SDimitry Andric   void EmitOMPBarrierDirective(const OMPBarrierDirective &S);
38410b57cec5SDimitry Andric   void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S);
38420b57cec5SDimitry Andric   void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S);
38430b57cec5SDimitry Andric   void EmitOMPFlushDirective(const OMPFlushDirective &S);
38445ffd83dbSDimitry Andric   void EmitOMPDepobjDirective(const OMPDepobjDirective &S);
38455ffd83dbSDimitry Andric   void EmitOMPScanDirective(const OMPScanDirective &S);
38460b57cec5SDimitry Andric   void EmitOMPOrderedDirective(const OMPOrderedDirective &S);
38470b57cec5SDimitry Andric   void EmitOMPAtomicDirective(const OMPAtomicDirective &S);
38480b57cec5SDimitry Andric   void EmitOMPTargetDirective(const OMPTargetDirective &S);
38490b57cec5SDimitry Andric   void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S);
38500b57cec5SDimitry Andric   void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S);
38510b57cec5SDimitry Andric   void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S);
38520b57cec5SDimitry Andric   void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S);
38530b57cec5SDimitry Andric   void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S);
38540b57cec5SDimitry Andric   void
38550b57cec5SDimitry Andric   EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S);
38560b57cec5SDimitry Andric   void EmitOMPTeamsDirective(const OMPTeamsDirective &S);
38570b57cec5SDimitry Andric   void
38580b57cec5SDimitry Andric   EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S);
38590b57cec5SDimitry Andric   void EmitOMPCancelDirective(const OMPCancelDirective &S);
38600b57cec5SDimitry Andric   void EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S);
38610b57cec5SDimitry Andric   void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S);
38620b57cec5SDimitry Andric   void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S);
3863a7dea167SDimitry Andric   void EmitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &S);
3864a7dea167SDimitry Andric   void
3865a7dea167SDimitry Andric   EmitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective &S);
3866a7dea167SDimitry Andric   void EmitOMPParallelMasterTaskLoopDirective(
3867a7dea167SDimitry Andric       const OMPParallelMasterTaskLoopDirective &S);
3868480093f4SDimitry Andric   void EmitOMPParallelMasterTaskLoopSimdDirective(
3869480093f4SDimitry Andric       const OMPParallelMasterTaskLoopSimdDirective &S);
38700b57cec5SDimitry Andric   void EmitOMPDistributeDirective(const OMPDistributeDirective &S);
38710b57cec5SDimitry Andric   void EmitOMPDistributeParallelForDirective(
38720b57cec5SDimitry Andric       const OMPDistributeParallelForDirective &S);
38730b57cec5SDimitry Andric   void EmitOMPDistributeParallelForSimdDirective(
38740b57cec5SDimitry Andric       const OMPDistributeParallelForSimdDirective &S);
38750b57cec5SDimitry Andric   void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S);
38760b57cec5SDimitry Andric   void EmitOMPTargetParallelForSimdDirective(
38770b57cec5SDimitry Andric       const OMPTargetParallelForSimdDirective &S);
38780b57cec5SDimitry Andric   void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S);
38790b57cec5SDimitry Andric   void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S);
38800b57cec5SDimitry Andric   void
38810b57cec5SDimitry Andric   EmitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &S);
38820b57cec5SDimitry Andric   void EmitOMPTeamsDistributeParallelForSimdDirective(
38830b57cec5SDimitry Andric       const OMPTeamsDistributeParallelForSimdDirective &S);
38840b57cec5SDimitry Andric   void EmitOMPTeamsDistributeParallelForDirective(
38850b57cec5SDimitry Andric       const OMPTeamsDistributeParallelForDirective &S);
38860b57cec5SDimitry Andric   void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S);
38870b57cec5SDimitry Andric   void EmitOMPTargetTeamsDistributeDirective(
38880b57cec5SDimitry Andric       const OMPTargetTeamsDistributeDirective &S);
38890b57cec5SDimitry Andric   void EmitOMPTargetTeamsDistributeParallelForDirective(
38900b57cec5SDimitry Andric       const OMPTargetTeamsDistributeParallelForDirective &S);
38910b57cec5SDimitry Andric   void EmitOMPTargetTeamsDistributeParallelForSimdDirective(
38920b57cec5SDimitry Andric       const OMPTargetTeamsDistributeParallelForSimdDirective &S);
38930b57cec5SDimitry Andric   void EmitOMPTargetTeamsDistributeSimdDirective(
38940b57cec5SDimitry Andric       const OMPTargetTeamsDistributeSimdDirective &S);
3895349cc55cSDimitry Andric   void EmitOMPGenericLoopDirective(const OMPGenericLoopDirective &S);
389606c3fb27SDimitry Andric   void EmitOMPParallelGenericLoopDirective(const OMPLoopDirective &S);
389706c3fb27SDimitry Andric   void EmitOMPTargetParallelGenericLoopDirective(
389806c3fb27SDimitry Andric       const OMPTargetParallelGenericLoopDirective &S);
389906c3fb27SDimitry Andric   void EmitOMPTargetTeamsGenericLoopDirective(
390006c3fb27SDimitry Andric       const OMPTargetTeamsGenericLoopDirective &S);
390106c3fb27SDimitry Andric   void EmitOMPTeamsGenericLoopDirective(const OMPTeamsGenericLoopDirective &S);
39021fd87a68SDimitry Andric   void EmitOMPInteropDirective(const OMPInteropDirective &S);
390306c3fb27SDimitry Andric   void EmitOMPParallelMaskedDirective(const OMPParallelMaskedDirective &S);
39040b57cec5SDimitry Andric 
39050b57cec5SDimitry Andric   /// Emit device code for the target directive.
39060b57cec5SDimitry Andric   static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
39070b57cec5SDimitry Andric                                           StringRef ParentName,
39080b57cec5SDimitry Andric                                           const OMPTargetDirective &S);
39090b57cec5SDimitry Andric   static void
39100b57cec5SDimitry Andric   EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName,
39110b57cec5SDimitry Andric                                       const OMPTargetParallelDirective &S);
39120b57cec5SDimitry Andric   /// Emit device code for the target parallel for directive.
39130b57cec5SDimitry Andric   static void EmitOMPTargetParallelForDeviceFunction(
39140b57cec5SDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
39150b57cec5SDimitry Andric       const OMPTargetParallelForDirective &S);
39160b57cec5SDimitry Andric   /// Emit device code for the target parallel for simd directive.
39170b57cec5SDimitry Andric   static void EmitOMPTargetParallelForSimdDeviceFunction(
39180b57cec5SDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
39190b57cec5SDimitry Andric       const OMPTargetParallelForSimdDirective &S);
39200b57cec5SDimitry Andric   /// Emit device code for the target teams directive.
39210b57cec5SDimitry Andric   static void
39220b57cec5SDimitry Andric   EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName,
39230b57cec5SDimitry Andric                                    const OMPTargetTeamsDirective &S);
39240b57cec5SDimitry Andric   /// Emit device code for the target teams distribute directive.
39250b57cec5SDimitry Andric   static void EmitOMPTargetTeamsDistributeDeviceFunction(
39260b57cec5SDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
39270b57cec5SDimitry Andric       const OMPTargetTeamsDistributeDirective &S);
39280b57cec5SDimitry Andric   /// Emit device code for the target teams distribute simd directive.
39290b57cec5SDimitry Andric   static void EmitOMPTargetTeamsDistributeSimdDeviceFunction(
39300b57cec5SDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
39310b57cec5SDimitry Andric       const OMPTargetTeamsDistributeSimdDirective &S);
39320b57cec5SDimitry Andric   /// Emit device code for the target simd directive.
39330b57cec5SDimitry Andric   static void EmitOMPTargetSimdDeviceFunction(CodeGenModule &CGM,
39340b57cec5SDimitry Andric                                               StringRef ParentName,
39350b57cec5SDimitry Andric                                               const OMPTargetSimdDirective &S);
39360b57cec5SDimitry Andric   /// Emit device code for the target teams distribute parallel for simd
39370b57cec5SDimitry Andric   /// directive.
39380b57cec5SDimitry Andric   static void EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(
39390b57cec5SDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
39400b57cec5SDimitry Andric       const OMPTargetTeamsDistributeParallelForSimdDirective &S);
39410b57cec5SDimitry Andric 
394206c3fb27SDimitry Andric   /// Emit device code for the target teams loop directive.
394306c3fb27SDimitry Andric   static void EmitOMPTargetTeamsGenericLoopDeviceFunction(
394406c3fb27SDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
394506c3fb27SDimitry Andric       const OMPTargetTeamsGenericLoopDirective &S);
394606c3fb27SDimitry Andric 
394706c3fb27SDimitry Andric   /// Emit device code for the target parallel loop directive.
394806c3fb27SDimitry Andric   static void EmitOMPTargetParallelGenericLoopDeviceFunction(
394906c3fb27SDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
395006c3fb27SDimitry Andric       const OMPTargetParallelGenericLoopDirective &S);
395106c3fb27SDimitry Andric 
39520b57cec5SDimitry Andric   static void EmitOMPTargetTeamsDistributeParallelForDeviceFunction(
39530b57cec5SDimitry Andric       CodeGenModule &CGM, StringRef ParentName,
39540b57cec5SDimitry Andric       const OMPTargetTeamsDistributeParallelForDirective &S);
3955fe6060f1SDimitry Andric 
3956fe6060f1SDimitry Andric   /// Emit the Stmt \p S and return its topmost canonical loop, if any.
3957fe6060f1SDimitry Andric   /// TODO: The \p Depth paramter is not yet implemented and must be 1. In the
3958fe6060f1SDimitry Andric   /// future it is meant to be the number of loops expected in the loop nests
3959fe6060f1SDimitry Andric   /// (usually specified by the "collapse" clause) that are collapsed to a
3960fe6060f1SDimitry Andric   /// single loop by this function.
3961fe6060f1SDimitry Andric   llvm::CanonicalLoopInfo *EmitOMPCollapsedCanonicalLoopNest(const Stmt *S,
3962fe6060f1SDimitry Andric                                                              int Depth);
3963fe6060f1SDimitry Andric 
3964fe6060f1SDimitry Andric   /// Emit an OMPCanonicalLoop using the OpenMPIRBuilder.
3965fe6060f1SDimitry Andric   void EmitOMPCanonicalLoop(const OMPCanonicalLoop *S);
3966fe6060f1SDimitry Andric 
39670b57cec5SDimitry Andric   /// Emit inner loop of the worksharing/simd construct.
39680b57cec5SDimitry Andric   ///
39690b57cec5SDimitry Andric   /// \param S Directive, for which the inner loop must be emitted.
39700b57cec5SDimitry Andric   /// \param RequiresCleanup true, if directive has some associated private
39710b57cec5SDimitry Andric   /// variables.
39720b57cec5SDimitry Andric   /// \param LoopCond Bollean condition for loop continuation.
39730b57cec5SDimitry Andric   /// \param IncExpr Increment expression for loop control variable.
39740b57cec5SDimitry Andric   /// \param BodyGen Generator for the inner body of the inner loop.
39750b57cec5SDimitry Andric   /// \param PostIncGen Genrator for post-increment code (required for ordered
39760b57cec5SDimitry Andric   /// loop directvies).
39770b57cec5SDimitry Andric   void EmitOMPInnerLoop(
39785ffd83dbSDimitry Andric       const OMPExecutableDirective &S, bool RequiresCleanup,
39795ffd83dbSDimitry Andric       const Expr *LoopCond, const Expr *IncExpr,
39800b57cec5SDimitry Andric       const llvm::function_ref<void(CodeGenFunction &)> BodyGen,
39810b57cec5SDimitry Andric       const llvm::function_ref<void(CodeGenFunction &)> PostIncGen);
39820b57cec5SDimitry Andric 
39830b57cec5SDimitry Andric   JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind);
39840b57cec5SDimitry Andric   /// Emit initial code for loop counters of loop-based directives.
39850b57cec5SDimitry Andric   void EmitOMPPrivateLoopCounters(const OMPLoopDirective &S,
39860b57cec5SDimitry Andric                                   OMPPrivateScope &LoopScope);
39870b57cec5SDimitry Andric 
39880b57cec5SDimitry Andric   /// Helper for the OpenMP loop directives.
39890b57cec5SDimitry Andric   void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit);
39900b57cec5SDimitry Andric 
39910b57cec5SDimitry Andric   /// Emit code for the worksharing loop-based directive.
39920b57cec5SDimitry Andric   /// \return true, if this construct has any lastprivate clause, false -
39930b57cec5SDimitry Andric   /// otherwise.
39940b57cec5SDimitry Andric   bool EmitOMPWorksharingLoop(const OMPLoopDirective &S, Expr *EUB,
39950b57cec5SDimitry Andric                               const CodeGenLoopBoundsTy &CodeGenLoopBounds,
39960b57cec5SDimitry Andric                               const CodeGenDispatchBoundsTy &CGDispatchBounds);
39970b57cec5SDimitry Andric 
39980b57cec5SDimitry Andric   /// Emit code for the distribute loop-based directive.
39990b57cec5SDimitry Andric   void EmitOMPDistributeLoop(const OMPLoopDirective &S,
40000b57cec5SDimitry Andric                              const CodeGenLoopTy &CodeGenLoop, Expr *IncExpr);
40010b57cec5SDimitry Andric 
40020b57cec5SDimitry Andric   /// Helpers for the OpenMP loop directives.
4003fe6060f1SDimitry Andric   void EmitOMPSimdInit(const OMPLoopDirective &D);
40040b57cec5SDimitry Andric   void EmitOMPSimdFinal(
40050b57cec5SDimitry Andric       const OMPLoopDirective &D,
40060b57cec5SDimitry Andric       const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen);
40070b57cec5SDimitry Andric 
40080b57cec5SDimitry Andric   /// Emits the lvalue for the expression with possibly captured variable.
40090b57cec5SDimitry Andric   LValue EmitOMPSharedLValue(const Expr *E);
40100b57cec5SDimitry Andric 
40110b57cec5SDimitry Andric private:
40120b57cec5SDimitry Andric   /// Helpers for blocks.
40130b57cec5SDimitry Andric   llvm::Value *EmitBlockLiteral(const CGBlockInfo &Info);
40140b57cec5SDimitry Andric 
40150b57cec5SDimitry Andric   /// struct with the values to be passed to the OpenMP loop-related functions
40160b57cec5SDimitry Andric   struct OMPLoopArguments {
40170b57cec5SDimitry Andric     /// loop lower bound
40180b57cec5SDimitry Andric     Address LB = Address::invalid();
40190b57cec5SDimitry Andric     /// loop upper bound
40200b57cec5SDimitry Andric     Address UB = Address::invalid();
40210b57cec5SDimitry Andric     /// loop stride
40220b57cec5SDimitry Andric     Address ST = Address::invalid();
40230b57cec5SDimitry Andric     /// isLastIteration argument for runtime functions
40240b57cec5SDimitry Andric     Address IL = Address::invalid();
40250b57cec5SDimitry Andric     /// Chunk value generated by sema
40260b57cec5SDimitry Andric     llvm::Value *Chunk = nullptr;
40270b57cec5SDimitry Andric     /// EnsureUpperBound
40280b57cec5SDimitry Andric     Expr *EUB = nullptr;
40290b57cec5SDimitry Andric     /// IncrementExpression
40300b57cec5SDimitry Andric     Expr *IncExpr = nullptr;
40310b57cec5SDimitry Andric     /// Loop initialization
40320b57cec5SDimitry Andric     Expr *Init = nullptr;
40330b57cec5SDimitry Andric     /// Loop exit condition
40340b57cec5SDimitry Andric     Expr *Cond = nullptr;
40350b57cec5SDimitry Andric     /// Update of LB after a whole chunk has been executed
40360b57cec5SDimitry Andric     Expr *NextLB = nullptr;
40370b57cec5SDimitry Andric     /// Update of UB after a whole chunk has been executed
40380b57cec5SDimitry Andric     Expr *NextUB = nullptr;
40390fca6ea1SDimitry Andric     /// Distinguish between the for distribute and sections
40400fca6ea1SDimitry Andric     OpenMPDirectiveKind DKind = llvm::omp::OMPD_unknown;
40410b57cec5SDimitry Andric     OMPLoopArguments() = default;
40420b57cec5SDimitry Andric     OMPLoopArguments(Address LB, Address UB, Address ST, Address IL,
40430b57cec5SDimitry Andric                      llvm::Value *Chunk = nullptr, Expr *EUB = nullptr,
40440b57cec5SDimitry Andric                      Expr *IncExpr = nullptr, Expr *Init = nullptr,
40450b57cec5SDimitry Andric                      Expr *Cond = nullptr, Expr *NextLB = nullptr,
40460b57cec5SDimitry Andric                      Expr *NextUB = nullptr)
40470b57cec5SDimitry Andric         : LB(LB), UB(UB), ST(ST), IL(IL), Chunk(Chunk), EUB(EUB),
40480b57cec5SDimitry Andric           IncExpr(IncExpr), Init(Init), Cond(Cond), NextLB(NextLB),
40490b57cec5SDimitry Andric           NextUB(NextUB) {}
40500b57cec5SDimitry Andric   };
40510b57cec5SDimitry Andric   void EmitOMPOuterLoop(bool DynamicOrOrdered, bool IsMonotonic,
40520b57cec5SDimitry Andric                         const OMPLoopDirective &S, OMPPrivateScope &LoopScope,
40530b57cec5SDimitry Andric                         const OMPLoopArguments &LoopArgs,
40540b57cec5SDimitry Andric                         const CodeGenLoopTy &CodeGenLoop,
40550b57cec5SDimitry Andric                         const CodeGenOrderedTy &CodeGenOrdered);
40560b57cec5SDimitry Andric   void EmitOMPForOuterLoop(const OpenMPScheduleTy &ScheduleKind,
40570b57cec5SDimitry Andric                            bool IsMonotonic, const OMPLoopDirective &S,
40580b57cec5SDimitry Andric                            OMPPrivateScope &LoopScope, bool Ordered,
40590b57cec5SDimitry Andric                            const OMPLoopArguments &LoopArgs,
40600b57cec5SDimitry Andric                            const CodeGenDispatchBoundsTy &CGDispatchBounds);
40610b57cec5SDimitry Andric   void EmitOMPDistributeOuterLoop(OpenMPDistScheduleClauseKind ScheduleKind,
40620b57cec5SDimitry Andric                                   const OMPLoopDirective &S,
40630b57cec5SDimitry Andric                                   OMPPrivateScope &LoopScope,
40640b57cec5SDimitry Andric                                   const OMPLoopArguments &LoopArgs,
40650b57cec5SDimitry Andric                                   const CodeGenLoopTy &CodeGenLoopContent);
40660b57cec5SDimitry Andric   /// Emit code for sections directive.
40670b57cec5SDimitry Andric   void EmitSections(const OMPExecutableDirective &S);
40680b57cec5SDimitry Andric 
40690b57cec5SDimitry Andric public:
40700fca6ea1SDimitry Andric   //===--------------------------------------------------------------------===//
40710fca6ea1SDimitry Andric   //                         OpenACC Emission
40720fca6ea1SDimitry Andric   //===--------------------------------------------------------------------===//
40730fca6ea1SDimitry Andric   void EmitOpenACCComputeConstruct(const OpenACCComputeConstruct &S) {
40740fca6ea1SDimitry Andric     // TODO OpenACC: Implement this.  It is currently implemented as a 'no-op',
40750fca6ea1SDimitry Andric     // simply emitting its structured block, but in the future we will implement
40760fca6ea1SDimitry Andric     // some sort of IR.
40770fca6ea1SDimitry Andric     EmitStmt(S.getStructuredBlock());
40780fca6ea1SDimitry Andric   }
40790fca6ea1SDimitry Andric 
40800fca6ea1SDimitry Andric   void EmitOpenACCLoopConstruct(const OpenACCLoopConstruct &S) {
40810fca6ea1SDimitry Andric     // TODO OpenACC: Implement this.  It is currently implemented as a 'no-op',
40820fca6ea1SDimitry Andric     // simply emitting its loop, but in the future we will implement
40830fca6ea1SDimitry Andric     // some sort of IR.
40840fca6ea1SDimitry Andric     EmitStmt(S.getLoop());
40850fca6ea1SDimitry Andric   }
40860b57cec5SDimitry Andric 
40870b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
40880b57cec5SDimitry Andric   //                         LValue Expression Emission
40890b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
40900b57cec5SDimitry Andric 
4091e8d8bef9SDimitry Andric   /// Create a check that a scalar RValue is non-null.
4092e8d8bef9SDimitry Andric   llvm::Value *EmitNonNullRValueCheck(RValue RV, QualType T);
4093e8d8bef9SDimitry Andric 
40940b57cec5SDimitry Andric   /// GetUndefRValue - Get an appropriate 'undef' rvalue for the given type.
40950b57cec5SDimitry Andric   RValue GetUndefRValue(QualType Ty);
40960b57cec5SDimitry Andric 
40970b57cec5SDimitry Andric   /// EmitUnsupportedRValue - Emit a dummy r-value using the type of E
40980b57cec5SDimitry Andric   /// and issue an ErrorUnsupported style diagnostic (using the
40990b57cec5SDimitry Andric   /// provided Name).
41000b57cec5SDimitry Andric   RValue EmitUnsupportedRValue(const Expr *E,
41010b57cec5SDimitry Andric                                const char *Name);
41020b57cec5SDimitry Andric 
41030b57cec5SDimitry Andric   /// EmitUnsupportedLValue - Emit a dummy l-value using the type of E and issue
41040b57cec5SDimitry Andric   /// an ErrorUnsupported style diagnostic (using the provided Name).
41050b57cec5SDimitry Andric   LValue EmitUnsupportedLValue(const Expr *E,
41060b57cec5SDimitry Andric                                const char *Name);
41070b57cec5SDimitry Andric 
41080b57cec5SDimitry Andric   /// EmitLValue - Emit code to compute a designator that specifies the location
41090b57cec5SDimitry Andric   /// of the expression.
41100b57cec5SDimitry Andric   ///
41110b57cec5SDimitry Andric   /// This can return one of two things: a simple address or a bitfield
41120b57cec5SDimitry Andric   /// reference.  In either case, the LLVM Value* in the LValue structure is
41130b57cec5SDimitry Andric   /// guaranteed to be an LLVM pointer type.
41140b57cec5SDimitry Andric   ///
41150b57cec5SDimitry Andric   /// If this returns a bitfield reference, nothing about the pointee type of
41160b57cec5SDimitry Andric   /// the LLVM value is known: For example, it may not be a pointer to an
41170b57cec5SDimitry Andric   /// integer.
41180b57cec5SDimitry Andric   ///
41190b57cec5SDimitry Andric   /// If this returns a normal address, and if the lvalue's C type is fixed
41200b57cec5SDimitry Andric   /// size, this method guarantees that the returned pointer type will point to
41210b57cec5SDimitry Andric   /// an LLVM type of the same size of the lvalue's type.  If the lvalue has a
41220b57cec5SDimitry Andric   /// variable length type, this is not possible.
41230b57cec5SDimitry Andric   ///
412406c3fb27SDimitry Andric   LValue EmitLValue(const Expr *E,
412506c3fb27SDimitry Andric                     KnownNonNull_t IsKnownNonNull = NotKnownNonNull);
41260b57cec5SDimitry Andric 
412706c3fb27SDimitry Andric private:
412806c3fb27SDimitry Andric   LValue EmitLValueHelper(const Expr *E, KnownNonNull_t IsKnownNonNull);
412906c3fb27SDimitry Andric 
413006c3fb27SDimitry Andric public:
41310b57cec5SDimitry Andric   /// Same as EmitLValue but additionally we generate checking code to
41320b57cec5SDimitry Andric   /// guard against undefined behavior.  This is only suitable when we know
41330b57cec5SDimitry Andric   /// that the address will be used to access the object.
41340b57cec5SDimitry Andric   LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK);
41350b57cec5SDimitry Andric 
41360b57cec5SDimitry Andric   RValue convertTempToRValue(Address addr, QualType type,
41370b57cec5SDimitry Andric                              SourceLocation Loc);
41380b57cec5SDimitry Andric 
41390b57cec5SDimitry Andric   void EmitAtomicInit(Expr *E, LValue lvalue);
41400b57cec5SDimitry Andric 
41410b57cec5SDimitry Andric   bool LValueIsSuitableForInlineAtomic(LValue Src);
41420b57cec5SDimitry Andric 
41430b57cec5SDimitry Andric   RValue EmitAtomicLoad(LValue LV, SourceLocation SL,
41440b57cec5SDimitry Andric                         AggValueSlot Slot = AggValueSlot::ignored());
41450b57cec5SDimitry Andric 
41460b57cec5SDimitry Andric   RValue EmitAtomicLoad(LValue lvalue, SourceLocation loc,
41470b57cec5SDimitry Andric                         llvm::AtomicOrdering AO, bool IsVolatile = false,
41480b57cec5SDimitry Andric                         AggValueSlot slot = AggValueSlot::ignored());
41490b57cec5SDimitry Andric 
41500b57cec5SDimitry Andric   void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit);
41510b57cec5SDimitry Andric 
41520b57cec5SDimitry Andric   void EmitAtomicStore(RValue rvalue, LValue lvalue, llvm::AtomicOrdering AO,
41530b57cec5SDimitry Andric                        bool IsVolatile, bool isInit);
41540b57cec5SDimitry Andric 
41550b57cec5SDimitry Andric   std::pair<RValue, llvm::Value *> EmitAtomicCompareExchange(
41560b57cec5SDimitry Andric       LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc,
41570b57cec5SDimitry Andric       llvm::AtomicOrdering Success =
41580b57cec5SDimitry Andric           llvm::AtomicOrdering::SequentiallyConsistent,
41590b57cec5SDimitry Andric       llvm::AtomicOrdering Failure =
41600b57cec5SDimitry Andric           llvm::AtomicOrdering::SequentiallyConsistent,
41610b57cec5SDimitry Andric       bool IsWeak = false, AggValueSlot Slot = AggValueSlot::ignored());
41620b57cec5SDimitry Andric 
41630b57cec5SDimitry Andric   void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO,
41640b57cec5SDimitry Andric                         const llvm::function_ref<RValue(RValue)> &UpdateOp,
41650b57cec5SDimitry Andric                         bool IsVolatile);
41660b57cec5SDimitry Andric 
41670b57cec5SDimitry Andric   /// EmitToMemory - Change a scalar value from its value
41680b57cec5SDimitry Andric   /// representation to its in-memory representation.
41690b57cec5SDimitry Andric   llvm::Value *EmitToMemory(llvm::Value *Value, QualType Ty);
41700b57cec5SDimitry Andric 
41710b57cec5SDimitry Andric   /// EmitFromMemory - Change a scalar value from its memory
41720b57cec5SDimitry Andric   /// representation to its value representation.
41730b57cec5SDimitry Andric   llvm::Value *EmitFromMemory(llvm::Value *Value, QualType Ty);
41740b57cec5SDimitry Andric 
41750b57cec5SDimitry Andric   /// Check if the scalar \p Value is within the valid range for the given
41760b57cec5SDimitry Andric   /// type \p Ty.
41770b57cec5SDimitry Andric   ///
41780b57cec5SDimitry Andric   /// Returns true if a check is needed (even if the range is unknown).
41790b57cec5SDimitry Andric   bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
41800b57cec5SDimitry Andric                             SourceLocation Loc);
41810b57cec5SDimitry Andric 
41820b57cec5SDimitry Andric   /// EmitLoadOfScalar - Load a scalar value from an address, taking
41830b57cec5SDimitry Andric   /// care to appropriately convert from the memory representation to
41840b57cec5SDimitry Andric   /// the LLVM value representation.
41850b57cec5SDimitry Andric   llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty,
41860b57cec5SDimitry Andric                                 SourceLocation Loc,
41870b57cec5SDimitry Andric                                 AlignmentSource Source = AlignmentSource::Type,
41880b57cec5SDimitry Andric                                 bool isNontemporal = false) {
41890b57cec5SDimitry Andric     return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, LValueBaseInfo(Source),
41900b57cec5SDimitry Andric                             CGM.getTBAAAccessInfo(Ty), isNontemporal);
41910b57cec5SDimitry Andric   }
41920b57cec5SDimitry Andric 
41930b57cec5SDimitry Andric   llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty,
41940b57cec5SDimitry Andric                                 SourceLocation Loc, LValueBaseInfo BaseInfo,
41950b57cec5SDimitry Andric                                 TBAAAccessInfo TBAAInfo,
41960b57cec5SDimitry Andric                                 bool isNontemporal = false);
41970b57cec5SDimitry Andric 
41980b57cec5SDimitry Andric   /// EmitLoadOfScalar - Load a scalar value from an address, taking
41990b57cec5SDimitry Andric   /// care to appropriately convert from the memory representation to
42000b57cec5SDimitry Andric   /// the LLVM value representation.  The l-value must be a simple
42010b57cec5SDimitry Andric   /// l-value.
42020b57cec5SDimitry Andric   llvm::Value *EmitLoadOfScalar(LValue lvalue, SourceLocation Loc);
42030b57cec5SDimitry Andric 
42040b57cec5SDimitry Andric   /// EmitStoreOfScalar - Store a scalar value to an address, taking
42050b57cec5SDimitry Andric   /// care to appropriately convert from the memory representation to
42060b57cec5SDimitry Andric   /// the LLVM value representation.
42070b57cec5SDimitry Andric   void EmitStoreOfScalar(llvm::Value *Value, Address Addr,
42080b57cec5SDimitry Andric                          bool Volatile, QualType Ty,
42090b57cec5SDimitry Andric                          AlignmentSource Source = AlignmentSource::Type,
42100b57cec5SDimitry Andric                          bool isInit = false, bool isNontemporal = false) {
42110b57cec5SDimitry Andric     EmitStoreOfScalar(Value, Addr, Volatile, Ty, LValueBaseInfo(Source),
42120b57cec5SDimitry Andric                       CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal);
42130b57cec5SDimitry Andric   }
42140b57cec5SDimitry Andric 
42150b57cec5SDimitry Andric   void EmitStoreOfScalar(llvm::Value *Value, Address Addr,
42160b57cec5SDimitry Andric                          bool Volatile, QualType Ty,
42170b57cec5SDimitry Andric                          LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo,
42180b57cec5SDimitry Andric                          bool isInit = false, bool isNontemporal = false);
42190b57cec5SDimitry Andric 
42200b57cec5SDimitry Andric   /// EmitStoreOfScalar - Store a scalar value to an address, taking
42210b57cec5SDimitry Andric   /// care to appropriately convert from the memory representation to
42220b57cec5SDimitry Andric   /// the LLVM value representation.  The l-value must be a simple
42230b57cec5SDimitry Andric   /// l-value.  The isInit flag indicates whether this is an initialization.
42240b57cec5SDimitry Andric   /// If so, atomic qualifiers are ignored and the store is always non-atomic.
42250b57cec5SDimitry Andric   void EmitStoreOfScalar(llvm::Value *value, LValue lvalue, bool isInit=false);
42260b57cec5SDimitry Andric 
42270b57cec5SDimitry Andric   /// EmitLoadOfLValue - Given an expression that represents a value lvalue,
42280b57cec5SDimitry Andric   /// this method emits the address of the lvalue, then loads the result as an
42290b57cec5SDimitry Andric   /// rvalue, returning the rvalue.
42300b57cec5SDimitry Andric   RValue EmitLoadOfLValue(LValue V, SourceLocation Loc);
42310b57cec5SDimitry Andric   RValue EmitLoadOfExtVectorElementLValue(LValue V);
42320b57cec5SDimitry Andric   RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc);
42330b57cec5SDimitry Andric   RValue EmitLoadOfGlobalRegLValue(LValue LV);
42340b57cec5SDimitry Andric 
42350fca6ea1SDimitry Andric   /// Like EmitLoadOfLValue but also handles complex and aggregate types.
42360fca6ea1SDimitry Andric   RValue EmitLoadOfAnyValue(LValue V,
42370fca6ea1SDimitry Andric                             AggValueSlot Slot = AggValueSlot::ignored(),
42380fca6ea1SDimitry Andric                             SourceLocation Loc = {});
42390fca6ea1SDimitry Andric 
42400b57cec5SDimitry Andric   /// EmitStoreThroughLValue - Store the specified rvalue into the specified
42410b57cec5SDimitry Andric   /// lvalue, where both are guaranteed to the have the same type, and that type
42420b57cec5SDimitry Andric   /// is 'Ty'.
42430b57cec5SDimitry Andric   void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit = false);
42440b57cec5SDimitry Andric   void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst);
42450b57cec5SDimitry Andric   void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst);
42460b57cec5SDimitry Andric 
42470b57cec5SDimitry Andric   /// EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints
42480b57cec5SDimitry Andric   /// as EmitStoreThroughLValue.
42490b57cec5SDimitry Andric   ///
42500b57cec5SDimitry Andric   /// \param Result [out] - If non-null, this will be set to a Value* for the
42510b57cec5SDimitry Andric   /// bit-field contents after the store, appropriate for use as the result of
42520b57cec5SDimitry Andric   /// an assignment to the bit-field.
42530b57cec5SDimitry Andric   void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
42540b57cec5SDimitry Andric                                       llvm::Value **Result=nullptr);
42550b57cec5SDimitry Andric 
42560b57cec5SDimitry Andric   /// Emit an l-value for an assignment (simple or compound) of complex type.
42570b57cec5SDimitry Andric   LValue EmitComplexAssignmentLValue(const BinaryOperator *E);
42580b57cec5SDimitry Andric   LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E);
42590b57cec5SDimitry Andric   LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E,
42600b57cec5SDimitry Andric                                              llvm::Value *&Result);
42610b57cec5SDimitry Andric 
42620b57cec5SDimitry Andric   // Note: only available for agg return types
42630b57cec5SDimitry Andric   LValue EmitBinaryOperatorLValue(const BinaryOperator *E);
42640b57cec5SDimitry Andric   LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E);
42650b57cec5SDimitry Andric   // Note: only available for agg return types
42660b57cec5SDimitry Andric   LValue EmitCallExprLValue(const CallExpr *E);
42670b57cec5SDimitry Andric   // Note: only available for agg return types
42680b57cec5SDimitry Andric   LValue EmitVAArgExprLValue(const VAArgExpr *E);
42690b57cec5SDimitry Andric   LValue EmitDeclRefLValue(const DeclRefExpr *E);
42700b57cec5SDimitry Andric   LValue EmitStringLiteralLValue(const StringLiteral *E);
42710b57cec5SDimitry Andric   LValue EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E);
42720b57cec5SDimitry Andric   LValue EmitPredefinedLValue(const PredefinedExpr *E);
42730b57cec5SDimitry Andric   LValue EmitUnaryOpLValue(const UnaryOperator *E);
42740b57cec5SDimitry Andric   LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
42750b57cec5SDimitry Andric                                 bool Accessed = false);
42765ffd83dbSDimitry Andric   LValue EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E);
42770fca6ea1SDimitry Andric   LValue EmitArraySectionExpr(const ArraySectionExpr *E,
42780b57cec5SDimitry Andric                               bool IsLowerBound = true);
42790b57cec5SDimitry Andric   LValue EmitExtVectorElementExpr(const ExtVectorElementExpr *E);
42800b57cec5SDimitry Andric   LValue EmitMemberExpr(const MemberExpr *E);
42810b57cec5SDimitry Andric   LValue EmitObjCIsaExpr(const ObjCIsaExpr *E);
42820b57cec5SDimitry Andric   LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E);
42830b57cec5SDimitry Andric   LValue EmitInitListLValue(const InitListExpr *E);
428481ad6265SDimitry Andric   void EmitIgnoredConditionalOperator(const AbstractConditionalOperator *E);
42850b57cec5SDimitry Andric   LValue EmitConditionalOperatorLValue(const AbstractConditionalOperator *E);
42860b57cec5SDimitry Andric   LValue EmitCastLValue(const CastExpr *E);
42870b57cec5SDimitry Andric   LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
42880b57cec5SDimitry Andric   LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e);
42890b57cec5SDimitry Andric 
42900b57cec5SDimitry Andric   Address EmitExtVectorElementLValue(LValue V);
42910b57cec5SDimitry Andric 
42920b57cec5SDimitry Andric   RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc);
42930b57cec5SDimitry Andric 
42940b57cec5SDimitry Andric   Address EmitArrayToPointerDecay(const Expr *Array,
42950b57cec5SDimitry Andric                                   LValueBaseInfo *BaseInfo = nullptr,
42960b57cec5SDimitry Andric                                   TBAAAccessInfo *TBAAInfo = nullptr);
42970b57cec5SDimitry Andric 
42980b57cec5SDimitry Andric   class ConstantEmission {
42990b57cec5SDimitry Andric     llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference;
43000b57cec5SDimitry Andric     ConstantEmission(llvm::Constant *C, bool isReference)
43010b57cec5SDimitry Andric       : ValueAndIsReference(C, isReference) {}
43020b57cec5SDimitry Andric   public:
43030b57cec5SDimitry Andric     ConstantEmission() {}
43040b57cec5SDimitry Andric     static ConstantEmission forReference(llvm::Constant *C) {
43050b57cec5SDimitry Andric       return ConstantEmission(C, true);
43060b57cec5SDimitry Andric     }
43070b57cec5SDimitry Andric     static ConstantEmission forValue(llvm::Constant *C) {
43080b57cec5SDimitry Andric       return ConstantEmission(C, false);
43090b57cec5SDimitry Andric     }
43100b57cec5SDimitry Andric 
43110b57cec5SDimitry Andric     explicit operator bool() const {
43120b57cec5SDimitry Andric       return ValueAndIsReference.getOpaqueValue() != nullptr;
43130b57cec5SDimitry Andric     }
43140b57cec5SDimitry Andric 
43150b57cec5SDimitry Andric     bool isReference() const { return ValueAndIsReference.getInt(); }
43160b57cec5SDimitry Andric     LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const {
43170b57cec5SDimitry Andric       assert(isReference());
43180b57cec5SDimitry Andric       return CGF.MakeNaturalAlignAddrLValue(ValueAndIsReference.getPointer(),
43190b57cec5SDimitry Andric                                             refExpr->getType());
43200b57cec5SDimitry Andric     }
43210b57cec5SDimitry Andric 
43220b57cec5SDimitry Andric     llvm::Constant *getValue() const {
43230b57cec5SDimitry Andric       assert(!isReference());
43240b57cec5SDimitry Andric       return ValueAndIsReference.getPointer();
43250b57cec5SDimitry Andric     }
43260b57cec5SDimitry Andric   };
43270b57cec5SDimitry Andric 
43280b57cec5SDimitry Andric   ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr);
43290b57cec5SDimitry Andric   ConstantEmission tryEmitAsConstant(const MemberExpr *ME);
43300b57cec5SDimitry Andric   llvm::Value *emitScalarConstant(const ConstantEmission &Constant, Expr *E);
43310b57cec5SDimitry Andric 
43320b57cec5SDimitry Andric   RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e,
43330b57cec5SDimitry Andric                                 AggValueSlot slot = AggValueSlot::ignored());
43340b57cec5SDimitry Andric   LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e);
43350b57cec5SDimitry Andric 
43360b57cec5SDimitry Andric   llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
43370b57cec5SDimitry Andric                               const ObjCIvarDecl *Ivar);
4338bdd1243dSDimitry Andric   llvm::Value *EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface,
4339bdd1243dSDimitry Andric                                            const ObjCIvarDecl *Ivar);
43400b57cec5SDimitry Andric   LValue EmitLValueForField(LValue Base, const FieldDecl* Field);
43410b57cec5SDimitry Andric   LValue EmitLValueForLambdaField(const FieldDecl *Field);
43425f757f3fSDimitry Andric   LValue EmitLValueForLambdaField(const FieldDecl *Field,
43435f757f3fSDimitry Andric                                   llvm::Value *ThisValue);
43440b57cec5SDimitry Andric 
43450b57cec5SDimitry Andric   /// EmitLValueForFieldInitialization - Like EmitLValueForField, except that
43460b57cec5SDimitry Andric   /// if the Field is a reference, this will return the address of the reference
43470b57cec5SDimitry Andric   /// and not the address of the value stored in the reference.
43480b57cec5SDimitry Andric   LValue EmitLValueForFieldInitialization(LValue Base,
43490b57cec5SDimitry Andric                                           const FieldDecl* Field);
43500b57cec5SDimitry Andric 
43510b57cec5SDimitry Andric   LValue EmitLValueForIvar(QualType ObjectTy,
43520b57cec5SDimitry Andric                            llvm::Value* Base, const ObjCIvarDecl *Ivar,
43530b57cec5SDimitry Andric                            unsigned CVRQualifiers);
43540b57cec5SDimitry Andric 
43550b57cec5SDimitry Andric   LValue EmitCXXConstructLValue(const CXXConstructExpr *E);
43560b57cec5SDimitry Andric   LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E);
43570b57cec5SDimitry Andric   LValue EmitCXXTypeidLValue(const CXXTypeidExpr *E);
43580b57cec5SDimitry Andric   LValue EmitCXXUuidofLValue(const CXXUuidofExpr *E);
43590b57cec5SDimitry Andric 
43600b57cec5SDimitry Andric   LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E);
43610b57cec5SDimitry Andric   LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E);
43620b57cec5SDimitry Andric   LValue EmitStmtExprLValue(const StmtExpr *E);
43630b57cec5SDimitry Andric   LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E);
43640b57cec5SDimitry Andric   LValue EmitObjCSelectorLValue(const ObjCSelectorExpr *E);
43650b57cec5SDimitry Andric   void   EmitDeclRefExprDbgValue(const DeclRefExpr *E, const APValue &Init);
43660b57cec5SDimitry Andric 
43670b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
43680b57cec5SDimitry Andric   //                         Scalar Expression Emission
43690b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
43700b57cec5SDimitry Andric 
43710b57cec5SDimitry Andric   /// EmitCall - Generate a call of the given function, expecting the given
43720b57cec5SDimitry Andric   /// result type, and using the given argument list which specifies both the
43730b57cec5SDimitry Andric   /// LLVM arguments and the types they were derived from.
43740b57cec5SDimitry Andric   RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee,
43750b57cec5SDimitry Andric                   ReturnValueSlot ReturnValue, const CallArgList &Args,
4376fe6060f1SDimitry Andric                   llvm::CallBase **callOrInvoke, bool IsMustTail,
43770fca6ea1SDimitry Andric                   SourceLocation Loc,
43780fca6ea1SDimitry Andric                   bool IsVirtualFunctionPointerThunk = false);
43790b57cec5SDimitry Andric   RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee,
43800b57cec5SDimitry Andric                   ReturnValueSlot ReturnValue, const CallArgList &Args,
4381fe6060f1SDimitry Andric                   llvm::CallBase **callOrInvoke = nullptr,
4382fe6060f1SDimitry Andric                   bool IsMustTail = false) {
43830b57cec5SDimitry Andric     return EmitCall(CallInfo, Callee, ReturnValue, Args, callOrInvoke,
4384fe6060f1SDimitry Andric                     IsMustTail, SourceLocation());
43850b57cec5SDimitry Andric   }
43860b57cec5SDimitry Andric   RValue EmitCall(QualType FnType, const CGCallee &Callee, const CallExpr *E,
43870b57cec5SDimitry Andric                   ReturnValueSlot ReturnValue, llvm::Value *Chain = nullptr);
43880b57cec5SDimitry Andric   RValue EmitCallExpr(const CallExpr *E,
43890b57cec5SDimitry Andric                       ReturnValueSlot ReturnValue = ReturnValueSlot());
43900b57cec5SDimitry Andric   RValue EmitSimpleCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue);
43910b57cec5SDimitry Andric   CGCallee EmitCallee(const Expr *E);
43920b57cec5SDimitry Andric 
43930b57cec5SDimitry Andric   void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl);
43940b57cec5SDimitry Andric   void checkTargetFeatures(SourceLocation Loc, const FunctionDecl *TargetDecl);
43950b57cec5SDimitry Andric 
43960b57cec5SDimitry Andric   llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee,
43970b57cec5SDimitry Andric                                   const Twine &name = "");
43980b57cec5SDimitry Andric   llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee,
43990b57cec5SDimitry Andric                                   ArrayRef<llvm::Value *> args,
44000b57cec5SDimitry Andric                                   const Twine &name = "");
44010b57cec5SDimitry Andric   llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
44020b57cec5SDimitry Andric                                           const Twine &name = "");
44030b57cec5SDimitry Andric   llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
44040fca6ea1SDimitry Andric                                           ArrayRef<Address> args,
44050fca6ea1SDimitry Andric                                           const Twine &name = "");
44060fca6ea1SDimitry Andric   llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
44070b57cec5SDimitry Andric                                           ArrayRef<llvm::Value *> args,
44080b57cec5SDimitry Andric                                           const Twine &name = "");
44090b57cec5SDimitry Andric 
44100b57cec5SDimitry Andric   SmallVector<llvm::OperandBundleDef, 1>
44110b57cec5SDimitry Andric   getBundlesForFunclet(llvm::Value *Callee);
44120b57cec5SDimitry Andric 
44130b57cec5SDimitry Andric   llvm::CallBase *EmitCallOrInvoke(llvm::FunctionCallee Callee,
44140b57cec5SDimitry Andric                                    ArrayRef<llvm::Value *> Args,
44150b57cec5SDimitry Andric                                    const Twine &Name = "");
44160b57cec5SDimitry Andric   llvm::CallBase *EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
44170b57cec5SDimitry Andric                                           ArrayRef<llvm::Value *> args,
44180b57cec5SDimitry Andric                                           const Twine &name = "");
44190b57cec5SDimitry Andric   llvm::CallBase *EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
44200b57cec5SDimitry Andric                                           const Twine &name = "");
44210b57cec5SDimitry Andric   void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee,
44220b57cec5SDimitry Andric                                        ArrayRef<llvm::Value *> args);
44230b57cec5SDimitry Andric 
44240b57cec5SDimitry Andric   CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
44250b57cec5SDimitry Andric                                      NestedNameSpecifier *Qual,
44260b57cec5SDimitry Andric                                      llvm::Type *Ty);
44270b57cec5SDimitry Andric 
44280b57cec5SDimitry Andric   CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD,
44290b57cec5SDimitry Andric                                                CXXDtorType Type,
44300b57cec5SDimitry Andric                                                const CXXRecordDecl *RD);
44310b57cec5SDimitry Andric 
44320fca6ea1SDimitry Andric   bool isPointerKnownNonNull(const Expr *E);
44330fca6ea1SDimitry Andric 
44340fca6ea1SDimitry Andric   /// Create the discriminator from the storage address and the entity hash.
44350fca6ea1SDimitry Andric   llvm::Value *EmitPointerAuthBlendDiscriminator(llvm::Value *StorageAddress,
44360fca6ea1SDimitry Andric                                                  llvm::Value *Discriminator);
44370fca6ea1SDimitry Andric   CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema,
44380fca6ea1SDimitry Andric                                         llvm::Value *StorageAddress,
44390fca6ea1SDimitry Andric                                         GlobalDecl SchemaDecl,
44400fca6ea1SDimitry Andric                                         QualType SchemaType);
44410fca6ea1SDimitry Andric 
44420fca6ea1SDimitry Andric   llvm::Value *EmitPointerAuthSign(const CGPointerAuthInfo &Info,
44430fca6ea1SDimitry Andric                                    llvm::Value *Pointer);
44440fca6ea1SDimitry Andric 
44450fca6ea1SDimitry Andric   llvm::Value *EmitPointerAuthAuth(const CGPointerAuthInfo &Info,
44460fca6ea1SDimitry Andric                                    llvm::Value *Pointer);
44470fca6ea1SDimitry Andric 
44480fca6ea1SDimitry Andric   llvm::Value *emitPointerAuthResign(llvm::Value *Pointer, QualType PointerType,
44490fca6ea1SDimitry Andric                                      const CGPointerAuthInfo &CurAuthInfo,
44500fca6ea1SDimitry Andric                                      const CGPointerAuthInfo &NewAuthInfo,
44510fca6ea1SDimitry Andric                                      bool IsKnownNonNull);
44520fca6ea1SDimitry Andric   llvm::Value *emitPointerAuthResignCall(llvm::Value *Pointer,
44530fca6ea1SDimitry Andric                                          const CGPointerAuthInfo &CurInfo,
44540fca6ea1SDimitry Andric                                          const CGPointerAuthInfo &NewInfo);
44550fca6ea1SDimitry Andric 
44560fca6ea1SDimitry Andric   void EmitPointerAuthOperandBundle(
44570fca6ea1SDimitry Andric       const CGPointerAuthInfo &Info,
44580fca6ea1SDimitry Andric       SmallVectorImpl<llvm::OperandBundleDef> &Bundles);
44590fca6ea1SDimitry Andric 
44600fca6ea1SDimitry Andric   llvm::Value *authPointerToPointerCast(llvm::Value *ResultPtr,
44610fca6ea1SDimitry Andric                                         QualType SourceType, QualType DestType);
44620fca6ea1SDimitry Andric   Address authPointerToPointerCast(Address Ptr, QualType SourceType,
44630fca6ea1SDimitry Andric                                    QualType DestType);
44640fca6ea1SDimitry Andric 
44650fca6ea1SDimitry Andric   Address getAsNaturalAddressOf(Address Addr, QualType PointeeTy);
44660fca6ea1SDimitry Andric 
44670fca6ea1SDimitry Andric   llvm::Value *getAsNaturalPointerTo(Address Addr, QualType PointeeType) {
44680fca6ea1SDimitry Andric     return getAsNaturalAddressOf(Addr, PointeeType).getBasePointer();
44690fca6ea1SDimitry Andric   }
44700fca6ea1SDimitry Andric 
44710b57cec5SDimitry Andric   // Return the copy constructor name with the prefix "__copy_constructor_"
44720b57cec5SDimitry Andric   // removed.
44730b57cec5SDimitry Andric   static std::string getNonTrivialCopyConstructorStr(QualType QT,
44740b57cec5SDimitry Andric                                                      CharUnits Alignment,
44750b57cec5SDimitry Andric                                                      bool IsVolatile,
44760b57cec5SDimitry Andric                                                      ASTContext &Ctx);
44770b57cec5SDimitry Andric 
44780b57cec5SDimitry Andric   // Return the destructor name with the prefix "__destructor_" removed.
44790b57cec5SDimitry Andric   static std::string getNonTrivialDestructorStr(QualType QT,
44800b57cec5SDimitry Andric                                                 CharUnits Alignment,
44810b57cec5SDimitry Andric                                                 bool IsVolatile,
44820b57cec5SDimitry Andric                                                 ASTContext &Ctx);
44830b57cec5SDimitry Andric 
44840b57cec5SDimitry Andric   // These functions emit calls to the special functions of non-trivial C
44850b57cec5SDimitry Andric   // structs.
44860b57cec5SDimitry Andric   void defaultInitNonTrivialCStructVar(LValue Dst);
44870b57cec5SDimitry Andric   void callCStructDefaultConstructor(LValue Dst);
44880b57cec5SDimitry Andric   void callCStructDestructor(LValue Dst);
44890b57cec5SDimitry Andric   void callCStructCopyConstructor(LValue Dst, LValue Src);
44900b57cec5SDimitry Andric   void callCStructMoveConstructor(LValue Dst, LValue Src);
44910b57cec5SDimitry Andric   void callCStructCopyAssignmentOperator(LValue Dst, LValue Src);
44920b57cec5SDimitry Andric   void callCStructMoveAssignmentOperator(LValue Dst, LValue Src);
44930b57cec5SDimitry Andric 
44940b57cec5SDimitry Andric   RValue
44950b57cec5SDimitry Andric   EmitCXXMemberOrOperatorCall(const CXXMethodDecl *Method,
44960b57cec5SDimitry Andric                               const CGCallee &Callee,
44970b57cec5SDimitry Andric                               ReturnValueSlot ReturnValue, llvm::Value *This,
44980b57cec5SDimitry Andric                               llvm::Value *ImplicitParam,
44990b57cec5SDimitry Andric                               QualType ImplicitParamTy, const CallExpr *E,
45000b57cec5SDimitry Andric                               CallArgList *RtlArgs);
45010b57cec5SDimitry Andric   RValue EmitCXXDestructorCall(GlobalDecl Dtor, const CGCallee &Callee,
45020b57cec5SDimitry Andric                                llvm::Value *This, QualType ThisTy,
45030b57cec5SDimitry Andric                                llvm::Value *ImplicitParam,
45040b57cec5SDimitry Andric                                QualType ImplicitParamTy, const CallExpr *E);
45050b57cec5SDimitry Andric   RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E,
45060b57cec5SDimitry Andric                                ReturnValueSlot ReturnValue);
45070b57cec5SDimitry Andric   RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE,
45080b57cec5SDimitry Andric                                                const CXXMethodDecl *MD,
45090b57cec5SDimitry Andric                                                ReturnValueSlot ReturnValue,
45100b57cec5SDimitry Andric                                                bool HasQualifier,
45110b57cec5SDimitry Andric                                                NestedNameSpecifier *Qualifier,
45120b57cec5SDimitry Andric                                                bool IsArrow, const Expr *Base);
45130b57cec5SDimitry Andric   // Compute the object pointer.
45140b57cec5SDimitry Andric   Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base,
45150b57cec5SDimitry Andric                                           llvm::Value *memberPtr,
45160b57cec5SDimitry Andric                                           const MemberPointerType *memberPtrType,
45170b57cec5SDimitry Andric                                           LValueBaseInfo *BaseInfo = nullptr,
45180b57cec5SDimitry Andric                                           TBAAAccessInfo *TBAAInfo = nullptr);
45190b57cec5SDimitry Andric   RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
45200b57cec5SDimitry Andric                                       ReturnValueSlot ReturnValue);
45210b57cec5SDimitry Andric 
45220b57cec5SDimitry Andric   RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
45230b57cec5SDimitry Andric                                        const CXXMethodDecl *MD,
45240b57cec5SDimitry Andric                                        ReturnValueSlot ReturnValue);
45250b57cec5SDimitry Andric   RValue EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
45260b57cec5SDimitry Andric 
45270b57cec5SDimitry Andric   RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E,
45280b57cec5SDimitry Andric                                 ReturnValueSlot ReturnValue);
45290b57cec5SDimitry Andric 
4530349cc55cSDimitry Andric   RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E);
4531349cc55cSDimitry Andric   RValue EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E);
4532349cc55cSDimitry Andric   RValue EmitOpenMPDevicePrintfCallExpr(const CallExpr *E);
45330b57cec5SDimitry Andric 
45340b57cec5SDimitry Andric   RValue EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
45350b57cec5SDimitry Andric                          const CallExpr *E, ReturnValueSlot ReturnValue);
45360b57cec5SDimitry Andric 
45370b57cec5SDimitry Andric   RValue emitRotate(const CallExpr *E, bool IsRotateRight);
45380b57cec5SDimitry Andric 
45390b57cec5SDimitry Andric   /// Emit IR for __builtin_os_log_format.
45400b57cec5SDimitry Andric   RValue emitBuiltinOSLogFormat(const CallExpr &E);
45410b57cec5SDimitry Andric 
4542480093f4SDimitry Andric   /// Emit IR for __builtin_is_aligned.
4543480093f4SDimitry Andric   RValue EmitBuiltinIsAligned(const CallExpr *E);
4544480093f4SDimitry Andric   /// Emit IR for __builtin_align_up/__builtin_align_down.
4545480093f4SDimitry Andric   RValue EmitBuiltinAlignTo(const CallExpr *E, bool AlignUp);
4546480093f4SDimitry Andric 
45470b57cec5SDimitry Andric   llvm::Function *generateBuiltinOSLogHelperFunction(
45480b57cec5SDimitry Andric       const analyze_os_log::OSLogBufferLayout &Layout,
45490b57cec5SDimitry Andric       CharUnits BufferAlignment);
45500b57cec5SDimitry Andric 
45510b57cec5SDimitry Andric   RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue);
45520b57cec5SDimitry Andric 
45530b57cec5SDimitry Andric   /// EmitTargetBuiltinExpr - Emit the given builtin call. Returns 0 if the call
45540b57cec5SDimitry Andric   /// is unhandled by the current target.
4555480093f4SDimitry Andric   llvm::Value *EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4556480093f4SDimitry Andric                                      ReturnValueSlot ReturnValue);
45570b57cec5SDimitry Andric 
45580b57cec5SDimitry Andric   llvm::Value *EmitAArch64CompareBuiltinExpr(llvm::Value *Op, llvm::Type *Ty,
45590b57cec5SDimitry Andric                                              const llvm::CmpInst::Predicate Fp,
45600b57cec5SDimitry Andric                                              const llvm::CmpInst::Predicate Ip,
45610b57cec5SDimitry Andric                                              const llvm::Twine &Name = "");
45620b57cec5SDimitry Andric   llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4563480093f4SDimitry Andric                                   ReturnValueSlot ReturnValue,
4564480093f4SDimitry Andric                                   llvm::Triple::ArchType Arch);
4565480093f4SDimitry Andric   llvm::Value *EmitARMMVEBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4566480093f4SDimitry Andric                                      ReturnValueSlot ReturnValue,
45670b57cec5SDimitry Andric                                      llvm::Triple::ArchType Arch);
45685ffd83dbSDimitry Andric   llvm::Value *EmitARMCDEBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
45695ffd83dbSDimitry Andric                                      ReturnValueSlot ReturnValue,
45705ffd83dbSDimitry Andric                                      llvm::Triple::ArchType Arch);
45715ffd83dbSDimitry Andric   llvm::Value *EmitCMSEClearRecord(llvm::Value *V, llvm::IntegerType *ITy,
45725ffd83dbSDimitry Andric                                    QualType RTy);
45735ffd83dbSDimitry Andric   llvm::Value *EmitCMSEClearRecord(llvm::Value *V, llvm::ArrayType *ATy,
45745ffd83dbSDimitry Andric                                    QualType RTy);
45750b57cec5SDimitry Andric 
45760b57cec5SDimitry Andric   llvm::Value *EmitCommonNeonBuiltinExpr(unsigned BuiltinID,
45770b57cec5SDimitry Andric                                          unsigned LLVMIntrinsic,
45780b57cec5SDimitry Andric                                          unsigned AltLLVMIntrinsic,
45790b57cec5SDimitry Andric                                          const char *NameHint,
45800b57cec5SDimitry Andric                                          unsigned Modifier,
45810b57cec5SDimitry Andric                                          const CallExpr *E,
45820b57cec5SDimitry Andric                                          SmallVectorImpl<llvm::Value *> &Ops,
45830b57cec5SDimitry Andric                                          Address PtrOp0, Address PtrOp1,
45840b57cec5SDimitry Andric                                          llvm::Triple::ArchType Arch);
45850b57cec5SDimitry Andric 
45860b57cec5SDimitry Andric   llvm::Function *LookupNeonLLVMIntrinsic(unsigned IntrinsicID,
45870b57cec5SDimitry Andric                                           unsigned Modifier, llvm::Type *ArgTy,
45880b57cec5SDimitry Andric                                           const CallExpr *E);
45890b57cec5SDimitry Andric   llvm::Value *EmitNeonCall(llvm::Function *F,
45900b57cec5SDimitry Andric                             SmallVectorImpl<llvm::Value*> &O,
45910b57cec5SDimitry Andric                             const char *name,
45920b57cec5SDimitry Andric                             unsigned shift = 0, bool rightshift = false);
45935ffd83dbSDimitry Andric   llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx,
45945ffd83dbSDimitry Andric                              const llvm::ElementCount &Count);
45950b57cec5SDimitry Andric   llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx);
45960b57cec5SDimitry Andric   llvm::Value *EmitNeonShiftVector(llvm::Value *V, llvm::Type *Ty,
45970b57cec5SDimitry Andric                                    bool negateForRightShift);
45980b57cec5SDimitry Andric   llvm::Value *EmitNeonRShiftImm(llvm::Value *Vec, llvm::Value *Amt,
45990b57cec5SDimitry Andric                                  llvm::Type *Ty, bool usgn, const char *name);
46000b57cec5SDimitry Andric   llvm::Value *vectorWrapScalar16(llvm::Value *Op);
46015ffd83dbSDimitry Andric   /// SVEBuiltinMemEltTy - Returns the memory element type for this memory
46025ffd83dbSDimitry Andric   /// access builtin.  Only required if it can't be inferred from the base
46035ffd83dbSDimitry Andric   /// pointer operand.
4604349cc55cSDimitry Andric   llvm::Type *SVEBuiltinMemEltTy(const SVETypeFlags &TypeFlags);
46055ffd83dbSDimitry Andric 
4606349cc55cSDimitry Andric   SmallVector<llvm::Type *, 2>
4607349cc55cSDimitry Andric   getSVEOverloadTypes(const SVETypeFlags &TypeFlags, llvm::Type *ReturnType,
46085ffd83dbSDimitry Andric                       ArrayRef<llvm::Value *> Ops);
4609349cc55cSDimitry Andric   llvm::Type *getEltType(const SVETypeFlags &TypeFlags);
46105ffd83dbSDimitry Andric   llvm::ScalableVectorType *getSVEType(const SVETypeFlags &TypeFlags);
4611349cc55cSDimitry Andric   llvm::ScalableVectorType *getSVEPredType(const SVETypeFlags &TypeFlags);
4612bdd1243dSDimitry Andric   llvm::Value *EmitSVETupleSetOrGet(const SVETypeFlags &TypeFlags,
4613bdd1243dSDimitry Andric                                     llvm::Type *ReturnType,
4614bdd1243dSDimitry Andric                                     ArrayRef<llvm::Value *> Ops);
4615bdd1243dSDimitry Andric   llvm::Value *EmitSVETupleCreate(const SVETypeFlags &TypeFlags,
4616bdd1243dSDimitry Andric                                   llvm::Type *ReturnType,
4617bdd1243dSDimitry Andric                                   ArrayRef<llvm::Value *> Ops);
4618349cc55cSDimitry Andric   llvm::Value *EmitSVEAllTruePred(const SVETypeFlags &TypeFlags);
46195ffd83dbSDimitry Andric   llvm::Value *EmitSVEDupX(llvm::Value *Scalar);
46205ffd83dbSDimitry Andric   llvm::Value *EmitSVEDupX(llvm::Value *Scalar, llvm::Type *Ty);
46215ffd83dbSDimitry Andric   llvm::Value *EmitSVEReinterpret(llvm::Value *Val, llvm::Type *Ty);
4622349cc55cSDimitry Andric   llvm::Value *EmitSVEPMull(const SVETypeFlags &TypeFlags,
46235ffd83dbSDimitry Andric                             llvm::SmallVectorImpl<llvm::Value *> &Ops,
46245ffd83dbSDimitry Andric                             unsigned BuiltinID);
4625349cc55cSDimitry Andric   llvm::Value *EmitSVEMovl(const SVETypeFlags &TypeFlags,
46265ffd83dbSDimitry Andric                            llvm::ArrayRef<llvm::Value *> Ops,
46275ffd83dbSDimitry Andric                            unsigned BuiltinID);
46285ffd83dbSDimitry Andric   llvm::Value *EmitSVEPredicateCast(llvm::Value *Pred,
46295ffd83dbSDimitry Andric                                     llvm::ScalableVectorType *VTy);
4630349cc55cSDimitry Andric   llvm::Value *EmitSVEGatherLoad(const SVETypeFlags &TypeFlags,
46315ffd83dbSDimitry Andric                                  llvm::SmallVectorImpl<llvm::Value *> &Ops,
46325ffd83dbSDimitry Andric                                  unsigned IntID);
4633349cc55cSDimitry Andric   llvm::Value *EmitSVEScatterStore(const SVETypeFlags &TypeFlags,
46345ffd83dbSDimitry Andric                                    llvm::SmallVectorImpl<llvm::Value *> &Ops,
46355ffd83dbSDimitry Andric                                    unsigned IntID);
46365ffd83dbSDimitry Andric   llvm::Value *EmitSVEMaskedLoad(const CallExpr *, llvm::Type *ReturnTy,
46375ffd83dbSDimitry Andric                                  SmallVectorImpl<llvm::Value *> &Ops,
46385ffd83dbSDimitry Andric                                  unsigned BuiltinID, bool IsZExtReturn);
46395ffd83dbSDimitry Andric   llvm::Value *EmitSVEMaskedStore(const CallExpr *,
46405ffd83dbSDimitry Andric                                   SmallVectorImpl<llvm::Value *> &Ops,
46415ffd83dbSDimitry Andric                                   unsigned BuiltinID);
4642349cc55cSDimitry Andric   llvm::Value *EmitSVEPrefetchLoad(const SVETypeFlags &TypeFlags,
46435ffd83dbSDimitry Andric                                    SmallVectorImpl<llvm::Value *> &Ops,
46445ffd83dbSDimitry Andric                                    unsigned BuiltinID);
4645349cc55cSDimitry Andric   llvm::Value *EmitSVEGatherPrefetch(const SVETypeFlags &TypeFlags,
46465ffd83dbSDimitry Andric                                      SmallVectorImpl<llvm::Value *> &Ops,
46475ffd83dbSDimitry Andric                                      unsigned IntID);
4648349cc55cSDimitry Andric   llvm::Value *EmitSVEStructLoad(const SVETypeFlags &TypeFlags,
4649349cc55cSDimitry Andric                                  SmallVectorImpl<llvm::Value *> &Ops,
4650349cc55cSDimitry Andric                                  unsigned IntID);
4651349cc55cSDimitry Andric   llvm::Value *EmitSVEStructStore(const SVETypeFlags &TypeFlags,
46525ffd83dbSDimitry Andric                                   SmallVectorImpl<llvm::Value *> &Ops,
46535ffd83dbSDimitry Andric                                   unsigned IntID);
46545f757f3fSDimitry Andric   /// FormSVEBuiltinResult - Returns the struct of scalable vectors as a wider
46555f757f3fSDimitry Andric   /// vector. It extracts the scalable vector from the struct and inserts into
46565f757f3fSDimitry Andric   /// the wider vector. This avoids the error when allocating space in llvm
46575f757f3fSDimitry Andric   /// for struct of scalable vectors if a function returns struct.
46585f757f3fSDimitry Andric   llvm::Value *FormSVEBuiltinResult(llvm::Value *Call);
46595f757f3fSDimitry Andric 
46605ffd83dbSDimitry Andric   llvm::Value *EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
46615ffd83dbSDimitry Andric 
46625f757f3fSDimitry Andric   llvm::Value *EmitSMELd1St1(const SVETypeFlags &TypeFlags,
466306c3fb27SDimitry Andric                              llvm::SmallVectorImpl<llvm::Value *> &Ops,
466406c3fb27SDimitry Andric                              unsigned IntID);
46655f757f3fSDimitry Andric   llvm::Value *EmitSMEReadWrite(const SVETypeFlags &TypeFlags,
466606c3fb27SDimitry Andric                                 llvm::SmallVectorImpl<llvm::Value *> &Ops,
466706c3fb27SDimitry Andric                                 unsigned IntID);
46685f757f3fSDimitry Andric   llvm::Value *EmitSMEZero(const SVETypeFlags &TypeFlags,
466906c3fb27SDimitry Andric                            llvm::SmallVectorImpl<llvm::Value *> &Ops,
467006c3fb27SDimitry Andric                            unsigned IntID);
46715f757f3fSDimitry Andric   llvm::Value *EmitSMELdrStr(const SVETypeFlags &TypeFlags,
467206c3fb27SDimitry Andric                              llvm::SmallVectorImpl<llvm::Value *> &Ops,
467306c3fb27SDimitry Andric                              unsigned IntID);
46745f757f3fSDimitry Andric 
46755f757f3fSDimitry Andric   void GetAArch64SVEProcessedOperands(unsigned BuiltinID, const CallExpr *E,
46765f757f3fSDimitry Andric                                       SmallVectorImpl<llvm::Value *> &Ops,
46775f757f3fSDimitry Andric                                       SVETypeFlags TypeFlags);
46785f757f3fSDimitry Andric 
467906c3fb27SDimitry Andric   llvm::Value *EmitAArch64SMEBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
468006c3fb27SDimitry Andric 
46810b57cec5SDimitry Andric   llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E,
46820b57cec5SDimitry Andric                                       llvm::Triple::ArchType Arch);
4683a7dea167SDimitry Andric   llvm::Value *EmitBPFBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
46840b57cec5SDimitry Andric 
46850b57cec5SDimitry Andric   llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops);
46860b57cec5SDimitry Andric   llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
46870b57cec5SDimitry Andric   llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
46880b57cec5SDimitry Andric   llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
46890fca6ea1SDimitry Andric   llvm::Value *EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
46905f757f3fSDimitry Andric   llvm::Value *EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx,
46915f757f3fSDimitry Andric                                            const CallExpr *E);
46920b57cec5SDimitry Andric   llvm::Value *EmitSystemZBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
46930b57cec5SDimitry Andric   llvm::Value *EmitNVPTXBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
46940b57cec5SDimitry Andric   llvm::Value *EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
46950b57cec5SDimitry Andric                                           const CallExpr *E);
46960b57cec5SDimitry Andric   llvm::Value *EmitHexagonBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
4697fe6060f1SDimitry Andric   llvm::Value *EmitRISCVBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
4698fe6060f1SDimitry Andric                                     ReturnValueSlot ReturnValue);
46990fca6ea1SDimitry Andric 
47000fca6ea1SDimitry Andric   void AddAMDGPUFenceAddressSpaceMMRA(llvm::Instruction *Inst,
47010fca6ea1SDimitry Andric                                       const CallExpr *E);
4702bdd1243dSDimitry Andric   void ProcessOrderScopeAMDGCN(llvm::Value *Order, llvm::Value *Scope,
47035ffd83dbSDimitry Andric                                llvm::AtomicOrdering &AO,
47045ffd83dbSDimitry Andric                                llvm::SyncScope::ID &SSID);
47050b57cec5SDimitry Andric 
47060b57cec5SDimitry Andric   enum class MSVCIntrin;
47070b57cec5SDimitry Andric   llvm::Value *EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E);
47080b57cec5SDimitry Andric 
4709e8d8bef9SDimitry Andric   llvm::Value *EmitBuiltinAvailable(const VersionTuple &Version);
47100b57cec5SDimitry Andric 
47110b57cec5SDimitry Andric   llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
47120b57cec5SDimitry Andric   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
47130b57cec5SDimitry Andric   llvm::Value *EmitObjCBoxedExpr(const ObjCBoxedExpr *E);
47140b57cec5SDimitry Andric   llvm::Value *EmitObjCArrayLiteral(const ObjCArrayLiteral *E);
47150b57cec5SDimitry Andric   llvm::Value *EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E);
47160b57cec5SDimitry Andric   llvm::Value *EmitObjCCollectionLiteral(const Expr *E,
47170b57cec5SDimitry Andric                                 const ObjCMethodDecl *MethodWithObjects);
47180b57cec5SDimitry Andric   llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
47190b57cec5SDimitry Andric   RValue EmitObjCMessageExpr(const ObjCMessageExpr *E,
47200b57cec5SDimitry Andric                              ReturnValueSlot Return = ReturnValueSlot());
47210b57cec5SDimitry Andric 
47220b57cec5SDimitry Andric   /// Retrieves the default cleanup kind for an ARC cleanup.
47230b57cec5SDimitry Andric   /// Except under -fobjc-arc-eh, ARC cleanups are normal-only.
47240b57cec5SDimitry Andric   CleanupKind getARCCleanupKind() {
47250b57cec5SDimitry Andric     return CGM.getCodeGenOpts().ObjCAutoRefCountExceptions
47260b57cec5SDimitry Andric              ? NormalAndEHCleanup : NormalCleanup;
47270b57cec5SDimitry Andric   }
47280b57cec5SDimitry Andric 
47290b57cec5SDimitry Andric   // ARC primitives.
47300b57cec5SDimitry Andric   void EmitARCInitWeak(Address addr, llvm::Value *value);
47310b57cec5SDimitry Andric   void EmitARCDestroyWeak(Address addr);
47320b57cec5SDimitry Andric   llvm::Value *EmitARCLoadWeak(Address addr);
47330b57cec5SDimitry Andric   llvm::Value *EmitARCLoadWeakRetained(Address addr);
47340b57cec5SDimitry Andric   llvm::Value *EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored);
47350b57cec5SDimitry Andric   void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr);
47360b57cec5SDimitry Andric   void emitARCMoveAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr);
47370b57cec5SDimitry Andric   void EmitARCCopyWeak(Address dst, Address src);
47380b57cec5SDimitry Andric   void EmitARCMoveWeak(Address dst, Address src);
47390b57cec5SDimitry Andric   llvm::Value *EmitARCRetainAutorelease(QualType type, llvm::Value *value);
47400b57cec5SDimitry Andric   llvm::Value *EmitARCRetainAutoreleaseNonBlock(llvm::Value *value);
47410b57cec5SDimitry Andric   llvm::Value *EmitARCStoreStrong(LValue lvalue, llvm::Value *value,
47420b57cec5SDimitry Andric                                   bool resultIgnored);
47430b57cec5SDimitry Andric   llvm::Value *EmitARCStoreStrongCall(Address addr, llvm::Value *value,
47440b57cec5SDimitry Andric                                       bool resultIgnored);
47450b57cec5SDimitry Andric   llvm::Value *EmitARCRetain(QualType type, llvm::Value *value);
47460b57cec5SDimitry Andric   llvm::Value *EmitARCRetainNonBlock(llvm::Value *value);
47470b57cec5SDimitry Andric   llvm::Value *EmitARCRetainBlock(llvm::Value *value, bool mandatory);
47480b57cec5SDimitry Andric   void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise);
47490b57cec5SDimitry Andric   void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise);
47500b57cec5SDimitry Andric   llvm::Value *EmitARCAutorelease(llvm::Value *value);
47510b57cec5SDimitry Andric   llvm::Value *EmitARCAutoreleaseReturnValue(llvm::Value *value);
47520b57cec5SDimitry Andric   llvm::Value *EmitARCRetainAutoreleaseReturnValue(llvm::Value *value);
47530b57cec5SDimitry Andric   llvm::Value *EmitARCRetainAutoreleasedReturnValue(llvm::Value *value);
47540b57cec5SDimitry Andric   llvm::Value *EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value);
47550b57cec5SDimitry Andric 
47560b57cec5SDimitry Andric   llvm::Value *EmitObjCAutorelease(llvm::Value *value, llvm::Type *returnType);
47570b57cec5SDimitry Andric   llvm::Value *EmitObjCRetainNonBlock(llvm::Value *value,
47580b57cec5SDimitry Andric                                       llvm::Type *returnType);
47590b57cec5SDimitry Andric   void EmitObjCRelease(llvm::Value *value, ARCPreciseLifetime_t precise);
47600b57cec5SDimitry Andric 
47610b57cec5SDimitry Andric   std::pair<LValue,llvm::Value*>
47620b57cec5SDimitry Andric   EmitARCStoreAutoreleasing(const BinaryOperator *e);
47630b57cec5SDimitry Andric   std::pair<LValue,llvm::Value*>
47640b57cec5SDimitry Andric   EmitARCStoreStrong(const BinaryOperator *e, bool ignored);
47650b57cec5SDimitry Andric   std::pair<LValue,llvm::Value*>
47660b57cec5SDimitry Andric   EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored);
47670b57cec5SDimitry Andric 
47680b57cec5SDimitry Andric   llvm::Value *EmitObjCAlloc(llvm::Value *value,
47690b57cec5SDimitry Andric                              llvm::Type *returnType);
47700b57cec5SDimitry Andric   llvm::Value *EmitObjCAllocWithZone(llvm::Value *value,
47710b57cec5SDimitry Andric                                      llvm::Type *returnType);
47720b57cec5SDimitry Andric   llvm::Value *EmitObjCAllocInit(llvm::Value *value, llvm::Type *resultType);
47730b57cec5SDimitry Andric 
47740b57cec5SDimitry Andric   llvm::Value *EmitObjCThrowOperand(const Expr *expr);
47750b57cec5SDimitry Andric   llvm::Value *EmitObjCConsumeObject(QualType T, llvm::Value *Ptr);
47760b57cec5SDimitry Andric   llvm::Value *EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr);
47770b57cec5SDimitry Andric 
47780b57cec5SDimitry Andric   llvm::Value *EmitARCExtendBlockObject(const Expr *expr);
47790b57cec5SDimitry Andric   llvm::Value *EmitARCReclaimReturnedObject(const Expr *e,
47800b57cec5SDimitry Andric                                             bool allowUnsafeClaim);
47810b57cec5SDimitry Andric   llvm::Value *EmitARCRetainScalarExpr(const Expr *expr);
47820b57cec5SDimitry Andric   llvm::Value *EmitARCRetainAutoreleaseScalarExpr(const Expr *expr);
47830b57cec5SDimitry Andric   llvm::Value *EmitARCUnsafeUnretainedScalarExpr(const Expr *expr);
47840b57cec5SDimitry Andric 
47850b57cec5SDimitry Andric   void EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values);
47860b57cec5SDimitry Andric 
4787fe6060f1SDimitry Andric   void EmitARCNoopIntrinsicUse(ArrayRef<llvm::Value *> values);
4788fe6060f1SDimitry Andric 
47890b57cec5SDimitry Andric   static Destroyer destroyARCStrongImprecise;
47900b57cec5SDimitry Andric   static Destroyer destroyARCStrongPrecise;
47910b57cec5SDimitry Andric   static Destroyer destroyARCWeak;
47920b57cec5SDimitry Andric   static Destroyer emitARCIntrinsicUse;
47930b57cec5SDimitry Andric   static Destroyer destroyNonTrivialCStruct;
47940b57cec5SDimitry Andric 
47950b57cec5SDimitry Andric   void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr);
47960b57cec5SDimitry Andric   llvm::Value *EmitObjCAutoreleasePoolPush();
47970b57cec5SDimitry Andric   llvm::Value *EmitObjCMRRAutoreleasePoolPush();
47980b57cec5SDimitry Andric   void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr);
47990b57cec5SDimitry Andric   void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr);
48000b57cec5SDimitry Andric 
48010b57cec5SDimitry Andric   /// Emits a reference binding to the passed in expression.
48020b57cec5SDimitry Andric   RValue EmitReferenceBindingToExpr(const Expr *E);
48030b57cec5SDimitry Andric 
48040b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
48050b57cec5SDimitry Andric   //                           Expression Emission
48060b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
48070b57cec5SDimitry Andric 
48080b57cec5SDimitry Andric   // Expressions are broken into three classes: scalar, complex, aggregate.
48090b57cec5SDimitry Andric 
48100b57cec5SDimitry Andric   /// EmitScalarExpr - Emit the computation of the specified expression of LLVM
48110b57cec5SDimitry Andric   /// scalar type, returning the result.
48120b57cec5SDimitry Andric   llvm::Value *EmitScalarExpr(const Expr *E , bool IgnoreResultAssign = false);
48130b57cec5SDimitry Andric 
48140b57cec5SDimitry Andric   /// Emit a conversion from the specified type to the specified destination
48150b57cec5SDimitry Andric   /// type, both of which are LLVM scalar types.
48160b57cec5SDimitry Andric   llvm::Value *EmitScalarConversion(llvm::Value *Src, QualType SrcTy,
48170b57cec5SDimitry Andric                                     QualType DstTy, SourceLocation Loc);
48180b57cec5SDimitry Andric 
48190b57cec5SDimitry Andric   /// Emit a conversion from the specified complex type to the specified
48200b57cec5SDimitry Andric   /// destination type, where the destination type is an LLVM scalar type.
48210b57cec5SDimitry Andric   llvm::Value *EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy,
48220b57cec5SDimitry Andric                                              QualType DstTy,
48230b57cec5SDimitry Andric                                              SourceLocation Loc);
48240b57cec5SDimitry Andric 
48250b57cec5SDimitry Andric   /// EmitAggExpr - Emit the computation of the specified expression
48260b57cec5SDimitry Andric   /// of aggregate type.  The result is computed into the given slot,
48270b57cec5SDimitry Andric   /// which may be null to indicate that the value is not needed.
48280b57cec5SDimitry Andric   void EmitAggExpr(const Expr *E, AggValueSlot AS);
48290b57cec5SDimitry Andric 
48300b57cec5SDimitry Andric   /// EmitAggExprToLValue - Emit the computation of the specified expression of
48310b57cec5SDimitry Andric   /// aggregate type into a temporary LValue.
48320b57cec5SDimitry Andric   LValue EmitAggExprToLValue(const Expr *E);
48330b57cec5SDimitry Andric 
48340fca6ea1SDimitry Andric   enum ExprValueKind { EVK_RValue, EVK_NonRValue };
48350fca6ea1SDimitry Andric 
48360fca6ea1SDimitry Andric   /// EmitAggFinalDestCopy - Emit copy of the specified aggregate into
48370fca6ea1SDimitry Andric   /// destination address.
48380fca6ea1SDimitry Andric   void EmitAggFinalDestCopy(QualType Type, AggValueSlot Dest, const LValue &Src,
48390fca6ea1SDimitry Andric                             ExprValueKind SrcKind);
48400fca6ea1SDimitry Andric 
4841*c80e69b0SDimitry Andric   /// Create a store to \arg DstPtr from \arg Src, truncating the stored value
4842*c80e69b0SDimitry Andric   /// to at most \arg DstSize bytes.
4843*c80e69b0SDimitry Andric   void CreateCoercedStore(llvm::Value *Src, Address Dst, llvm::TypeSize DstSize,
4844*c80e69b0SDimitry Andric                           bool DstIsVolatile);
48455ffd83dbSDimitry Andric 
48460b57cec5SDimitry Andric   /// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
48470b57cec5SDimitry Andric   /// make sure it survives garbage collection until this point.
48480b57cec5SDimitry Andric   void EmitExtendGCLifetime(llvm::Value *object);
48490b57cec5SDimitry Andric 
48500b57cec5SDimitry Andric   /// EmitComplexExpr - Emit the computation of the specified expression of
48510b57cec5SDimitry Andric   /// complex type, returning the result.
48520b57cec5SDimitry Andric   ComplexPairTy EmitComplexExpr(const Expr *E,
48530b57cec5SDimitry Andric                                 bool IgnoreReal = false,
48540b57cec5SDimitry Andric                                 bool IgnoreImag = false);
48550b57cec5SDimitry Andric 
48560b57cec5SDimitry Andric   /// EmitComplexExprIntoLValue - Emit the given expression of complex
48570b57cec5SDimitry Andric   /// type and place its result into the specified l-value.
48580b57cec5SDimitry Andric   void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit);
48590b57cec5SDimitry Andric 
48600b57cec5SDimitry Andric   /// EmitStoreOfComplex - Store a complex number into the specified l-value.
48610b57cec5SDimitry Andric   void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit);
48620b57cec5SDimitry Andric 
48630b57cec5SDimitry Andric   /// EmitLoadOfComplex - Load a complex number from the specified l-value.
48640b57cec5SDimitry Andric   ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc);
48650b57cec5SDimitry Andric 
4866bdd1243dSDimitry Andric   ComplexPairTy EmitPromotedComplexExpr(const Expr *E, QualType PromotionType);
4867bdd1243dSDimitry Andric   llvm::Value *EmitPromotedScalarExpr(const Expr *E, QualType PromotionType);
4868bdd1243dSDimitry Andric   ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType);
4869bdd1243dSDimitry Andric   ComplexPairTy EmitUnPromotedValue(ComplexPairTy result, QualType PromotionType);
4870bdd1243dSDimitry Andric 
48710b57cec5SDimitry Andric   Address emitAddrOfRealComponent(Address complex, QualType complexType);
48720b57cec5SDimitry Andric   Address emitAddrOfImagComponent(Address complex, QualType complexType);
48730b57cec5SDimitry Andric 
48740b57cec5SDimitry Andric   /// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the
48750b57cec5SDimitry Andric   /// global variable that has already been created for it.  If the initializer
48760b57cec5SDimitry Andric   /// has a different type than GV does, this may free GV and return a different
48770b57cec5SDimitry Andric   /// one.  Otherwise it just returns GV.
48780b57cec5SDimitry Andric   llvm::GlobalVariable *
48790b57cec5SDimitry Andric   AddInitializerToStaticVarDecl(const VarDecl &D,
48800b57cec5SDimitry Andric                                 llvm::GlobalVariable *GV);
48810b57cec5SDimitry Andric 
48820b57cec5SDimitry Andric   // Emit an @llvm.invariant.start call for the given memory region.
48830b57cec5SDimitry Andric   void EmitInvariantStart(llvm::Constant *Addr, CharUnits Size);
48840b57cec5SDimitry Andric 
48850b57cec5SDimitry Andric   /// EmitCXXGlobalVarDeclInit - Create the initializer for a C++
48860b57cec5SDimitry Andric   /// variable with global storage.
48870eae32dcSDimitry Andric   void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV,
48880b57cec5SDimitry Andric                                 bool PerformInit);
48890b57cec5SDimitry Andric 
48900fca6ea1SDimitry Andric   llvm::Constant *createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor,
48910b57cec5SDimitry Andric                                    llvm::Constant *Addr);
48920b57cec5SDimitry Andric 
4893fe6060f1SDimitry Andric   llvm::Function *createTLSAtExitStub(const VarDecl &VD,
4894fe6060f1SDimitry Andric                                       llvm::FunctionCallee Dtor,
4895fe6060f1SDimitry Andric                                       llvm::Constant *Addr,
4896fe6060f1SDimitry Andric                                       llvm::FunctionCallee &AtExit);
4897fe6060f1SDimitry Andric 
48980b57cec5SDimitry Andric   /// Call atexit() with a function that passes the given argument to
48990b57cec5SDimitry Andric   /// the given function.
49000b57cec5SDimitry Andric   void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn,
49010b57cec5SDimitry Andric                                     llvm::Constant *addr);
49020b57cec5SDimitry Andric 
49035f757f3fSDimitry Andric   /// Registers the dtor using 'llvm.global_dtors' for platforms that do not
49045f757f3fSDimitry Andric   /// support an 'atexit()' function.
49055f757f3fSDimitry Andric   void registerGlobalDtorWithLLVM(const VarDecl &D, llvm::FunctionCallee fn,
49065f757f3fSDimitry Andric                                   llvm::Constant *addr);
49075f757f3fSDimitry Andric 
49080b57cec5SDimitry Andric   /// Call atexit() with function dtorStub.
49090b57cec5SDimitry Andric   void registerGlobalDtorWithAtExit(llvm::Constant *dtorStub);
49100b57cec5SDimitry Andric 
49115ffd83dbSDimitry Andric   /// Call unatexit() with function dtorStub.
4912e8d8bef9SDimitry Andric   llvm::Value *unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub);
49135ffd83dbSDimitry Andric 
49140b57cec5SDimitry Andric   /// Emit code in this function to perform a guarded variable
49150b57cec5SDimitry Andric   /// initialization.  Guarded initializations are used when it's not
49160b57cec5SDimitry Andric   /// possible to prove that an initialization will be done exactly
49170b57cec5SDimitry Andric   /// once, e.g. with a static local variable or a static data member
49180b57cec5SDimitry Andric   /// of a class template.
49190b57cec5SDimitry Andric   void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr,
49200b57cec5SDimitry Andric                           bool PerformInit);
49210b57cec5SDimitry Andric 
49220b57cec5SDimitry Andric   enum class GuardKind { VariableGuard, TlsGuard };
49230b57cec5SDimitry Andric 
49240b57cec5SDimitry Andric   /// Emit a branch to select whether or not to perform guarded initialization.
49250b57cec5SDimitry Andric   void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit,
49260b57cec5SDimitry Andric                                 llvm::BasicBlock *InitBlock,
49270b57cec5SDimitry Andric                                 llvm::BasicBlock *NoInitBlock,
49280b57cec5SDimitry Andric                                 GuardKind Kind, const VarDecl *D);
49290b57cec5SDimitry Andric 
49300b57cec5SDimitry Andric   /// GenerateCXXGlobalInitFunc - Generates code for initializing global
49310b57cec5SDimitry Andric   /// variables.
49320b57cec5SDimitry Andric   void
49330b57cec5SDimitry Andric   GenerateCXXGlobalInitFunc(llvm::Function *Fn,
49340b57cec5SDimitry Andric                             ArrayRef<llvm::Function *> CXXThreadLocals,
49350b57cec5SDimitry Andric                             ConstantAddress Guard = ConstantAddress::invalid());
49360b57cec5SDimitry Andric 
49375ffd83dbSDimitry Andric   /// GenerateCXXGlobalCleanUpFunc - Generates code for cleaning up global
49380b57cec5SDimitry Andric   /// variables.
49395ffd83dbSDimitry Andric   void GenerateCXXGlobalCleanUpFunc(
49400b57cec5SDimitry Andric       llvm::Function *Fn,
4941fe6060f1SDimitry Andric       ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
4942fe6060f1SDimitry Andric                           llvm::Constant *>>
4943fe6060f1SDimitry Andric           DtorsOrStermFinalizers);
49440b57cec5SDimitry Andric 
49450b57cec5SDimitry Andric   void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
49460b57cec5SDimitry Andric                                         const VarDecl *D,
49470b57cec5SDimitry Andric                                         llvm::GlobalVariable *Addr,
49480b57cec5SDimitry Andric                                         bool PerformInit);
49490b57cec5SDimitry Andric 
49500b57cec5SDimitry Andric   void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest);
49510b57cec5SDimitry Andric 
49520b57cec5SDimitry Andric   void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp);
49530b57cec5SDimitry Andric 
49540b57cec5SDimitry Andric   void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint = true);
49550b57cec5SDimitry Andric 
49560b57cec5SDimitry Andric   RValue EmitAtomicExpr(AtomicExpr *E);
49570b57cec5SDimitry Andric 
49580b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
49590b57cec5SDimitry Andric   //                         Annotations Emission
49600b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
49610b57cec5SDimitry Andric 
49620b57cec5SDimitry Andric   /// Emit an annotation call (intrinsic).
49630b57cec5SDimitry Andric   llvm::Value *EmitAnnotationCall(llvm::Function *AnnotationFn,
49640b57cec5SDimitry Andric                                   llvm::Value *AnnotatedVal,
49650b57cec5SDimitry Andric                                   StringRef AnnotationStr,
4966e8d8bef9SDimitry Andric                                   SourceLocation Location,
4967e8d8bef9SDimitry Andric                                   const AnnotateAttr *Attr);
49680b57cec5SDimitry Andric 
49690b57cec5SDimitry Andric   /// Emit local annotations for the local variable V, declared by D.
49700b57cec5SDimitry Andric   void EmitVarAnnotations(const VarDecl *D, llvm::Value *V);
49710b57cec5SDimitry Andric 
49720b57cec5SDimitry Andric   /// Emit field annotations for the given field & value. Returns the
49730b57cec5SDimitry Andric   /// annotation result.
49740b57cec5SDimitry Andric   Address EmitFieldAnnotations(const FieldDecl *D, Address V);
49750b57cec5SDimitry Andric 
49760b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
49770b57cec5SDimitry Andric   //                             Internal Helpers
49780b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
49790b57cec5SDimitry Andric 
49800b57cec5SDimitry Andric   /// ContainsLabel - Return true if the statement contains a label in it.  If
49810b57cec5SDimitry Andric   /// this statement is not executed normally, it not containing a label means
49820b57cec5SDimitry Andric   /// that we can just remove the code.
49830b57cec5SDimitry Andric   static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false);
49840b57cec5SDimitry Andric 
49850b57cec5SDimitry Andric   /// containsBreak - Return true if the statement contains a break out of it.
49860b57cec5SDimitry Andric   /// If the statement (recursively) contains a switch or loop with a break
49870b57cec5SDimitry Andric   /// inside of it, this is fine.
49880b57cec5SDimitry Andric   static bool containsBreak(const Stmt *S);
49890b57cec5SDimitry Andric 
49900b57cec5SDimitry Andric   /// Determine if the given statement might introduce a declaration into the
49910b57cec5SDimitry Andric   /// current scope, by being a (possibly-labelled) DeclStmt.
49920b57cec5SDimitry Andric   static bool mightAddDeclToScope(const Stmt *S);
49930b57cec5SDimitry Andric 
49940b57cec5SDimitry Andric   /// ConstantFoldsToSimpleInteger - If the specified expression does not fold
49950b57cec5SDimitry Andric   /// to a constant, or if it does but contains a label, return false.  If it
49960b57cec5SDimitry Andric   /// constant folds return true and set the boolean result in Result.
49970b57cec5SDimitry Andric   bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result,
49980b57cec5SDimitry Andric                                     bool AllowLabels = false);
49990b57cec5SDimitry Andric 
50000b57cec5SDimitry Andric   /// ConstantFoldsToSimpleInteger - If the specified expression does not fold
50010b57cec5SDimitry Andric   /// to a constant, or if it does but contains a label, return false.  If it
50020b57cec5SDimitry Andric   /// constant folds return true and set the folded value.
50030b57cec5SDimitry Andric   bool ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APSInt &Result,
50040b57cec5SDimitry Andric                                     bool AllowLabels = false);
50050b57cec5SDimitry Andric 
50061db9f3b2SDimitry Andric   /// Ignore parentheses and logical-NOT to track conditions consistently.
50071db9f3b2SDimitry Andric   static const Expr *stripCond(const Expr *C);
50081db9f3b2SDimitry Andric 
5009e8d8bef9SDimitry Andric   /// isInstrumentedCondition - Determine whether the given condition is an
5010e8d8bef9SDimitry Andric   /// instrumentable condition (i.e. no "&&" or "||").
5011e8d8bef9SDimitry Andric   static bool isInstrumentedCondition(const Expr *C);
5012e8d8bef9SDimitry Andric 
5013e8d8bef9SDimitry Andric   /// EmitBranchToCounterBlock - Emit a conditional branch to a new block that
5014e8d8bef9SDimitry Andric   /// increments a profile counter based on the semantics of the given logical
5015e8d8bef9SDimitry Andric   /// operator opcode.  This is used to instrument branch condition coverage
5016e8d8bef9SDimitry Andric   /// for logical operators.
5017e8d8bef9SDimitry Andric   void EmitBranchToCounterBlock(const Expr *Cond, BinaryOperator::Opcode LOp,
5018e8d8bef9SDimitry Andric                                 llvm::BasicBlock *TrueBlock,
5019e8d8bef9SDimitry Andric                                 llvm::BasicBlock *FalseBlock,
5020e8d8bef9SDimitry Andric                                 uint64_t TrueCount = 0,
5021e8d8bef9SDimitry Andric                                 Stmt::Likelihood LH = Stmt::LH_None,
5022e8d8bef9SDimitry Andric                                 const Expr *CntrIdx = nullptr);
5023e8d8bef9SDimitry Andric 
50240b57cec5SDimitry Andric   /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an
50250b57cec5SDimitry Andric   /// if statement) to the specified blocks.  Based on the condition, this might
50260b57cec5SDimitry Andric   /// try to simplify the codegen of the conditional based on the branch.
50270b57cec5SDimitry Andric   /// TrueCount should be the number of times we expect the condition to
50280b57cec5SDimitry Andric   /// evaluate to true based on PGO data.
50290b57cec5SDimitry Andric   void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock,
5030e8d8bef9SDimitry Andric                             llvm::BasicBlock *FalseBlock, uint64_t TrueCount,
50311db9f3b2SDimitry Andric                             Stmt::Likelihood LH = Stmt::LH_None,
50321db9f3b2SDimitry Andric                             const Expr *ConditionalOp = nullptr);
50330b57cec5SDimitry Andric 
50340b57cec5SDimitry Andric   /// Given an assignment `*LHS = RHS`, emit a test that checks if \p RHS is
50350b57cec5SDimitry Andric   /// nonnull, if \p LHS is marked _Nonnull.
50360b57cec5SDimitry Andric   void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc);
50370b57cec5SDimitry Andric 
50380b57cec5SDimitry Andric   /// An enumeration which makes it easier to specify whether or not an
50390b57cec5SDimitry Andric   /// operation is a subtraction.
50400b57cec5SDimitry Andric   enum { NotSubtraction = false, IsSubtraction = true };
50410b57cec5SDimitry Andric 
50420b57cec5SDimitry Andric   /// Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to
50430b57cec5SDimitry Andric   /// detect undefined behavior when the pointer overflow sanitizer is enabled.
50440b57cec5SDimitry Andric   /// \p SignedIndices indicates whether any of the GEP indices are signed.
50450b57cec5SDimitry Andric   /// \p IsSubtraction indicates whether the expression used to form the GEP
50460b57cec5SDimitry Andric   /// is a subtraction.
50470eae32dcSDimitry Andric   llvm::Value *EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr,
50480b57cec5SDimitry Andric                                       ArrayRef<llvm::Value *> IdxList,
50490b57cec5SDimitry Andric                                       bool SignedIndices,
50500b57cec5SDimitry Andric                                       bool IsSubtraction,
50510b57cec5SDimitry Andric                                       SourceLocation Loc,
50520b57cec5SDimitry Andric                                       const Twine &Name = "");
50530b57cec5SDimitry Andric 
50540fca6ea1SDimitry Andric   Address EmitCheckedInBoundsGEP(Address Addr, ArrayRef<llvm::Value *> IdxList,
50550fca6ea1SDimitry Andric                                  llvm::Type *elementType, bool SignedIndices,
50560fca6ea1SDimitry Andric                                  bool IsSubtraction, SourceLocation Loc,
50570fca6ea1SDimitry Andric                                  CharUnits Align, const Twine &Name = "");
50580fca6ea1SDimitry Andric 
50590b57cec5SDimitry Andric   /// Specifies which type of sanitizer check to apply when handling a
50600b57cec5SDimitry Andric   /// particular builtin.
50610b57cec5SDimitry Andric   enum BuiltinCheckKind {
50620b57cec5SDimitry Andric     BCK_CTZPassedZero,
50630b57cec5SDimitry Andric     BCK_CLZPassedZero,
50640b57cec5SDimitry Andric   };
50650b57cec5SDimitry Andric 
50660b57cec5SDimitry Andric   /// Emits an argument for a call to a builtin. If the builtin sanitizer is
50670b57cec5SDimitry Andric   /// enabled, a runtime check specified by \p Kind is also emitted.
50680b57cec5SDimitry Andric   llvm::Value *EmitCheckedArgForBuiltin(const Expr *E, BuiltinCheckKind Kind);
50690b57cec5SDimitry Andric 
50700b57cec5SDimitry Andric   /// Emit a description of a type in a format suitable for passing to
50710b57cec5SDimitry Andric   /// a runtime sanitizer handler.
50720b57cec5SDimitry Andric   llvm::Constant *EmitCheckTypeDescriptor(QualType T);
50730b57cec5SDimitry Andric 
50740b57cec5SDimitry Andric   /// Convert a value into a format suitable for passing to a runtime
50750b57cec5SDimitry Andric   /// sanitizer handler.
50760b57cec5SDimitry Andric   llvm::Value *EmitCheckValue(llvm::Value *V);
50770b57cec5SDimitry Andric 
50780b57cec5SDimitry Andric   /// Emit a description of a source location in a format suitable for
50790b57cec5SDimitry Andric   /// passing to a runtime sanitizer handler.
50800b57cec5SDimitry Andric   llvm::Constant *EmitCheckSourceLocation(SourceLocation Loc);
50810b57cec5SDimitry Andric 
5082bdd1243dSDimitry Andric   void EmitKCFIOperandBundle(const CGCallee &Callee,
5083bdd1243dSDimitry Andric                              SmallVectorImpl<llvm::OperandBundleDef> &Bundles);
5084bdd1243dSDimitry Andric 
50850b57cec5SDimitry Andric   /// Create a basic block that will either trap or call a handler function in
50860b57cec5SDimitry Andric   /// the UBSan runtime with the provided arguments, and create a conditional
50870b57cec5SDimitry Andric   /// branch to it.
50880b57cec5SDimitry Andric   void EmitCheck(ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked,
50890b57cec5SDimitry Andric                  SanitizerHandler Check, ArrayRef<llvm::Constant *> StaticArgs,
50900b57cec5SDimitry Andric                  ArrayRef<llvm::Value *> DynamicArgs);
50910b57cec5SDimitry Andric 
50920b57cec5SDimitry Andric   /// Emit a slow path cross-DSO CFI check which calls __cfi_slowpath
50930b57cec5SDimitry Andric   /// if Cond if false.
50940b57cec5SDimitry Andric   void EmitCfiSlowPathCheck(SanitizerMask Kind, llvm::Value *Cond,
50950b57cec5SDimitry Andric                             llvm::ConstantInt *TypeId, llvm::Value *Ptr,
50960b57cec5SDimitry Andric                             ArrayRef<llvm::Constant *> StaticArgs);
50970b57cec5SDimitry Andric 
50980b57cec5SDimitry Andric   /// Emit a reached-unreachable diagnostic if \p Loc is valid and runtime
50990b57cec5SDimitry Andric   /// checking is enabled. Otherwise, just emit an unreachable instruction.
51000b57cec5SDimitry Andric   void EmitUnreachable(SourceLocation Loc);
51010b57cec5SDimitry Andric 
51020b57cec5SDimitry Andric   /// Create a basic block that will call the trap intrinsic, and emit a
51030b57cec5SDimitry Andric   /// conditional branch to it, for the -ftrapv checks.
5104e8d8bef9SDimitry Andric   void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID);
51050b57cec5SDimitry Andric 
51060b57cec5SDimitry Andric   /// Emit a call to trap or debugtrap and attach function attribute
51070b57cec5SDimitry Andric   /// "trap-func-name" if specified.
51080b57cec5SDimitry Andric   llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID);
51090b57cec5SDimitry Andric 
51100b57cec5SDimitry Andric   /// Emit a stub for the cross-DSO CFI check function.
51110b57cec5SDimitry Andric   void EmitCfiCheckStub();
51120b57cec5SDimitry Andric 
51130b57cec5SDimitry Andric   /// Emit a cross-DSO CFI failure handling function.
51140b57cec5SDimitry Andric   void EmitCfiCheckFail();
51150b57cec5SDimitry Andric 
51160b57cec5SDimitry Andric   /// Create a check for a function parameter that may potentially be
51170b57cec5SDimitry Andric   /// declared as non-null.
51180b57cec5SDimitry Andric   void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc,
51190b57cec5SDimitry Andric                            AbstractCallee AC, unsigned ParmNum);
51200b57cec5SDimitry Andric 
51210fca6ea1SDimitry Andric   void EmitNonNullArgCheck(Address Addr, QualType ArgType,
51220fca6ea1SDimitry Andric                            SourceLocation ArgLoc, AbstractCallee AC,
51230fca6ea1SDimitry Andric                            unsigned ParmNum);
51240fca6ea1SDimitry Andric 
51250b57cec5SDimitry Andric   /// EmitCallArg - Emit a single call argument.
51260b57cec5SDimitry Andric   void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);
51270b57cec5SDimitry Andric 
51280b57cec5SDimitry Andric   /// EmitDelegateCallArg - We are performing a delegate call; that
51290b57cec5SDimitry Andric   /// is, the current function is delegating to another one.  Produce
51300b57cec5SDimitry Andric   /// a r-value suitable for passing the given parameter.
51310b57cec5SDimitry Andric   void EmitDelegateCallArg(CallArgList &args, const VarDecl *param,
51320b57cec5SDimitry Andric                            SourceLocation loc);
51330b57cec5SDimitry Andric 
51340b57cec5SDimitry Andric   /// SetFPAccuracy - Set the minimum required accuracy of the given floating
51350b57cec5SDimitry Andric   /// point operation, expressed as the maximum relative error in ulp.
51360b57cec5SDimitry Andric   void SetFPAccuracy(llvm::Value *Val, float Accuracy);
51370b57cec5SDimitry Andric 
513806c3fb27SDimitry Andric   /// Set the minimum required accuracy of the given sqrt operation
513906c3fb27SDimitry Andric   /// based on CodeGenOpts.
514006c3fb27SDimitry Andric   void SetSqrtFPAccuracy(llvm::Value *Val);
514106c3fb27SDimitry Andric 
514206c3fb27SDimitry Andric   /// Set the minimum required accuracy of the given sqrt operation based on
514306c3fb27SDimitry Andric   /// CodeGenOpts.
514406c3fb27SDimitry Andric   void SetDivFPAccuracy(llvm::Value *Val);
514506c3fb27SDimitry Andric 
51465ffd83dbSDimitry Andric   /// Set the codegen fast-math flags.
51475ffd83dbSDimitry Andric   void SetFastMathFlags(FPOptions FPFeatures);
51485ffd83dbSDimitry Andric 
514981ad6265SDimitry Andric   // Truncate or extend a boolean vector to the requested number of elements.
515081ad6265SDimitry Andric   llvm::Value *emitBoolVecConversion(llvm::Value *SrcVec,
515181ad6265SDimitry Andric                                      unsigned NumElementsDst,
515281ad6265SDimitry Andric                                      const llvm::Twine &Name = "");
51530fca6ea1SDimitry Andric   // Adds a convergence_ctrl token to |Input| and emits the required parent
51540fca6ea1SDimitry Andric   // convergence instructions.
51550fca6ea1SDimitry Andric   template <typename CallType>
51560fca6ea1SDimitry Andric   CallType *addControlledConvergenceToken(CallType *Input) {
51570fca6ea1SDimitry Andric     return cast<CallType>(
51580fca6ea1SDimitry Andric         addConvergenceControlToken(Input, ConvergenceTokenStack.back()));
51590fca6ea1SDimitry Andric   }
51600fca6ea1SDimitry Andric 
51610fca6ea1SDimitry Andric private:
51620fca6ea1SDimitry Andric   // Emits a convergence_loop instruction for the given |BB|, with |ParentToken|
51630fca6ea1SDimitry Andric   // as it's parent convergence instr.
51640fca6ea1SDimitry Andric   llvm::IntrinsicInst *emitConvergenceLoopToken(llvm::BasicBlock *BB,
51650fca6ea1SDimitry Andric                                                 llvm::Value *ParentToken);
51660fca6ea1SDimitry Andric   // Adds a convergence_ctrl token with |ParentToken| as parent convergence
51670fca6ea1SDimitry Andric   // instr to the call |Input|.
51680fca6ea1SDimitry Andric   llvm::CallBase *addConvergenceControlToken(llvm::CallBase *Input,
51690fca6ea1SDimitry Andric                                              llvm::Value *ParentToken);
51700fca6ea1SDimitry Andric   // Find the convergence_entry instruction |F|, or emits ones if none exists.
51710fca6ea1SDimitry Andric   // Returns the convergence instruction.
51720fca6ea1SDimitry Andric   llvm::IntrinsicInst *getOrEmitConvergenceEntryToken(llvm::Function *F);
51730fca6ea1SDimitry Andric   // Find the convergence_loop instruction for the loop defined by |LI|, or
51740fca6ea1SDimitry Andric   // emits one if none exists. Returns the convergence instruction.
51750fca6ea1SDimitry Andric   llvm::IntrinsicInst *getOrEmitConvergenceLoopToken(const LoopInfo *LI);
517681ad6265SDimitry Andric 
51770b57cec5SDimitry Andric private:
51780b57cec5SDimitry Andric   llvm::MDNode *getRangeForLoadFromType(QualType Ty);
51790b57cec5SDimitry Andric   void EmitReturnOfRValue(RValue RV, QualType Ty);
51800b57cec5SDimitry Andric 
51810b57cec5SDimitry Andric   void deferPlaceholderReplacement(llvm::Instruction *Old, llvm::Value *New);
51820b57cec5SDimitry Andric 
5183fe6060f1SDimitry Andric   llvm::SmallVector<std::pair<llvm::WeakTrackingVH, llvm::Value *>, 4>
51840b57cec5SDimitry Andric       DeferredReplacements;
51850b57cec5SDimitry Andric 
51860b57cec5SDimitry Andric   /// Set the address of a local variable.
51870b57cec5SDimitry Andric   void setAddrOfLocalVar(const VarDecl *VD, Address Addr) {
51880b57cec5SDimitry Andric     assert(!LocalDeclMap.count(VD) && "Decl already exists in LocalDeclMap!");
51890b57cec5SDimitry Andric     LocalDeclMap.insert({VD, Addr});
51900b57cec5SDimitry Andric   }
51910b57cec5SDimitry Andric 
51920b57cec5SDimitry Andric   /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty
51930b57cec5SDimitry Andric   /// from function arguments into \arg Dst. See ABIArgInfo::Expand.
51940b57cec5SDimitry Andric   ///
51950b57cec5SDimitry Andric   /// \param AI - The first function argument of the expansion.
51960b57cec5SDimitry Andric   void ExpandTypeFromArgs(QualType Ty, LValue Dst,
51975ffd83dbSDimitry Andric                           llvm::Function::arg_iterator &AI);
51980b57cec5SDimitry Andric 
51990b57cec5SDimitry Andric   /// ExpandTypeToArgs - Expand an CallArg \arg Arg, with the LLVM type for \arg
52000b57cec5SDimitry Andric   /// Ty, into individual arguments on the provided vector \arg IRCallArgs,
52010b57cec5SDimitry Andric   /// starting at index \arg IRCallArgPos. See ABIArgInfo::Expand.
52020b57cec5SDimitry Andric   void ExpandTypeToArgs(QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy,
52030b57cec5SDimitry Andric                         SmallVectorImpl<llvm::Value *> &IRCallArgs,
52040b57cec5SDimitry Andric                         unsigned &IRCallArgPos);
52050b57cec5SDimitry Andric 
520604eeddc0SDimitry Andric   std::pair<llvm::Value *, llvm::Type *>
520704eeddc0SDimitry Andric   EmitAsmInput(const TargetInfo::ConstraintInfo &Info, const Expr *InputExpr,
520804eeddc0SDimitry Andric                std::string &ConstraintStr);
52090b57cec5SDimitry Andric 
521004eeddc0SDimitry Andric   std::pair<llvm::Value *, llvm::Type *>
521104eeddc0SDimitry Andric   EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, LValue InputValue,
521204eeddc0SDimitry Andric                      QualType InputType, std::string &ConstraintStr,
52130b57cec5SDimitry Andric                      SourceLocation Loc);
52140b57cec5SDimitry Andric 
52150b57cec5SDimitry Andric   /// Attempts to statically evaluate the object size of E. If that
52160b57cec5SDimitry Andric   /// fails, emits code to figure the size of E out for us. This is
52170b57cec5SDimitry Andric   /// pass_object_size aware.
52180b57cec5SDimitry Andric   ///
52190b57cec5SDimitry Andric   /// If EmittedExpr is non-null, this will use that instead of re-emitting E.
52200b57cec5SDimitry Andric   llvm::Value *evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
52210b57cec5SDimitry Andric                                                llvm::IntegerType *ResType,
52220b57cec5SDimitry Andric                                                llvm::Value *EmittedE,
52230b57cec5SDimitry Andric                                                bool IsDynamic);
52240b57cec5SDimitry Andric 
52250b57cec5SDimitry Andric   /// Emits the size of E, as required by __builtin_object_size. This
52260b57cec5SDimitry Andric   /// function is aware of pass_object_size parameters, and will act accordingly
52270b57cec5SDimitry Andric   /// if E is a parameter with the pass_object_size attribute.
52280b57cec5SDimitry Andric   llvm::Value *emitBuiltinObjectSize(const Expr *E, unsigned Type,
52290b57cec5SDimitry Andric                                      llvm::IntegerType *ResType,
52300b57cec5SDimitry Andric                                      llvm::Value *EmittedE,
52310b57cec5SDimitry Andric                                      bool IsDynamic);
52320b57cec5SDimitry Andric 
5233297eecfbSDimitry Andric   llvm::Value *emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
5234297eecfbSDimitry Andric                                            llvm::IntegerType *ResType);
5235297eecfbSDimitry Andric 
52360b57cec5SDimitry Andric   void emitZeroOrPatternForAutoVarInit(QualType type, const VarDecl &D,
52370b57cec5SDimitry Andric                                        Address Loc);
52380b57cec5SDimitry Andric 
52390b57cec5SDimitry Andric public:
52400b57cec5SDimitry Andric   enum class EvaluationOrder {
52410b57cec5SDimitry Andric     ///! No language constraints on evaluation order.
52420b57cec5SDimitry Andric     Default,
52430b57cec5SDimitry Andric     ///! Language semantics require left-to-right evaluation.
52440b57cec5SDimitry Andric     ForceLeftToRight,
52450b57cec5SDimitry Andric     ///! Language semantics require right-to-left evaluation.
52460b57cec5SDimitry Andric     ForceRightToLeft
52470b57cec5SDimitry Andric   };
52480b57cec5SDimitry Andric 
5249e8d8bef9SDimitry Andric   // Wrapper for function prototype sources. Wraps either a FunctionProtoType or
5250e8d8bef9SDimitry Andric   // an ObjCMethodDecl.
5251e8d8bef9SDimitry Andric   struct PrototypeWrapper {
5252e8d8bef9SDimitry Andric     llvm::PointerUnion<const FunctionProtoType *, const ObjCMethodDecl *> P;
52530b57cec5SDimitry Andric 
5254e8d8bef9SDimitry Andric     PrototypeWrapper(const FunctionProtoType *FT) : P(FT) {}
5255e8d8bef9SDimitry Andric     PrototypeWrapper(const ObjCMethodDecl *MD) : P(MD) {}
5256e8d8bef9SDimitry Andric   };
52570b57cec5SDimitry Andric 
5258e8d8bef9SDimitry Andric   void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype,
52590b57cec5SDimitry Andric                     llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
52600b57cec5SDimitry Andric                     AbstractCallee AC = AbstractCallee(),
52610b57cec5SDimitry Andric                     unsigned ParamsToSkip = 0,
52620b57cec5SDimitry Andric                     EvaluationOrder Order = EvaluationOrder::Default);
52630b57cec5SDimitry Andric 
52640b57cec5SDimitry Andric   /// EmitPointerWithAlignment - Given an expression with a pointer type,
52650b57cec5SDimitry Andric   /// emit the value and compute our best estimate of the alignment of the
52660b57cec5SDimitry Andric   /// pointee.
52670b57cec5SDimitry Andric   ///
52680b57cec5SDimitry Andric   /// \param BaseInfo - If non-null, this will be initialized with
52690b57cec5SDimitry Andric   /// information about the source of the alignment and the may-alias
52700b57cec5SDimitry Andric   /// attribute.  Note that this function will conservatively fall back on
52710b57cec5SDimitry Andric   /// the type when it doesn't recognize the expression and may-alias will
52720b57cec5SDimitry Andric   /// be set to false.
52730b57cec5SDimitry Andric   ///
52740b57cec5SDimitry Andric   /// One reasonable way to use this information is when there's a language
52750b57cec5SDimitry Andric   /// guarantee that the pointer must be aligned to some stricter value, and
52760b57cec5SDimitry Andric   /// we're simply trying to ensure that sufficiently obvious uses of under-
52770b57cec5SDimitry Andric   /// aligned objects don't get miscompiled; for example, a placement new
52780b57cec5SDimitry Andric   /// into the address of a local variable.  In such a case, it's quite
52790b57cec5SDimitry Andric   /// reasonable to just ignore the returned alignment when it isn't from an
52800b57cec5SDimitry Andric   /// explicit source.
528106c3fb27SDimitry Andric   Address
528206c3fb27SDimitry Andric   EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo = nullptr,
528306c3fb27SDimitry Andric                            TBAAAccessInfo *TBAAInfo = nullptr,
528406c3fb27SDimitry Andric                            KnownNonNull_t IsKnownNonNull = NotKnownNonNull);
52850b57cec5SDimitry Andric 
52860b57cec5SDimitry Andric   /// If \p E references a parameter with pass_object_size info or a constant
52870b57cec5SDimitry Andric   /// array size modifier, emit the object size divided by the size of \p EltTy.
52880b57cec5SDimitry Andric   /// Otherwise return null.
52890b57cec5SDimitry Andric   llvm::Value *LoadPassedObjectSize(const Expr *E, QualType EltTy);
52900b57cec5SDimitry Andric 
52910b57cec5SDimitry Andric   void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK);
52920b57cec5SDimitry Andric 
52930b57cec5SDimitry Andric   struct MultiVersionResolverOption {
52940b57cec5SDimitry Andric     llvm::Function *Function;
52950b57cec5SDimitry Andric     struct Conds {
52960b57cec5SDimitry Andric       StringRef Architecture;
52970b57cec5SDimitry Andric       llvm::SmallVector<StringRef, 8> Features;
52980b57cec5SDimitry Andric 
52990b57cec5SDimitry Andric       Conds(StringRef Arch, ArrayRef<StringRef> Feats)
53000b57cec5SDimitry Andric           : Architecture(Arch), Features(Feats.begin(), Feats.end()) {}
53010b57cec5SDimitry Andric     } Conditions;
53020b57cec5SDimitry Andric 
53030b57cec5SDimitry Andric     MultiVersionResolverOption(llvm::Function *F, StringRef Arch,
53040b57cec5SDimitry Andric                                ArrayRef<StringRef> Feats)
53050b57cec5SDimitry Andric         : Function(F), Conditions(Arch, Feats) {}
53060b57cec5SDimitry Andric   };
53070b57cec5SDimitry Andric 
53080b57cec5SDimitry Andric   // Emits the body of a multiversion function's resolver. Assumes that the
53090b57cec5SDimitry Andric   // options are already sorted in the proper order, with the 'default' option
53100b57cec5SDimitry Andric   // last (if it exists).
53110b57cec5SDimitry Andric   void EmitMultiVersionResolver(llvm::Function *Resolver,
53120b57cec5SDimitry Andric                                 ArrayRef<MultiVersionResolverOption> Options);
5313bdd1243dSDimitry Andric   void
5314bdd1243dSDimitry Andric   EmitX86MultiVersionResolver(llvm::Function *Resolver,
5315bdd1243dSDimitry Andric                               ArrayRef<MultiVersionResolverOption> Options);
5316bdd1243dSDimitry Andric   void
5317bdd1243dSDimitry Andric   EmitAArch64MultiVersionResolver(llvm::Function *Resolver,
5318bdd1243dSDimitry Andric                                   ArrayRef<MultiVersionResolverOption> Options);
53190b57cec5SDimitry Andric 
53200b57cec5SDimitry Andric private:
53210b57cec5SDimitry Andric   QualType getVarArgType(const Expr *Arg);
53220b57cec5SDimitry Andric 
53230b57cec5SDimitry Andric   void EmitDeclMetadata();
53240b57cec5SDimitry Andric 
53250b57cec5SDimitry Andric   BlockByrefHelpers *buildByrefHelpers(llvm::StructType &byrefType,
53260b57cec5SDimitry Andric                                   const AutoVarEmission &emission);
53270b57cec5SDimitry Andric 
53280b57cec5SDimitry Andric   void AddObjCARCExceptionMetadata(llvm::Instruction *Inst);
53290b57cec5SDimitry Andric 
53300b57cec5SDimitry Andric   llvm::Value *GetValueForARMHint(unsigned BuiltinID);
53310b57cec5SDimitry Andric   llvm::Value *EmitX86CpuIs(const CallExpr *E);
53320b57cec5SDimitry Andric   llvm::Value *EmitX86CpuIs(StringRef CPUStr);
53330b57cec5SDimitry Andric   llvm::Value *EmitX86CpuSupports(const CallExpr *E);
53340b57cec5SDimitry Andric   llvm::Value *EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs);
53355f757f3fSDimitry Andric   llvm::Value *EmitX86CpuSupports(std::array<uint32_t, 4> FeatureMask);
53360b57cec5SDimitry Andric   llvm::Value *EmitX86CpuInit();
5337bdd1243dSDimitry Andric   llvm::Value *FormX86ResolverCondition(const MultiVersionResolverOption &RO);
5338bdd1243dSDimitry Andric   llvm::Value *EmitAArch64CpuInit();
5339bdd1243dSDimitry Andric   llvm::Value *
5340bdd1243dSDimitry Andric   FormAArch64ResolverCondition(const MultiVersionResolverOption &RO);
53410fca6ea1SDimitry Andric   llvm::Value *EmitAArch64CpuSupports(const CallExpr *E);
5342bdd1243dSDimitry Andric   llvm::Value *EmitAArch64CpuSupports(ArrayRef<StringRef> FeatureStrs);
53430b57cec5SDimitry Andric };
53440b57cec5SDimitry Andric 
53450b57cec5SDimitry Andric inline DominatingLLVMValue::saved_type
53460b57cec5SDimitry Andric DominatingLLVMValue::save(CodeGenFunction &CGF, llvm::Value *value) {
53470b57cec5SDimitry Andric   if (!needsSaving(value)) return saved_type(value, false);
53480b57cec5SDimitry Andric 
53490b57cec5SDimitry Andric   // Otherwise, we need an alloca.
53500b57cec5SDimitry Andric   auto align = CharUnits::fromQuantity(
5351bdd1243dSDimitry Andric       CGF.CGM.getDataLayout().getPrefTypeAlign(value->getType()));
53520b57cec5SDimitry Andric   Address alloca =
53530b57cec5SDimitry Andric       CGF.CreateTempAlloca(value->getType(), align, "cond-cleanup.save");
53540b57cec5SDimitry Andric   CGF.Builder.CreateStore(value, alloca);
53550b57cec5SDimitry Andric 
53560fca6ea1SDimitry Andric   return saved_type(alloca.emitRawPointer(CGF), true);
53570b57cec5SDimitry Andric }
53580b57cec5SDimitry Andric 
53590b57cec5SDimitry Andric inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF,
53600b57cec5SDimitry Andric                                                  saved_type value) {
53610b57cec5SDimitry Andric   // If the value says it wasn't saved, trust that it's still dominating.
53620b57cec5SDimitry Andric   if (!value.getInt()) return value.getPointer();
53630b57cec5SDimitry Andric 
53640b57cec5SDimitry Andric   // Otherwise, it should be an alloca instruction, as set up in save().
53650b57cec5SDimitry Andric   auto alloca = cast<llvm::AllocaInst>(value.getPointer());
5366fe6060f1SDimitry Andric   return CGF.Builder.CreateAlignedLoad(alloca->getAllocatedType(), alloca,
5367fe6060f1SDimitry Andric                                        alloca->getAlign());
53680b57cec5SDimitry Andric }
53690b57cec5SDimitry Andric 
53700b57cec5SDimitry Andric }  // end namespace CodeGen
53715ffd83dbSDimitry Andric 
53725ffd83dbSDimitry Andric // Map the LangOption for floating point exception behavior into
53735ffd83dbSDimitry Andric // the corresponding enum in the IR.
53745ffd83dbSDimitry Andric llvm::fp::ExceptionBehavior
53755ffd83dbSDimitry Andric ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind);
53760b57cec5SDimitry Andric }  // end namespace clang
53770b57cec5SDimitry Andric 
53780b57cec5SDimitry Andric #endif
5379