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