17330f729Sjoerg //===-- CodeGenFunction.h - Per-Function state for LLVM CodeGen -*- C++ -*-===// 27330f729Sjoerg // 37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information. 57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67330f729Sjoerg // 77330f729Sjoerg //===----------------------------------------------------------------------===// 87330f729Sjoerg // 97330f729Sjoerg // This is the internal per-function state used for llvm translation. 107330f729Sjoerg // 117330f729Sjoerg //===----------------------------------------------------------------------===// 127330f729Sjoerg 137330f729Sjoerg #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENFUNCTION_H 147330f729Sjoerg #define LLVM_CLANG_LIB_CODEGEN_CODEGENFUNCTION_H 157330f729Sjoerg 167330f729Sjoerg #include "CGBuilder.h" 177330f729Sjoerg #include "CGDebugInfo.h" 187330f729Sjoerg #include "CGLoopInfo.h" 197330f729Sjoerg #include "CGValue.h" 207330f729Sjoerg #include "CodeGenModule.h" 217330f729Sjoerg #include "CodeGenPGO.h" 227330f729Sjoerg #include "EHScopeStack.h" 237330f729Sjoerg #include "VarBypassDetector.h" 247330f729Sjoerg #include "clang/AST/CharUnits.h" 257330f729Sjoerg #include "clang/AST/CurrentSourceLocExprScope.h" 267330f729Sjoerg #include "clang/AST/ExprCXX.h" 277330f729Sjoerg #include "clang/AST/ExprObjC.h" 287330f729Sjoerg #include "clang/AST/ExprOpenMP.h" 29*e038c9c4Sjoerg #include "clang/AST/StmtOpenMP.h" 307330f729Sjoerg #include "clang/AST/Type.h" 317330f729Sjoerg #include "clang/Basic/ABI.h" 327330f729Sjoerg #include "clang/Basic/CapturedStmt.h" 337330f729Sjoerg #include "clang/Basic/CodeGenOptions.h" 347330f729Sjoerg #include "clang/Basic/OpenMPKinds.h" 357330f729Sjoerg #include "clang/Basic/TargetInfo.h" 367330f729Sjoerg #include "llvm/ADT/ArrayRef.h" 377330f729Sjoerg #include "llvm/ADT/DenseMap.h" 387330f729Sjoerg #include "llvm/ADT/MapVector.h" 397330f729Sjoerg #include "llvm/ADT/SmallVector.h" 40*e038c9c4Sjoerg #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" 417330f729Sjoerg #include "llvm/IR/ValueHandle.h" 427330f729Sjoerg #include "llvm/Support/Debug.h" 437330f729Sjoerg #include "llvm/Transforms/Utils/SanitizerStats.h" 447330f729Sjoerg 457330f729Sjoerg namespace llvm { 467330f729Sjoerg class BasicBlock; 477330f729Sjoerg class LLVMContext; 487330f729Sjoerg class MDNode; 497330f729Sjoerg class Module; 507330f729Sjoerg class SwitchInst; 517330f729Sjoerg class Twine; 527330f729Sjoerg class Value; 53*e038c9c4Sjoerg class CanonicalLoopInfo; 547330f729Sjoerg } 557330f729Sjoerg 567330f729Sjoerg namespace clang { 577330f729Sjoerg class ASTContext; 587330f729Sjoerg class BlockDecl; 597330f729Sjoerg class CXXDestructorDecl; 607330f729Sjoerg class CXXForRangeStmt; 617330f729Sjoerg class CXXTryStmt; 627330f729Sjoerg class Decl; 637330f729Sjoerg class LabelDecl; 647330f729Sjoerg class EnumConstantDecl; 657330f729Sjoerg class FunctionDecl; 667330f729Sjoerg class FunctionProtoType; 677330f729Sjoerg class LabelStmt; 687330f729Sjoerg class ObjCContainerDecl; 697330f729Sjoerg class ObjCInterfaceDecl; 707330f729Sjoerg class ObjCIvarDecl; 717330f729Sjoerg class ObjCMethodDecl; 727330f729Sjoerg class ObjCImplementationDecl; 737330f729Sjoerg class ObjCPropertyImplDecl; 747330f729Sjoerg class TargetInfo; 757330f729Sjoerg class VarDecl; 767330f729Sjoerg class ObjCForCollectionStmt; 777330f729Sjoerg class ObjCAtTryStmt; 787330f729Sjoerg class ObjCAtThrowStmt; 797330f729Sjoerg class ObjCAtSynchronizedStmt; 807330f729Sjoerg class ObjCAutoreleasePoolStmt; 81*e038c9c4Sjoerg class OMPUseDevicePtrClause; 82*e038c9c4Sjoerg class OMPUseDeviceAddrClause; 83*e038c9c4Sjoerg class ReturnsNonNullAttr; 84*e038c9c4Sjoerg class SVETypeFlags; 85*e038c9c4Sjoerg class OMPExecutableDirective; 867330f729Sjoerg 877330f729Sjoerg namespace analyze_os_log { 887330f729Sjoerg class OSLogBufferLayout; 897330f729Sjoerg } 907330f729Sjoerg 917330f729Sjoerg namespace CodeGen { 927330f729Sjoerg class CodeGenTypes; 937330f729Sjoerg class CGCallee; 947330f729Sjoerg class CGFunctionInfo; 957330f729Sjoerg class CGRecordLayout; 967330f729Sjoerg class CGBlockInfo; 977330f729Sjoerg class CGCXXABI; 987330f729Sjoerg class BlockByrefHelpers; 997330f729Sjoerg class BlockByrefInfo; 1007330f729Sjoerg class BlockFlags; 1017330f729Sjoerg class BlockFieldFlags; 1027330f729Sjoerg class RegionCodeGenTy; 1037330f729Sjoerg class TargetCodeGenInfo; 1047330f729Sjoerg struct OMPTaskDataTy; 1057330f729Sjoerg struct CGCoroData; 1067330f729Sjoerg 1077330f729Sjoerg /// The kind of evaluation to perform on values of a particular 1087330f729Sjoerg /// type. Basically, is the code in CGExprScalar, CGExprComplex, or 1097330f729Sjoerg /// CGExprAgg? 1107330f729Sjoerg /// 1117330f729Sjoerg /// TODO: should vectors maybe be split out into their own thing? 1127330f729Sjoerg enum TypeEvaluationKind { 1137330f729Sjoerg TEK_Scalar, 1147330f729Sjoerg TEK_Complex, 1157330f729Sjoerg TEK_Aggregate 1167330f729Sjoerg }; 1177330f729Sjoerg 1187330f729Sjoerg #define LIST_SANITIZER_CHECKS \ 1197330f729Sjoerg SANITIZER_CHECK(AddOverflow, add_overflow, 0) \ 1207330f729Sjoerg SANITIZER_CHECK(BuiltinUnreachable, builtin_unreachable, 0) \ 1217330f729Sjoerg SANITIZER_CHECK(CFICheckFail, cfi_check_fail, 0) \ 1227330f729Sjoerg SANITIZER_CHECK(DivremOverflow, divrem_overflow, 0) \ 1237330f729Sjoerg SANITIZER_CHECK(DynamicTypeCacheMiss, dynamic_type_cache_miss, 0) \ 1247330f729Sjoerg SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0) \ 1257330f729Sjoerg SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 1) \ 1267330f729Sjoerg SANITIZER_CHECK(ImplicitConversion, implicit_conversion, 0) \ 1277330f729Sjoerg SANITIZER_CHECK(InvalidBuiltin, invalid_builtin, 0) \ 128*e038c9c4Sjoerg SANITIZER_CHECK(InvalidObjCCast, invalid_objc_cast, 0) \ 1297330f729Sjoerg SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0) \ 1307330f729Sjoerg SANITIZER_CHECK(MissingReturn, missing_return, 0) \ 1317330f729Sjoerg SANITIZER_CHECK(MulOverflow, mul_overflow, 0) \ 1327330f729Sjoerg SANITIZER_CHECK(NegateOverflow, negate_overflow, 0) \ 1337330f729Sjoerg SANITIZER_CHECK(NullabilityArg, nullability_arg, 0) \ 1347330f729Sjoerg SANITIZER_CHECK(NullabilityReturn, nullability_return, 1) \ 1357330f729Sjoerg SANITIZER_CHECK(NonnullArg, nonnull_arg, 0) \ 1367330f729Sjoerg SANITIZER_CHECK(NonnullReturn, nonnull_return, 1) \ 1377330f729Sjoerg SANITIZER_CHECK(OutOfBounds, out_of_bounds, 0) \ 1387330f729Sjoerg SANITIZER_CHECK(PointerOverflow, pointer_overflow, 0) \ 1397330f729Sjoerg SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0) \ 1407330f729Sjoerg SANITIZER_CHECK(SubOverflow, sub_overflow, 0) \ 1417330f729Sjoerg SANITIZER_CHECK(TypeMismatch, type_mismatch, 1) \ 1427330f729Sjoerg SANITIZER_CHECK(AlignmentAssumption, alignment_assumption, 0) \ 1437330f729Sjoerg SANITIZER_CHECK(VLABoundNotPositive, vla_bound_not_positive, 0) 1447330f729Sjoerg 1457330f729Sjoerg enum SanitizerHandler { 1467330f729Sjoerg #define SANITIZER_CHECK(Enum, Name, Version) Enum, 1477330f729Sjoerg LIST_SANITIZER_CHECKS 1487330f729Sjoerg #undef SANITIZER_CHECK 1497330f729Sjoerg }; 1507330f729Sjoerg 1517330f729Sjoerg /// Helper class with most of the code for saving a value for a 1527330f729Sjoerg /// conditional expression cleanup. 1537330f729Sjoerg struct DominatingLLVMValue { 1547330f729Sjoerg typedef llvm::PointerIntPair<llvm::Value*, 1, bool> saved_type; 1557330f729Sjoerg 1567330f729Sjoerg /// Answer whether the given value needs extra work to be saved. needsSavingDominatingLLVMValue1577330f729Sjoerg static bool needsSaving(llvm::Value *value) { 1587330f729Sjoerg // If it's not an instruction, we don't need to save. 1597330f729Sjoerg if (!isa<llvm::Instruction>(value)) return false; 1607330f729Sjoerg 1617330f729Sjoerg // If it's an instruction in the entry block, we don't need to save. 1627330f729Sjoerg llvm::BasicBlock *block = cast<llvm::Instruction>(value)->getParent(); 1637330f729Sjoerg return (block != &block->getParent()->getEntryBlock()); 1647330f729Sjoerg } 1657330f729Sjoerg 1667330f729Sjoerg static saved_type save(CodeGenFunction &CGF, llvm::Value *value); 1677330f729Sjoerg static llvm::Value *restore(CodeGenFunction &CGF, saved_type value); 1687330f729Sjoerg }; 1697330f729Sjoerg 1707330f729Sjoerg /// A partial specialization of DominatingValue for llvm::Values that 1717330f729Sjoerg /// might be llvm::Instructions. 1727330f729Sjoerg template <class T> struct DominatingPointer<T,true> : DominatingLLVMValue { 1737330f729Sjoerg typedef T *type; 1747330f729Sjoerg static type restore(CodeGenFunction &CGF, saved_type value) { 1757330f729Sjoerg return static_cast<T*>(DominatingLLVMValue::restore(CGF, value)); 1767330f729Sjoerg } 1777330f729Sjoerg }; 1787330f729Sjoerg 1797330f729Sjoerg /// A specialization of DominatingValue for Address. 1807330f729Sjoerg template <> struct DominatingValue<Address> { 1817330f729Sjoerg typedef Address type; 1827330f729Sjoerg 1837330f729Sjoerg struct saved_type { 1847330f729Sjoerg DominatingLLVMValue::saved_type SavedValue; 1857330f729Sjoerg CharUnits Alignment; 1867330f729Sjoerg }; 1877330f729Sjoerg 1887330f729Sjoerg static bool needsSaving(type value) { 1897330f729Sjoerg return DominatingLLVMValue::needsSaving(value.getPointer()); 1907330f729Sjoerg } 1917330f729Sjoerg static saved_type save(CodeGenFunction &CGF, type value) { 1927330f729Sjoerg return { DominatingLLVMValue::save(CGF, value.getPointer()), 1937330f729Sjoerg value.getAlignment() }; 1947330f729Sjoerg } 1957330f729Sjoerg static type restore(CodeGenFunction &CGF, saved_type value) { 1967330f729Sjoerg return Address(DominatingLLVMValue::restore(CGF, value.SavedValue), 1977330f729Sjoerg value.Alignment); 1987330f729Sjoerg } 1997330f729Sjoerg }; 2007330f729Sjoerg 2017330f729Sjoerg /// A specialization of DominatingValue for RValue. 2027330f729Sjoerg template <> struct DominatingValue<RValue> { 2037330f729Sjoerg typedef RValue type; 2047330f729Sjoerg class saved_type { 2057330f729Sjoerg enum Kind { ScalarLiteral, ScalarAddress, AggregateLiteral, 2067330f729Sjoerg AggregateAddress, ComplexAddress }; 2077330f729Sjoerg 2087330f729Sjoerg llvm::Value *Value; 2097330f729Sjoerg unsigned K : 3; 2107330f729Sjoerg unsigned Align : 29; 2117330f729Sjoerg saved_type(llvm::Value *v, Kind k, unsigned a = 0) 2127330f729Sjoerg : Value(v), K(k), Align(a) {} 2137330f729Sjoerg 2147330f729Sjoerg public: 2157330f729Sjoerg static bool needsSaving(RValue value); 2167330f729Sjoerg static saved_type save(CodeGenFunction &CGF, RValue value); 2177330f729Sjoerg RValue restore(CodeGenFunction &CGF); 2187330f729Sjoerg 2197330f729Sjoerg // implementations in CGCleanup.cpp 2207330f729Sjoerg }; 2217330f729Sjoerg 2227330f729Sjoerg static bool needsSaving(type value) { 2237330f729Sjoerg return saved_type::needsSaving(value); 2247330f729Sjoerg } 2257330f729Sjoerg static saved_type save(CodeGenFunction &CGF, type value) { 2267330f729Sjoerg return saved_type::save(CGF, value); 2277330f729Sjoerg } 2287330f729Sjoerg static type restore(CodeGenFunction &CGF, saved_type value) { 2297330f729Sjoerg return value.restore(CGF); 2307330f729Sjoerg } 2317330f729Sjoerg }; 2327330f729Sjoerg 2337330f729Sjoerg /// CodeGenFunction - This class organizes the per-function state that is used 2347330f729Sjoerg /// while generating LLVM code. 2357330f729Sjoerg class CodeGenFunction : public CodeGenTypeCache { 2367330f729Sjoerg CodeGenFunction(const CodeGenFunction &) = delete; 2377330f729Sjoerg void operator=(const CodeGenFunction &) = delete; 2387330f729Sjoerg 2397330f729Sjoerg friend class CGCXXABI; 2407330f729Sjoerg public: 2417330f729Sjoerg /// A jump destination is an abstract label, branching to which may 2427330f729Sjoerg /// require a jump out through normal cleanups. 2437330f729Sjoerg struct JumpDest { 2447330f729Sjoerg JumpDest() : Block(nullptr), ScopeDepth(), Index(0) {} 2457330f729Sjoerg JumpDest(llvm::BasicBlock *Block, 2467330f729Sjoerg EHScopeStack::stable_iterator Depth, 2477330f729Sjoerg unsigned Index) 2487330f729Sjoerg : Block(Block), ScopeDepth(Depth), Index(Index) {} 2497330f729Sjoerg 2507330f729Sjoerg bool isValid() const { return Block != nullptr; } 2517330f729Sjoerg llvm::BasicBlock *getBlock() const { return Block; } 2527330f729Sjoerg EHScopeStack::stable_iterator getScopeDepth() const { return ScopeDepth; } 2537330f729Sjoerg unsigned getDestIndex() const { return Index; } 2547330f729Sjoerg 2557330f729Sjoerg // This should be used cautiously. 2567330f729Sjoerg void setScopeDepth(EHScopeStack::stable_iterator depth) { 2577330f729Sjoerg ScopeDepth = depth; 2587330f729Sjoerg } 2597330f729Sjoerg 2607330f729Sjoerg private: 2617330f729Sjoerg llvm::BasicBlock *Block; 2627330f729Sjoerg EHScopeStack::stable_iterator ScopeDepth; 2637330f729Sjoerg unsigned Index; 2647330f729Sjoerg }; 2657330f729Sjoerg 2667330f729Sjoerg CodeGenModule &CGM; // Per-module state. 2677330f729Sjoerg const TargetInfo &Target; 2687330f729Sjoerg 269*e038c9c4Sjoerg // For EH/SEH outlined funclets, this field points to parent's CGF 270*e038c9c4Sjoerg CodeGenFunction *ParentCGF = nullptr; 271*e038c9c4Sjoerg 2727330f729Sjoerg typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy; 2737330f729Sjoerg LoopInfoStack LoopStack; 2747330f729Sjoerg CGBuilderTy Builder; 2757330f729Sjoerg 2767330f729Sjoerg // Stores variables for which we can't generate correct lifetime markers 2777330f729Sjoerg // because of jumps. 2787330f729Sjoerg VarBypassDetector Bypasses; 2797330f729Sjoerg 280*e038c9c4Sjoerg /// List of recently emitted OMPCanonicalLoops. 281*e038c9c4Sjoerg /// 282*e038c9c4Sjoerg /// Since OMPCanonicalLoops are nested inside other statements (in particular 283*e038c9c4Sjoerg /// CapturedStmt generated by OMPExecutableDirective and non-perfectly nested 284*e038c9c4Sjoerg /// loops), we cannot directly call OMPEmitOMPCanonicalLoop and receive its 285*e038c9c4Sjoerg /// llvm::CanonicalLoopInfo. Instead, we call EmitStmt and any 286*e038c9c4Sjoerg /// OMPEmitOMPCanonicalLoop called by it will add its CanonicalLoopInfo to 287*e038c9c4Sjoerg /// this stack when done. Entering a new loop requires clearing this list; it 288*e038c9c4Sjoerg /// either means we start parsing a new loop nest (in which case the previous 289*e038c9c4Sjoerg /// loop nest goes out of scope) or a second loop in the same level in which 290*e038c9c4Sjoerg /// case it would be ambiguous into which of the two (or more) loops the loop 291*e038c9c4Sjoerg /// nest would extend. 292*e038c9c4Sjoerg SmallVector<llvm::CanonicalLoopInfo *, 4> OMPLoopNestStack; 293*e038c9c4Sjoerg 2947330f729Sjoerg // CodeGen lambda for loops and support for ordered clause 2957330f729Sjoerg typedef llvm::function_ref<void(CodeGenFunction &, const OMPLoopDirective &, 2967330f729Sjoerg JumpDest)> 2977330f729Sjoerg CodeGenLoopTy; 2987330f729Sjoerg typedef llvm::function_ref<void(CodeGenFunction &, SourceLocation, 2997330f729Sjoerg const unsigned, const bool)> 3007330f729Sjoerg CodeGenOrderedTy; 3017330f729Sjoerg 3027330f729Sjoerg // Codegen lambda for loop bounds in worksharing loop constructs 3037330f729Sjoerg typedef llvm::function_ref<std::pair<LValue, LValue>( 3047330f729Sjoerg CodeGenFunction &, const OMPExecutableDirective &S)> 3057330f729Sjoerg CodeGenLoopBoundsTy; 3067330f729Sjoerg 3077330f729Sjoerg // Codegen lambda for loop bounds in dispatch-based loop implementation 3087330f729Sjoerg typedef llvm::function_ref<std::pair<llvm::Value *, llvm::Value *>( 3097330f729Sjoerg CodeGenFunction &, const OMPExecutableDirective &S, Address LB, 3107330f729Sjoerg Address UB)> 3117330f729Sjoerg CodeGenDispatchBoundsTy; 3127330f729Sjoerg 3137330f729Sjoerg /// CGBuilder insert helper. This function is called after an 3147330f729Sjoerg /// instruction is created using Builder. 3157330f729Sjoerg void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, 3167330f729Sjoerg llvm::BasicBlock *BB, 3177330f729Sjoerg llvm::BasicBlock::iterator InsertPt) const; 3187330f729Sjoerg 3197330f729Sjoerg /// CurFuncDecl - Holds the Decl for the current outermost 3207330f729Sjoerg /// non-closure context. 3217330f729Sjoerg const Decl *CurFuncDecl; 3227330f729Sjoerg /// CurCodeDecl - This is the inner-most code context, which includes blocks. 3237330f729Sjoerg const Decl *CurCodeDecl; 3247330f729Sjoerg const CGFunctionInfo *CurFnInfo; 3257330f729Sjoerg QualType FnRetTy; 3267330f729Sjoerg llvm::Function *CurFn = nullptr; 3277330f729Sjoerg 328*e038c9c4Sjoerg /// Save Parameter Decl for coroutine. 329*e038c9c4Sjoerg llvm::SmallVector<const ParmVarDecl *, 4> FnArgs; 330*e038c9c4Sjoerg 3317330f729Sjoerg // Holds coroutine data if the current function is a coroutine. We use a 3327330f729Sjoerg // wrapper to manage its lifetime, so that we don't have to define CGCoroData 3337330f729Sjoerg // in this header. 3347330f729Sjoerg struct CGCoroInfo { 3357330f729Sjoerg std::unique_ptr<CGCoroData> Data; 3367330f729Sjoerg CGCoroInfo(); 3377330f729Sjoerg ~CGCoroInfo(); 3387330f729Sjoerg }; 3397330f729Sjoerg CGCoroInfo CurCoro; 3407330f729Sjoerg 3417330f729Sjoerg bool isCoroutine() const { 3427330f729Sjoerg return CurCoro.Data != nullptr; 3437330f729Sjoerg } 3447330f729Sjoerg 3457330f729Sjoerg /// CurGD - The GlobalDecl for the current function being compiled. 3467330f729Sjoerg GlobalDecl CurGD; 3477330f729Sjoerg 3487330f729Sjoerg /// PrologueCleanupDepth - The cleanup depth enclosing all the 3497330f729Sjoerg /// cleanups associated with the parameters. 3507330f729Sjoerg EHScopeStack::stable_iterator PrologueCleanupDepth; 3517330f729Sjoerg 3527330f729Sjoerg /// ReturnBlock - Unified return block. 3537330f729Sjoerg JumpDest ReturnBlock; 3547330f729Sjoerg 3557330f729Sjoerg /// ReturnValue - The temporary alloca to hold the return 3567330f729Sjoerg /// value. This is invalid iff the function has no return value. 3577330f729Sjoerg Address ReturnValue = Address::invalid(); 3587330f729Sjoerg 3597330f729Sjoerg /// ReturnValuePointer - The temporary alloca to hold a pointer to sret. 3607330f729Sjoerg /// This is invalid if sret is not in use. 3617330f729Sjoerg Address ReturnValuePointer = Address::invalid(); 3627330f729Sjoerg 363*e038c9c4Sjoerg /// If a return statement is being visited, this holds the return statment's 364*e038c9c4Sjoerg /// result expression. 365*e038c9c4Sjoerg const Expr *RetExpr = nullptr; 366*e038c9c4Sjoerg 3677330f729Sjoerg /// Return true if a label was seen in the current scope. 3687330f729Sjoerg bool hasLabelBeenSeenInCurrentScope() const { 3697330f729Sjoerg if (CurLexicalScope) 3707330f729Sjoerg return CurLexicalScope->hasLabels(); 3717330f729Sjoerg return !LabelMap.empty(); 3727330f729Sjoerg } 3737330f729Sjoerg 3747330f729Sjoerg /// AllocaInsertPoint - This is an instruction in the entry block before which 3757330f729Sjoerg /// we prefer to insert allocas. 3767330f729Sjoerg llvm::AssertingVH<llvm::Instruction> AllocaInsertPt; 3777330f729Sjoerg 3787330f729Sjoerg /// API for captured statement code generation. 3797330f729Sjoerg class CGCapturedStmtInfo { 3807330f729Sjoerg public: 3817330f729Sjoerg explicit CGCapturedStmtInfo(CapturedRegionKind K = CR_Default) 3827330f729Sjoerg : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {} 3837330f729Sjoerg explicit CGCapturedStmtInfo(const CapturedStmt &S, 3847330f729Sjoerg CapturedRegionKind K = CR_Default) 3857330f729Sjoerg : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) { 3867330f729Sjoerg 3877330f729Sjoerg RecordDecl::field_iterator Field = 3887330f729Sjoerg S.getCapturedRecordDecl()->field_begin(); 3897330f729Sjoerg for (CapturedStmt::const_capture_iterator I = S.capture_begin(), 3907330f729Sjoerg E = S.capture_end(); 3917330f729Sjoerg I != E; ++I, ++Field) { 3927330f729Sjoerg if (I->capturesThis()) 3937330f729Sjoerg CXXThisFieldDecl = *Field; 3947330f729Sjoerg else if (I->capturesVariable()) 3957330f729Sjoerg CaptureFields[I->getCapturedVar()->getCanonicalDecl()] = *Field; 3967330f729Sjoerg else if (I->capturesVariableByCopy()) 3977330f729Sjoerg CaptureFields[I->getCapturedVar()->getCanonicalDecl()] = *Field; 3987330f729Sjoerg } 3997330f729Sjoerg } 4007330f729Sjoerg 4017330f729Sjoerg virtual ~CGCapturedStmtInfo(); 4027330f729Sjoerg 4037330f729Sjoerg CapturedRegionKind getKind() const { return Kind; } 4047330f729Sjoerg 4057330f729Sjoerg virtual void setContextValue(llvm::Value *V) { ThisValue = V; } 4067330f729Sjoerg // Retrieve the value of the context parameter. 4077330f729Sjoerg virtual llvm::Value *getContextValue() const { return ThisValue; } 4087330f729Sjoerg 4097330f729Sjoerg /// Lookup the captured field decl for a variable. 4107330f729Sjoerg virtual const FieldDecl *lookup(const VarDecl *VD) const { 4117330f729Sjoerg return CaptureFields.lookup(VD->getCanonicalDecl()); 4127330f729Sjoerg } 4137330f729Sjoerg 4147330f729Sjoerg bool isCXXThisExprCaptured() const { return getThisFieldDecl() != nullptr; } 4157330f729Sjoerg virtual FieldDecl *getThisFieldDecl() const { return CXXThisFieldDecl; } 4167330f729Sjoerg 4177330f729Sjoerg static bool classof(const CGCapturedStmtInfo *) { 4187330f729Sjoerg return true; 4197330f729Sjoerg } 4207330f729Sjoerg 4217330f729Sjoerg /// Emit the captured statement body. 4227330f729Sjoerg virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S) { 4237330f729Sjoerg CGF.incrementProfileCounter(S); 4247330f729Sjoerg CGF.EmitStmt(S); 4257330f729Sjoerg } 4267330f729Sjoerg 4277330f729Sjoerg /// Get the name of the capture helper. 4287330f729Sjoerg virtual StringRef getHelperName() const { return "__captured_stmt"; } 4297330f729Sjoerg 4307330f729Sjoerg private: 4317330f729Sjoerg /// The kind of captured statement being generated. 4327330f729Sjoerg CapturedRegionKind Kind; 4337330f729Sjoerg 4347330f729Sjoerg /// Keep the map between VarDecl and FieldDecl. 4357330f729Sjoerg llvm::SmallDenseMap<const VarDecl *, FieldDecl *> CaptureFields; 4367330f729Sjoerg 4377330f729Sjoerg /// The base address of the captured record, passed in as the first 4387330f729Sjoerg /// argument of the parallel region function. 4397330f729Sjoerg llvm::Value *ThisValue; 4407330f729Sjoerg 4417330f729Sjoerg /// Captured 'this' type. 4427330f729Sjoerg FieldDecl *CXXThisFieldDecl; 4437330f729Sjoerg }; 4447330f729Sjoerg CGCapturedStmtInfo *CapturedStmtInfo = nullptr; 4457330f729Sjoerg 4467330f729Sjoerg /// RAII for correct setting/restoring of CapturedStmtInfo. 4477330f729Sjoerg class CGCapturedStmtRAII { 4487330f729Sjoerg private: 4497330f729Sjoerg CodeGenFunction &CGF; 4507330f729Sjoerg CGCapturedStmtInfo *PrevCapturedStmtInfo; 4517330f729Sjoerg public: 4527330f729Sjoerg CGCapturedStmtRAII(CodeGenFunction &CGF, 4537330f729Sjoerg CGCapturedStmtInfo *NewCapturedStmtInfo) 4547330f729Sjoerg : CGF(CGF), PrevCapturedStmtInfo(CGF.CapturedStmtInfo) { 4557330f729Sjoerg CGF.CapturedStmtInfo = NewCapturedStmtInfo; 4567330f729Sjoerg } 4577330f729Sjoerg ~CGCapturedStmtRAII() { CGF.CapturedStmtInfo = PrevCapturedStmtInfo; } 4587330f729Sjoerg }; 4597330f729Sjoerg 4607330f729Sjoerg /// An abstract representation of regular/ObjC call/message targets. 4617330f729Sjoerg class AbstractCallee { 4627330f729Sjoerg /// The function declaration of the callee. 4637330f729Sjoerg const Decl *CalleeDecl; 4647330f729Sjoerg 4657330f729Sjoerg public: 4667330f729Sjoerg AbstractCallee() : CalleeDecl(nullptr) {} 4677330f729Sjoerg AbstractCallee(const FunctionDecl *FD) : CalleeDecl(FD) {} 4687330f729Sjoerg AbstractCallee(const ObjCMethodDecl *OMD) : CalleeDecl(OMD) {} 4697330f729Sjoerg bool hasFunctionDecl() const { 4707330f729Sjoerg return dyn_cast_or_null<FunctionDecl>(CalleeDecl); 4717330f729Sjoerg } 4727330f729Sjoerg const Decl *getDecl() const { return CalleeDecl; } 4737330f729Sjoerg unsigned getNumParams() const { 4747330f729Sjoerg if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) 4757330f729Sjoerg return FD->getNumParams(); 4767330f729Sjoerg return cast<ObjCMethodDecl>(CalleeDecl)->param_size(); 4777330f729Sjoerg } 4787330f729Sjoerg const ParmVarDecl *getParamDecl(unsigned I) const { 4797330f729Sjoerg if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) 4807330f729Sjoerg return FD->getParamDecl(I); 4817330f729Sjoerg return *(cast<ObjCMethodDecl>(CalleeDecl)->param_begin() + I); 4827330f729Sjoerg } 4837330f729Sjoerg }; 4847330f729Sjoerg 4857330f729Sjoerg /// Sanitizers enabled for this function. 4867330f729Sjoerg SanitizerSet SanOpts; 4877330f729Sjoerg 4887330f729Sjoerg /// True if CodeGen currently emits code implementing sanitizer checks. 4897330f729Sjoerg bool IsSanitizerScope = false; 4907330f729Sjoerg 4917330f729Sjoerg /// RAII object to set/unset CodeGenFunction::IsSanitizerScope. 4927330f729Sjoerg class SanitizerScope { 4937330f729Sjoerg CodeGenFunction *CGF; 4947330f729Sjoerg public: 4957330f729Sjoerg SanitizerScope(CodeGenFunction *CGF); 4967330f729Sjoerg ~SanitizerScope(); 4977330f729Sjoerg }; 4987330f729Sjoerg 4997330f729Sjoerg /// In C++, whether we are code generating a thunk. This controls whether we 5007330f729Sjoerg /// should emit cleanups. 5017330f729Sjoerg bool CurFuncIsThunk = false; 5027330f729Sjoerg 5037330f729Sjoerg /// In ARC, whether we should autorelease the return value. 5047330f729Sjoerg bool AutoreleaseResult = false; 5057330f729Sjoerg 5067330f729Sjoerg /// Whether we processed a Microsoft-style asm block during CodeGen. These can 5077330f729Sjoerg /// potentially set the return value. 5087330f729Sjoerg bool SawAsmBlock = false; 5097330f729Sjoerg 5107330f729Sjoerg const NamedDecl *CurSEHParent = nullptr; 5117330f729Sjoerg 5127330f729Sjoerg /// True if the current function is an outlined SEH helper. This can be a 5137330f729Sjoerg /// finally block or filter expression. 5147330f729Sjoerg bool IsOutlinedSEHHelper = false; 5157330f729Sjoerg 5167330f729Sjoerg /// True if CodeGen currently emits code inside presereved access index 5177330f729Sjoerg /// region. 5187330f729Sjoerg bool IsInPreservedAIRegion = false; 5197330f729Sjoerg 520*e038c9c4Sjoerg /// True if the current statement has nomerge attribute. 521*e038c9c4Sjoerg bool InNoMergeAttributedStmt = false; 522*e038c9c4Sjoerg 523*e038c9c4Sjoerg // The CallExpr within the current statement that the musttail attribute 524*e038c9c4Sjoerg // applies to. nullptr if there is no 'musttail' on the current statement. 525*e038c9c4Sjoerg const CallExpr *MustTailCall = nullptr; 526*e038c9c4Sjoerg 527*e038c9c4Sjoerg /// Returns true if a function must make progress, which means the 528*e038c9c4Sjoerg /// mustprogress attribute can be added. 529*e038c9c4Sjoerg bool checkIfFunctionMustProgress() { 530*e038c9c4Sjoerg if (CGM.getCodeGenOpts().getFiniteLoops() == 531*e038c9c4Sjoerg CodeGenOptions::FiniteLoopsKind::Never) 532*e038c9c4Sjoerg return false; 533*e038c9c4Sjoerg 534*e038c9c4Sjoerg // C++11 and later guarantees that a thread eventually will do one of the 535*e038c9c4Sjoerg // following (6.9.2.3.1 in C++11): 536*e038c9c4Sjoerg // - terminate, 537*e038c9c4Sjoerg // - make a call to a library I/O function, 538*e038c9c4Sjoerg // - perform an access through a volatile glvalue, or 539*e038c9c4Sjoerg // - perform a synchronization operation or an atomic operation. 540*e038c9c4Sjoerg // 541*e038c9c4Sjoerg // Hence each function is 'mustprogress' in C++11 or later. 542*e038c9c4Sjoerg return getLangOpts().CPlusPlus11; 543*e038c9c4Sjoerg } 544*e038c9c4Sjoerg 545*e038c9c4Sjoerg /// Returns true if a loop must make progress, which means the mustprogress 546*e038c9c4Sjoerg /// attribute can be added. \p HasConstantCond indicates whether the branch 547*e038c9c4Sjoerg /// condition is a known constant. 548*e038c9c4Sjoerg bool checkIfLoopMustProgress(bool HasConstantCond) { 549*e038c9c4Sjoerg if (CGM.getCodeGenOpts().getFiniteLoops() == 550*e038c9c4Sjoerg CodeGenOptions::FiniteLoopsKind::Always) 551*e038c9c4Sjoerg return true; 552*e038c9c4Sjoerg if (CGM.getCodeGenOpts().getFiniteLoops() == 553*e038c9c4Sjoerg CodeGenOptions::FiniteLoopsKind::Never) 554*e038c9c4Sjoerg return false; 555*e038c9c4Sjoerg 556*e038c9c4Sjoerg // If the containing function must make progress, loops also must make 557*e038c9c4Sjoerg // progress (as in C++11 and later). 558*e038c9c4Sjoerg if (checkIfFunctionMustProgress()) 559*e038c9c4Sjoerg return true; 560*e038c9c4Sjoerg 561*e038c9c4Sjoerg // Now apply rules for plain C (see 6.8.5.6 in C11). 562*e038c9c4Sjoerg // Loops with constant conditions do not have to make progress in any C 563*e038c9c4Sjoerg // version. 564*e038c9c4Sjoerg if (HasConstantCond) 565*e038c9c4Sjoerg return false; 566*e038c9c4Sjoerg 567*e038c9c4Sjoerg // Loops with non-constant conditions must make progress in C11 and later. 568*e038c9c4Sjoerg return getLangOpts().C11; 569*e038c9c4Sjoerg } 570*e038c9c4Sjoerg 5717330f729Sjoerg const CodeGen::CGBlockInfo *BlockInfo = nullptr; 5727330f729Sjoerg llvm::Value *BlockPointer = nullptr; 5737330f729Sjoerg 5747330f729Sjoerg llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields; 5757330f729Sjoerg FieldDecl *LambdaThisCaptureField = nullptr; 5767330f729Sjoerg 5777330f729Sjoerg /// A mapping from NRVO variables to the flags used to indicate 5787330f729Sjoerg /// when the NRVO has been applied to this variable. 5797330f729Sjoerg llvm::DenseMap<const VarDecl *, llvm::Value *> NRVOFlags; 5807330f729Sjoerg 5817330f729Sjoerg EHScopeStack EHStack; 5827330f729Sjoerg llvm::SmallVector<char, 256> LifetimeExtendedCleanupStack; 5837330f729Sjoerg llvm::SmallVector<const JumpDest *, 2> SEHTryEpilogueStack; 5847330f729Sjoerg 5857330f729Sjoerg llvm::Instruction *CurrentFuncletPad = nullptr; 5867330f729Sjoerg 5877330f729Sjoerg class CallLifetimeEnd final : public EHScopeStack::Cleanup { 588*e038c9c4Sjoerg bool isRedundantBeforeReturn() override { return true; } 589*e038c9c4Sjoerg 5907330f729Sjoerg llvm::Value *Addr; 5917330f729Sjoerg llvm::Value *Size; 5927330f729Sjoerg 5937330f729Sjoerg public: 5947330f729Sjoerg CallLifetimeEnd(Address addr, llvm::Value *size) 5957330f729Sjoerg : Addr(addr.getPointer()), Size(size) {} 5967330f729Sjoerg 5977330f729Sjoerg void Emit(CodeGenFunction &CGF, Flags flags) override { 5987330f729Sjoerg CGF.EmitLifetimeEnd(Size, Addr); 5997330f729Sjoerg } 6007330f729Sjoerg }; 6017330f729Sjoerg 6027330f729Sjoerg /// Header for data within LifetimeExtendedCleanupStack. 6037330f729Sjoerg struct LifetimeExtendedCleanupHeader { 6047330f729Sjoerg /// The size of the following cleanup object. 6057330f729Sjoerg unsigned Size; 6067330f729Sjoerg /// The kind of cleanup to push: a value from the CleanupKind enumeration. 6077330f729Sjoerg unsigned Kind : 31; 6087330f729Sjoerg /// Whether this is a conditional cleanup. 6097330f729Sjoerg unsigned IsConditional : 1; 6107330f729Sjoerg 6117330f729Sjoerg size_t getSize() const { return Size; } 6127330f729Sjoerg CleanupKind getKind() const { return (CleanupKind)Kind; } 6137330f729Sjoerg bool isConditional() const { return IsConditional; } 6147330f729Sjoerg }; 6157330f729Sjoerg 6167330f729Sjoerg /// i32s containing the indexes of the cleanup destinations. 6177330f729Sjoerg Address NormalCleanupDest = Address::invalid(); 6187330f729Sjoerg 6197330f729Sjoerg unsigned NextCleanupDestIndex = 1; 6207330f729Sjoerg 6217330f729Sjoerg /// EHResumeBlock - Unified block containing a call to llvm.eh.resume. 6227330f729Sjoerg llvm::BasicBlock *EHResumeBlock = nullptr; 6237330f729Sjoerg 6247330f729Sjoerg /// The exception slot. All landing pads write the current exception pointer 6257330f729Sjoerg /// into this alloca. 6267330f729Sjoerg llvm::Value *ExceptionSlot = nullptr; 6277330f729Sjoerg 6287330f729Sjoerg /// The selector slot. Under the MandatoryCleanup model, all landing pads 6297330f729Sjoerg /// write the current selector value into this alloca. 6307330f729Sjoerg llvm::AllocaInst *EHSelectorSlot = nullptr; 6317330f729Sjoerg 6327330f729Sjoerg /// A stack of exception code slots. Entering an __except block pushes a slot 6337330f729Sjoerg /// on the stack and leaving pops one. The __exception_code() intrinsic loads 6347330f729Sjoerg /// a value from the top of the stack. 6357330f729Sjoerg SmallVector<Address, 1> SEHCodeSlotStack; 6367330f729Sjoerg 6377330f729Sjoerg /// Value returned by __exception_info intrinsic. 6387330f729Sjoerg llvm::Value *SEHInfo = nullptr; 6397330f729Sjoerg 6407330f729Sjoerg /// Emits a landing pad for the current EH stack. 6417330f729Sjoerg llvm::BasicBlock *EmitLandingPad(); 6427330f729Sjoerg 6437330f729Sjoerg llvm::BasicBlock *getInvokeDestImpl(); 6447330f729Sjoerg 645*e038c9c4Sjoerg /// Parent loop-based directive for scan directive. 646*e038c9c4Sjoerg const OMPExecutableDirective *OMPParentLoopDirectiveForScan = nullptr; 647*e038c9c4Sjoerg llvm::BasicBlock *OMPBeforeScanBlock = nullptr; 648*e038c9c4Sjoerg llvm::BasicBlock *OMPAfterScanBlock = nullptr; 649*e038c9c4Sjoerg llvm::BasicBlock *OMPScanExitBlock = nullptr; 650*e038c9c4Sjoerg llvm::BasicBlock *OMPScanDispatch = nullptr; 651*e038c9c4Sjoerg bool OMPFirstScanLoop = false; 652*e038c9c4Sjoerg 653*e038c9c4Sjoerg /// Manages parent directive for scan directives. 654*e038c9c4Sjoerg class ParentLoopDirectiveForScanRegion { 655*e038c9c4Sjoerg CodeGenFunction &CGF; 656*e038c9c4Sjoerg const OMPExecutableDirective *ParentLoopDirectiveForScan; 657*e038c9c4Sjoerg 658*e038c9c4Sjoerg public: 659*e038c9c4Sjoerg ParentLoopDirectiveForScanRegion( 660*e038c9c4Sjoerg CodeGenFunction &CGF, 661*e038c9c4Sjoerg const OMPExecutableDirective &ParentLoopDirectiveForScan) 662*e038c9c4Sjoerg : CGF(CGF), 663*e038c9c4Sjoerg ParentLoopDirectiveForScan(CGF.OMPParentLoopDirectiveForScan) { 664*e038c9c4Sjoerg CGF.OMPParentLoopDirectiveForScan = &ParentLoopDirectiveForScan; 665*e038c9c4Sjoerg } 666*e038c9c4Sjoerg ~ParentLoopDirectiveForScanRegion() { 667*e038c9c4Sjoerg CGF.OMPParentLoopDirectiveForScan = ParentLoopDirectiveForScan; 668*e038c9c4Sjoerg } 669*e038c9c4Sjoerg }; 670*e038c9c4Sjoerg 6717330f729Sjoerg template <class T> 6727330f729Sjoerg typename DominatingValue<T>::saved_type saveValueInCond(T value) { 6737330f729Sjoerg return DominatingValue<T>::save(*this, value); 6747330f729Sjoerg } 6757330f729Sjoerg 676*e038c9c4Sjoerg class CGFPOptionsRAII { 677*e038c9c4Sjoerg public: 678*e038c9c4Sjoerg CGFPOptionsRAII(CodeGenFunction &CGF, FPOptions FPFeatures); 679*e038c9c4Sjoerg CGFPOptionsRAII(CodeGenFunction &CGF, const Expr *E); 680*e038c9c4Sjoerg ~CGFPOptionsRAII(); 681*e038c9c4Sjoerg 682*e038c9c4Sjoerg private: 683*e038c9c4Sjoerg void ConstructorHelper(FPOptions FPFeatures); 684*e038c9c4Sjoerg CodeGenFunction &CGF; 685*e038c9c4Sjoerg FPOptions OldFPFeatures; 686*e038c9c4Sjoerg llvm::fp::ExceptionBehavior OldExcept; 687*e038c9c4Sjoerg llvm::RoundingMode OldRounding; 688*e038c9c4Sjoerg Optional<CGBuilderTy::FastMathFlagGuard> FMFGuard; 689*e038c9c4Sjoerg }; 690*e038c9c4Sjoerg FPOptions CurFPFeatures; 691*e038c9c4Sjoerg 6927330f729Sjoerg public: 6937330f729Sjoerg /// ObjCEHValueStack - Stack of Objective-C exception values, used for 6947330f729Sjoerg /// rethrows. 6957330f729Sjoerg SmallVector<llvm::Value*, 8> ObjCEHValueStack; 6967330f729Sjoerg 6977330f729Sjoerg /// A class controlling the emission of a finally block. 6987330f729Sjoerg class FinallyInfo { 6997330f729Sjoerg /// Where the catchall's edge through the cleanup should go. 7007330f729Sjoerg JumpDest RethrowDest; 7017330f729Sjoerg 7027330f729Sjoerg /// A function to call to enter the catch. 7037330f729Sjoerg llvm::FunctionCallee BeginCatchFn; 7047330f729Sjoerg 7057330f729Sjoerg /// An i1 variable indicating whether or not the @finally is 7067330f729Sjoerg /// running for an exception. 7077330f729Sjoerg llvm::AllocaInst *ForEHVar; 7087330f729Sjoerg 7097330f729Sjoerg /// An i8* variable into which the exception pointer to rethrow 7107330f729Sjoerg /// has been saved. 7117330f729Sjoerg llvm::AllocaInst *SavedExnVar; 7127330f729Sjoerg 7137330f729Sjoerg public: 7147330f729Sjoerg void enter(CodeGenFunction &CGF, const Stmt *Finally, 7157330f729Sjoerg llvm::FunctionCallee beginCatchFn, 7167330f729Sjoerg llvm::FunctionCallee endCatchFn, llvm::FunctionCallee rethrowFn); 7177330f729Sjoerg void exit(CodeGenFunction &CGF); 7187330f729Sjoerg }; 7197330f729Sjoerg 7207330f729Sjoerg /// Returns true inside SEH __try blocks. 7217330f729Sjoerg bool isSEHTryScope() const { return !SEHTryEpilogueStack.empty(); } 7227330f729Sjoerg 7237330f729Sjoerg /// Returns true while emitting a cleanuppad. 7247330f729Sjoerg bool isCleanupPadScope() const { 7257330f729Sjoerg return CurrentFuncletPad && isa<llvm::CleanupPadInst>(CurrentFuncletPad); 7267330f729Sjoerg } 7277330f729Sjoerg 7287330f729Sjoerg /// pushFullExprCleanup - Push a cleanup to be run at the end of the 7297330f729Sjoerg /// current full-expression. Safe against the possibility that 7307330f729Sjoerg /// we're currently inside a conditionally-evaluated expression. 7317330f729Sjoerg template <class T, class... As> 7327330f729Sjoerg void pushFullExprCleanup(CleanupKind kind, As... A) { 7337330f729Sjoerg // If we're not in a conditional branch, or if none of the 7347330f729Sjoerg // arguments requires saving, then use the unconditional cleanup. 7357330f729Sjoerg if (!isInConditionalBranch()) 7367330f729Sjoerg return EHStack.pushCleanup<T>(kind, A...); 7377330f729Sjoerg 7387330f729Sjoerg // Stash values in a tuple so we can guarantee the order of saves. 7397330f729Sjoerg typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple; 7407330f729Sjoerg SavedTuple Saved{saveValueInCond(A)...}; 7417330f729Sjoerg 7427330f729Sjoerg typedef EHScopeStack::ConditionalCleanup<T, As...> CleanupType; 7437330f729Sjoerg EHStack.pushCleanupTuple<CleanupType>(kind, Saved); 7447330f729Sjoerg initFullExprCleanup(); 7457330f729Sjoerg } 7467330f729Sjoerg 747*e038c9c4Sjoerg /// Queue a cleanup to be pushed after finishing the current full-expression, 748*e038c9c4Sjoerg /// potentially with an active flag. 7497330f729Sjoerg template <class T, class... As> 7507330f729Sjoerg void pushCleanupAfterFullExpr(CleanupKind Kind, As... A) { 7517330f729Sjoerg if (!isInConditionalBranch()) 752*e038c9c4Sjoerg return pushCleanupAfterFullExprWithActiveFlag<T>(Kind, Address::invalid(), 753*e038c9c4Sjoerg A...); 7547330f729Sjoerg 7557330f729Sjoerg Address ActiveFlag = createCleanupActiveFlag(); 7567330f729Sjoerg assert(!DominatingValue<Address>::needsSaving(ActiveFlag) && 7577330f729Sjoerg "cleanup active flag should never need saving"); 7587330f729Sjoerg 7597330f729Sjoerg typedef std::tuple<typename DominatingValue<As>::saved_type...> SavedTuple; 7607330f729Sjoerg SavedTuple Saved{saveValueInCond(A)...}; 7617330f729Sjoerg 7627330f729Sjoerg typedef EHScopeStack::ConditionalCleanup<T, As...> CleanupType; 763*e038c9c4Sjoerg pushCleanupAfterFullExprWithActiveFlag<CleanupType>(Kind, ActiveFlag, Saved); 7647330f729Sjoerg } 7657330f729Sjoerg 7667330f729Sjoerg template <class T, class... As> 767*e038c9c4Sjoerg void pushCleanupAfterFullExprWithActiveFlag(CleanupKind Kind, 768*e038c9c4Sjoerg Address ActiveFlag, As... A) { 7697330f729Sjoerg LifetimeExtendedCleanupHeader Header = {sizeof(T), Kind, 7707330f729Sjoerg ActiveFlag.isValid()}; 7717330f729Sjoerg 7727330f729Sjoerg size_t OldSize = LifetimeExtendedCleanupStack.size(); 7737330f729Sjoerg LifetimeExtendedCleanupStack.resize( 7747330f729Sjoerg LifetimeExtendedCleanupStack.size() + sizeof(Header) + Header.Size + 7757330f729Sjoerg (Header.IsConditional ? sizeof(ActiveFlag) : 0)); 7767330f729Sjoerg 7777330f729Sjoerg static_assert(sizeof(Header) % alignof(T) == 0, 7787330f729Sjoerg "Cleanup will be allocated on misaligned address"); 7797330f729Sjoerg char *Buffer = &LifetimeExtendedCleanupStack[OldSize]; 7807330f729Sjoerg new (Buffer) LifetimeExtendedCleanupHeader(Header); 7817330f729Sjoerg new (Buffer + sizeof(Header)) T(A...); 7827330f729Sjoerg if (Header.IsConditional) 7837330f729Sjoerg new (Buffer + sizeof(Header) + sizeof(T)) Address(ActiveFlag); 7847330f729Sjoerg } 7857330f729Sjoerg 7867330f729Sjoerg /// Set up the last cleanup that was pushed as a conditional 7877330f729Sjoerg /// full-expression cleanup. 7887330f729Sjoerg void initFullExprCleanup() { 7897330f729Sjoerg initFullExprCleanupWithFlag(createCleanupActiveFlag()); 7907330f729Sjoerg } 7917330f729Sjoerg 7927330f729Sjoerg void initFullExprCleanupWithFlag(Address ActiveFlag); 7937330f729Sjoerg Address createCleanupActiveFlag(); 7947330f729Sjoerg 7957330f729Sjoerg /// PushDestructorCleanup - Push a cleanup to call the 7967330f729Sjoerg /// complete-object destructor of an object of the given type at the 7977330f729Sjoerg /// given address. Does nothing if T is not a C++ class type with a 7987330f729Sjoerg /// non-trivial destructor. 7997330f729Sjoerg void PushDestructorCleanup(QualType T, Address Addr); 8007330f729Sjoerg 8017330f729Sjoerg /// PushDestructorCleanup - Push a cleanup to call the 8027330f729Sjoerg /// complete-object variant of the given destructor on the object at 8037330f729Sjoerg /// the given address. 8047330f729Sjoerg void PushDestructorCleanup(const CXXDestructorDecl *Dtor, QualType T, 8057330f729Sjoerg Address Addr); 8067330f729Sjoerg 8077330f729Sjoerg /// PopCleanupBlock - Will pop the cleanup entry on the stack and 8087330f729Sjoerg /// process all branch fixups. 8097330f729Sjoerg void PopCleanupBlock(bool FallThroughIsBranchThrough = false); 8107330f729Sjoerg 8117330f729Sjoerg /// DeactivateCleanupBlock - Deactivates the given cleanup block. 8127330f729Sjoerg /// The block cannot be reactivated. Pops it if it's the top of the 8137330f729Sjoerg /// stack. 8147330f729Sjoerg /// 8157330f729Sjoerg /// \param DominatingIP - An instruction which is known to 8167330f729Sjoerg /// dominate the current IP (if set) and which lies along 8177330f729Sjoerg /// all paths of execution between the current IP and the 8187330f729Sjoerg /// the point at which the cleanup comes into scope. 8197330f729Sjoerg void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, 8207330f729Sjoerg llvm::Instruction *DominatingIP); 8217330f729Sjoerg 8227330f729Sjoerg /// ActivateCleanupBlock - Activates an initially-inactive cleanup. 8237330f729Sjoerg /// Cannot be used to resurrect a deactivated cleanup. 8247330f729Sjoerg /// 8257330f729Sjoerg /// \param DominatingIP - An instruction which is known to 8267330f729Sjoerg /// dominate the current IP (if set) and which lies along 8277330f729Sjoerg /// all paths of execution between the current IP and the 8287330f729Sjoerg /// the point at which the cleanup comes into scope. 8297330f729Sjoerg void ActivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, 8307330f729Sjoerg llvm::Instruction *DominatingIP); 8317330f729Sjoerg 8327330f729Sjoerg /// Enters a new scope for capturing cleanups, all of which 8337330f729Sjoerg /// will be executed once the scope is exited. 8347330f729Sjoerg class RunCleanupsScope { 8357330f729Sjoerg EHScopeStack::stable_iterator CleanupStackDepth, OldCleanupScopeDepth; 8367330f729Sjoerg size_t LifetimeExtendedCleanupStackSize; 8377330f729Sjoerg bool OldDidCallStackSave; 8387330f729Sjoerg protected: 8397330f729Sjoerg bool PerformCleanup; 8407330f729Sjoerg private: 8417330f729Sjoerg 8427330f729Sjoerg RunCleanupsScope(const RunCleanupsScope &) = delete; 8437330f729Sjoerg void operator=(const RunCleanupsScope &) = delete; 8447330f729Sjoerg 8457330f729Sjoerg protected: 8467330f729Sjoerg CodeGenFunction& CGF; 8477330f729Sjoerg 8487330f729Sjoerg public: 8497330f729Sjoerg /// Enter a new cleanup scope. 8507330f729Sjoerg explicit RunCleanupsScope(CodeGenFunction &CGF) 8517330f729Sjoerg : PerformCleanup(true), CGF(CGF) 8527330f729Sjoerg { 8537330f729Sjoerg CleanupStackDepth = CGF.EHStack.stable_begin(); 8547330f729Sjoerg LifetimeExtendedCleanupStackSize = 8557330f729Sjoerg CGF.LifetimeExtendedCleanupStack.size(); 8567330f729Sjoerg OldDidCallStackSave = CGF.DidCallStackSave; 8577330f729Sjoerg CGF.DidCallStackSave = false; 8587330f729Sjoerg OldCleanupScopeDepth = CGF.CurrentCleanupScopeDepth; 8597330f729Sjoerg CGF.CurrentCleanupScopeDepth = CleanupStackDepth; 8607330f729Sjoerg } 8617330f729Sjoerg 8627330f729Sjoerg /// Exit this cleanup scope, emitting any accumulated cleanups. 8637330f729Sjoerg ~RunCleanupsScope() { 8647330f729Sjoerg if (PerformCleanup) 8657330f729Sjoerg ForceCleanup(); 8667330f729Sjoerg } 8677330f729Sjoerg 8687330f729Sjoerg /// Determine whether this scope requires any cleanups. 8697330f729Sjoerg bool requiresCleanups() const { 8707330f729Sjoerg return CGF.EHStack.stable_begin() != CleanupStackDepth; 8717330f729Sjoerg } 8727330f729Sjoerg 8737330f729Sjoerg /// Force the emission of cleanups now, instead of waiting 8747330f729Sjoerg /// until this object is destroyed. 8757330f729Sjoerg /// \param ValuesToReload - A list of values that need to be available at 8767330f729Sjoerg /// the insertion point after cleanup emission. If cleanup emission created 8777330f729Sjoerg /// a shared cleanup block, these value pointers will be rewritten. 8787330f729Sjoerg /// Otherwise, they not will be modified. 8797330f729Sjoerg void ForceCleanup(std::initializer_list<llvm::Value**> ValuesToReload = {}) { 8807330f729Sjoerg assert(PerformCleanup && "Already forced cleanup"); 8817330f729Sjoerg CGF.DidCallStackSave = OldDidCallStackSave; 8827330f729Sjoerg CGF.PopCleanupBlocks(CleanupStackDepth, LifetimeExtendedCleanupStackSize, 8837330f729Sjoerg ValuesToReload); 8847330f729Sjoerg PerformCleanup = false; 8857330f729Sjoerg CGF.CurrentCleanupScopeDepth = OldCleanupScopeDepth; 8867330f729Sjoerg } 8877330f729Sjoerg }; 8887330f729Sjoerg 8897330f729Sjoerg // Cleanup stack depth of the RunCleanupsScope that was pushed most recently. 8907330f729Sjoerg EHScopeStack::stable_iterator CurrentCleanupScopeDepth = 8917330f729Sjoerg EHScopeStack::stable_end(); 8927330f729Sjoerg 8937330f729Sjoerg class LexicalScope : public RunCleanupsScope { 8947330f729Sjoerg SourceRange Range; 8957330f729Sjoerg SmallVector<const LabelDecl*, 4> Labels; 8967330f729Sjoerg LexicalScope *ParentScope; 8977330f729Sjoerg 8987330f729Sjoerg LexicalScope(const LexicalScope &) = delete; 8997330f729Sjoerg void operator=(const LexicalScope &) = delete; 9007330f729Sjoerg 9017330f729Sjoerg public: 9027330f729Sjoerg /// Enter a new cleanup scope. 9037330f729Sjoerg explicit LexicalScope(CodeGenFunction &CGF, SourceRange Range) 9047330f729Sjoerg : RunCleanupsScope(CGF), Range(Range), ParentScope(CGF.CurLexicalScope) { 9057330f729Sjoerg CGF.CurLexicalScope = this; 9067330f729Sjoerg if (CGDebugInfo *DI = CGF.getDebugInfo()) 9077330f729Sjoerg DI->EmitLexicalBlockStart(CGF.Builder, Range.getBegin()); 9087330f729Sjoerg } 9097330f729Sjoerg 9107330f729Sjoerg void addLabel(const LabelDecl *label) { 9117330f729Sjoerg assert(PerformCleanup && "adding label to dead scope?"); 9127330f729Sjoerg Labels.push_back(label); 9137330f729Sjoerg } 9147330f729Sjoerg 9157330f729Sjoerg /// Exit this cleanup scope, emitting any accumulated 9167330f729Sjoerg /// cleanups. 9177330f729Sjoerg ~LexicalScope() { 9187330f729Sjoerg if (CGDebugInfo *DI = CGF.getDebugInfo()) 9197330f729Sjoerg DI->EmitLexicalBlockEnd(CGF.Builder, Range.getEnd()); 9207330f729Sjoerg 9217330f729Sjoerg // If we should perform a cleanup, force them now. Note that 9227330f729Sjoerg // this ends the cleanup scope before rescoping any labels. 9237330f729Sjoerg if (PerformCleanup) { 9247330f729Sjoerg ApplyDebugLocation DL(CGF, Range.getEnd()); 9257330f729Sjoerg ForceCleanup(); 9267330f729Sjoerg } 9277330f729Sjoerg } 9287330f729Sjoerg 9297330f729Sjoerg /// Force the emission of cleanups now, instead of waiting 9307330f729Sjoerg /// until this object is destroyed. 9317330f729Sjoerg void ForceCleanup() { 9327330f729Sjoerg CGF.CurLexicalScope = ParentScope; 9337330f729Sjoerg RunCleanupsScope::ForceCleanup(); 9347330f729Sjoerg 9357330f729Sjoerg if (!Labels.empty()) 9367330f729Sjoerg rescopeLabels(); 9377330f729Sjoerg } 9387330f729Sjoerg 9397330f729Sjoerg bool hasLabels() const { 9407330f729Sjoerg return !Labels.empty(); 9417330f729Sjoerg } 9427330f729Sjoerg 9437330f729Sjoerg void rescopeLabels(); 9447330f729Sjoerg }; 9457330f729Sjoerg 9467330f729Sjoerg typedef llvm::DenseMap<const Decl *, Address> DeclMapTy; 9477330f729Sjoerg 9487330f729Sjoerg /// The class used to assign some variables some temporarily addresses. 9497330f729Sjoerg class OMPMapVars { 9507330f729Sjoerg DeclMapTy SavedLocals; 9517330f729Sjoerg DeclMapTy SavedTempAddresses; 9527330f729Sjoerg OMPMapVars(const OMPMapVars &) = delete; 9537330f729Sjoerg void operator=(const OMPMapVars &) = delete; 9547330f729Sjoerg 9557330f729Sjoerg public: 9567330f729Sjoerg explicit OMPMapVars() = default; 9577330f729Sjoerg ~OMPMapVars() { 9587330f729Sjoerg assert(SavedLocals.empty() && "Did not restored original addresses."); 9597330f729Sjoerg }; 9607330f729Sjoerg 9617330f729Sjoerg /// Sets the address of the variable \p LocalVD to be \p TempAddr in 9627330f729Sjoerg /// function \p CGF. 9637330f729Sjoerg /// \return true if at least one variable was set already, false otherwise. 9647330f729Sjoerg bool setVarAddr(CodeGenFunction &CGF, const VarDecl *LocalVD, 9657330f729Sjoerg Address TempAddr) { 9667330f729Sjoerg LocalVD = LocalVD->getCanonicalDecl(); 9677330f729Sjoerg // Only save it once. 9687330f729Sjoerg if (SavedLocals.count(LocalVD)) return false; 9697330f729Sjoerg 9707330f729Sjoerg // Copy the existing local entry to SavedLocals. 9717330f729Sjoerg auto it = CGF.LocalDeclMap.find(LocalVD); 9727330f729Sjoerg if (it != CGF.LocalDeclMap.end()) 9737330f729Sjoerg SavedLocals.try_emplace(LocalVD, it->second); 9747330f729Sjoerg else 9757330f729Sjoerg SavedLocals.try_emplace(LocalVD, Address::invalid()); 9767330f729Sjoerg 9777330f729Sjoerg // Generate the private entry. 9787330f729Sjoerg QualType VarTy = LocalVD->getType(); 9797330f729Sjoerg if (VarTy->isReferenceType()) { 9807330f729Sjoerg Address Temp = CGF.CreateMemTemp(VarTy); 9817330f729Sjoerg CGF.Builder.CreateStore(TempAddr.getPointer(), Temp); 9827330f729Sjoerg TempAddr = Temp; 9837330f729Sjoerg } 9847330f729Sjoerg SavedTempAddresses.try_emplace(LocalVD, TempAddr); 9857330f729Sjoerg 9867330f729Sjoerg return true; 9877330f729Sjoerg } 9887330f729Sjoerg 9897330f729Sjoerg /// Applies new addresses to the list of the variables. 9907330f729Sjoerg /// \return true if at least one variable is using new address, false 9917330f729Sjoerg /// otherwise. 9927330f729Sjoerg bool apply(CodeGenFunction &CGF) { 9937330f729Sjoerg copyInto(SavedTempAddresses, CGF.LocalDeclMap); 9947330f729Sjoerg SavedTempAddresses.clear(); 9957330f729Sjoerg return !SavedLocals.empty(); 9967330f729Sjoerg } 9977330f729Sjoerg 9987330f729Sjoerg /// Restores original addresses of the variables. 9997330f729Sjoerg void restore(CodeGenFunction &CGF) { 10007330f729Sjoerg if (!SavedLocals.empty()) { 10017330f729Sjoerg copyInto(SavedLocals, CGF.LocalDeclMap); 10027330f729Sjoerg SavedLocals.clear(); 10037330f729Sjoerg } 10047330f729Sjoerg } 10057330f729Sjoerg 10067330f729Sjoerg private: 10077330f729Sjoerg /// Copy all the entries in the source map over the corresponding 10087330f729Sjoerg /// entries in the destination, which must exist. 10097330f729Sjoerg static void copyInto(const DeclMapTy &Src, DeclMapTy &Dest) { 10107330f729Sjoerg for (auto &Pair : Src) { 10117330f729Sjoerg if (!Pair.second.isValid()) { 10127330f729Sjoerg Dest.erase(Pair.first); 10137330f729Sjoerg continue; 10147330f729Sjoerg } 10157330f729Sjoerg 10167330f729Sjoerg auto I = Dest.find(Pair.first); 10177330f729Sjoerg if (I != Dest.end()) 10187330f729Sjoerg I->second = Pair.second; 10197330f729Sjoerg else 10207330f729Sjoerg Dest.insert(Pair); 10217330f729Sjoerg } 10227330f729Sjoerg } 10237330f729Sjoerg }; 10247330f729Sjoerg 10257330f729Sjoerg /// The scope used to remap some variables as private in the OpenMP loop body 10267330f729Sjoerg /// (or other captured region emitted without outlining), and to restore old 10277330f729Sjoerg /// vars back on exit. 10287330f729Sjoerg class OMPPrivateScope : public RunCleanupsScope { 10297330f729Sjoerg OMPMapVars MappedVars; 10307330f729Sjoerg OMPPrivateScope(const OMPPrivateScope &) = delete; 10317330f729Sjoerg void operator=(const OMPPrivateScope &) = delete; 10327330f729Sjoerg 10337330f729Sjoerg public: 10347330f729Sjoerg /// Enter a new OpenMP private scope. 10357330f729Sjoerg explicit OMPPrivateScope(CodeGenFunction &CGF) : RunCleanupsScope(CGF) {} 10367330f729Sjoerg 10377330f729Sjoerg /// Registers \p LocalVD variable as a private and apply \p PrivateGen 10387330f729Sjoerg /// function for it to generate corresponding private variable. \p 10397330f729Sjoerg /// PrivateGen returns an address of the generated private variable. 10407330f729Sjoerg /// \return true if the variable is registered as private, false if it has 10417330f729Sjoerg /// been privatized already. 10427330f729Sjoerg bool addPrivate(const VarDecl *LocalVD, 10437330f729Sjoerg const llvm::function_ref<Address()> PrivateGen) { 10447330f729Sjoerg assert(PerformCleanup && "adding private to dead scope"); 10457330f729Sjoerg return MappedVars.setVarAddr(CGF, LocalVD, PrivateGen()); 10467330f729Sjoerg } 10477330f729Sjoerg 10487330f729Sjoerg /// Privatizes local variables previously registered as private. 10497330f729Sjoerg /// Registration is separate from the actual privatization to allow 10507330f729Sjoerg /// initializers use values of the original variables, not the private one. 10517330f729Sjoerg /// This is important, for example, if the private variable is a class 10527330f729Sjoerg /// variable initialized by a constructor that references other private 10537330f729Sjoerg /// variables. But at initialization original variables must be used, not 10547330f729Sjoerg /// private copies. 10557330f729Sjoerg /// \return true if at least one variable was privatized, false otherwise. 10567330f729Sjoerg bool Privatize() { return MappedVars.apply(CGF); } 10577330f729Sjoerg 10587330f729Sjoerg void ForceCleanup() { 10597330f729Sjoerg RunCleanupsScope::ForceCleanup(); 10607330f729Sjoerg MappedVars.restore(CGF); 10617330f729Sjoerg } 10627330f729Sjoerg 10637330f729Sjoerg /// Exit scope - all the mapped variables are restored. 10647330f729Sjoerg ~OMPPrivateScope() { 10657330f729Sjoerg if (PerformCleanup) 10667330f729Sjoerg ForceCleanup(); 10677330f729Sjoerg } 10687330f729Sjoerg 10697330f729Sjoerg /// Checks if the global variable is captured in current function. 10707330f729Sjoerg bool isGlobalVarCaptured(const VarDecl *VD) const { 10717330f729Sjoerg VD = VD->getCanonicalDecl(); 10727330f729Sjoerg return !VD->isLocalVarDeclOrParm() && CGF.LocalDeclMap.count(VD) > 0; 10737330f729Sjoerg } 10747330f729Sjoerg }; 10757330f729Sjoerg 1076*e038c9c4Sjoerg /// Save/restore original map of previously emitted local vars in case when we 1077*e038c9c4Sjoerg /// need to duplicate emission of the same code several times in the same 1078*e038c9c4Sjoerg /// function for OpenMP code. 1079*e038c9c4Sjoerg class OMPLocalDeclMapRAII { 1080*e038c9c4Sjoerg CodeGenFunction &CGF; 1081*e038c9c4Sjoerg DeclMapTy SavedMap; 1082*e038c9c4Sjoerg 1083*e038c9c4Sjoerg public: 1084*e038c9c4Sjoerg OMPLocalDeclMapRAII(CodeGenFunction &CGF) 1085*e038c9c4Sjoerg : CGF(CGF), SavedMap(CGF.LocalDeclMap) {} 1086*e038c9c4Sjoerg ~OMPLocalDeclMapRAII() { SavedMap.swap(CGF.LocalDeclMap); } 1087*e038c9c4Sjoerg }; 1088*e038c9c4Sjoerg 10897330f729Sjoerg /// Takes the old cleanup stack size and emits the cleanup blocks 10907330f729Sjoerg /// that have been added. 10917330f729Sjoerg void 10927330f729Sjoerg PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize, 10937330f729Sjoerg std::initializer_list<llvm::Value **> ValuesToReload = {}); 10947330f729Sjoerg 10957330f729Sjoerg /// Takes the old cleanup stack size and emits the cleanup blocks 10967330f729Sjoerg /// that have been added, then adds all lifetime-extended cleanups from 10977330f729Sjoerg /// the given position to the stack. 10987330f729Sjoerg void 10997330f729Sjoerg PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize, 11007330f729Sjoerg size_t OldLifetimeExtendedStackSize, 11017330f729Sjoerg std::initializer_list<llvm::Value **> ValuesToReload = {}); 11027330f729Sjoerg 11037330f729Sjoerg void ResolveBranchFixups(llvm::BasicBlock *Target); 11047330f729Sjoerg 11057330f729Sjoerg /// The given basic block lies in the current EH scope, but may be a 11067330f729Sjoerg /// target of a potentially scope-crossing jump; get a stable handle 11077330f729Sjoerg /// to which we can perform this jump later. 11087330f729Sjoerg JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target) { 11097330f729Sjoerg return JumpDest(Target, 11107330f729Sjoerg EHStack.getInnermostNormalCleanup(), 11117330f729Sjoerg NextCleanupDestIndex++); 11127330f729Sjoerg } 11137330f729Sjoerg 11147330f729Sjoerg /// The given basic block lies in the current EH scope, but may be a 11157330f729Sjoerg /// target of a potentially scope-crossing jump; get a stable handle 11167330f729Sjoerg /// to which we can perform this jump later. 11177330f729Sjoerg JumpDest getJumpDestInCurrentScope(StringRef Name = StringRef()) { 11187330f729Sjoerg return getJumpDestInCurrentScope(createBasicBlock(Name)); 11197330f729Sjoerg } 11207330f729Sjoerg 11217330f729Sjoerg /// EmitBranchThroughCleanup - Emit a branch from the current insert 11227330f729Sjoerg /// block through the normal cleanup handling code (if any) and then 11237330f729Sjoerg /// on to \arg Dest. 11247330f729Sjoerg void EmitBranchThroughCleanup(JumpDest Dest); 11257330f729Sjoerg 11267330f729Sjoerg /// isObviouslyBranchWithoutCleanups - Return true if a branch to the 11277330f729Sjoerg /// specified destination obviously has no cleanups to run. 'false' is always 11287330f729Sjoerg /// a conservatively correct answer for this method. 11297330f729Sjoerg bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const; 11307330f729Sjoerg 11317330f729Sjoerg /// popCatchScope - Pops the catch scope at the top of the EHScope 11327330f729Sjoerg /// stack, emitting any required code (other than the catch handlers 11337330f729Sjoerg /// themselves). 11347330f729Sjoerg void popCatchScope(); 11357330f729Sjoerg 11367330f729Sjoerg llvm::BasicBlock *getEHResumeBlock(bool isCleanup); 11377330f729Sjoerg llvm::BasicBlock *getEHDispatchBlock(EHScopeStack::stable_iterator scope); 11387330f729Sjoerg llvm::BasicBlock * 11397330f729Sjoerg getFuncletEHDispatchBlock(EHScopeStack::stable_iterator scope); 11407330f729Sjoerg 11417330f729Sjoerg /// An object to manage conditionally-evaluated expressions. 11427330f729Sjoerg class ConditionalEvaluation { 11437330f729Sjoerg llvm::BasicBlock *StartBB; 11447330f729Sjoerg 11457330f729Sjoerg public: 11467330f729Sjoerg ConditionalEvaluation(CodeGenFunction &CGF) 11477330f729Sjoerg : StartBB(CGF.Builder.GetInsertBlock()) {} 11487330f729Sjoerg 11497330f729Sjoerg void begin(CodeGenFunction &CGF) { 11507330f729Sjoerg assert(CGF.OutermostConditional != this); 11517330f729Sjoerg if (!CGF.OutermostConditional) 11527330f729Sjoerg CGF.OutermostConditional = this; 11537330f729Sjoerg } 11547330f729Sjoerg 11557330f729Sjoerg void end(CodeGenFunction &CGF) { 11567330f729Sjoerg assert(CGF.OutermostConditional != nullptr); 11577330f729Sjoerg if (CGF.OutermostConditional == this) 11587330f729Sjoerg CGF.OutermostConditional = nullptr; 11597330f729Sjoerg } 11607330f729Sjoerg 11617330f729Sjoerg /// Returns a block which will be executed prior to each 11627330f729Sjoerg /// evaluation of the conditional code. 11637330f729Sjoerg llvm::BasicBlock *getStartingBlock() const { 11647330f729Sjoerg return StartBB; 11657330f729Sjoerg } 11667330f729Sjoerg }; 11677330f729Sjoerg 11687330f729Sjoerg /// isInConditionalBranch - Return true if we're currently emitting 11697330f729Sjoerg /// one branch or the other of a conditional expression. 11707330f729Sjoerg bool isInConditionalBranch() const { return OutermostConditional != nullptr; } 11717330f729Sjoerg 11727330f729Sjoerg void setBeforeOutermostConditional(llvm::Value *value, Address addr) { 11737330f729Sjoerg assert(isInConditionalBranch()); 11747330f729Sjoerg llvm::BasicBlock *block = OutermostConditional->getStartingBlock(); 11757330f729Sjoerg auto store = new llvm::StoreInst(value, addr.getPointer(), &block->back()); 11767330f729Sjoerg store->setAlignment(addr.getAlignment().getAsAlign()); 11777330f729Sjoerg } 11787330f729Sjoerg 11797330f729Sjoerg /// An RAII object to record that we're evaluating a statement 11807330f729Sjoerg /// expression. 11817330f729Sjoerg class StmtExprEvaluation { 11827330f729Sjoerg CodeGenFunction &CGF; 11837330f729Sjoerg 11847330f729Sjoerg /// We have to save the outermost conditional: cleanups in a 11857330f729Sjoerg /// statement expression aren't conditional just because the 11867330f729Sjoerg /// StmtExpr is. 11877330f729Sjoerg ConditionalEvaluation *SavedOutermostConditional; 11887330f729Sjoerg 11897330f729Sjoerg public: 11907330f729Sjoerg StmtExprEvaluation(CodeGenFunction &CGF) 11917330f729Sjoerg : CGF(CGF), SavedOutermostConditional(CGF.OutermostConditional) { 11927330f729Sjoerg CGF.OutermostConditional = nullptr; 11937330f729Sjoerg } 11947330f729Sjoerg 11957330f729Sjoerg ~StmtExprEvaluation() { 11967330f729Sjoerg CGF.OutermostConditional = SavedOutermostConditional; 11977330f729Sjoerg CGF.EnsureInsertPoint(); 11987330f729Sjoerg } 11997330f729Sjoerg }; 12007330f729Sjoerg 12017330f729Sjoerg /// An object which temporarily prevents a value from being 12027330f729Sjoerg /// destroyed by aggressive peephole optimizations that assume that 12037330f729Sjoerg /// all uses of a value have been realized in the IR. 12047330f729Sjoerg class PeepholeProtection { 12057330f729Sjoerg llvm::Instruction *Inst; 12067330f729Sjoerg friend class CodeGenFunction; 12077330f729Sjoerg 12087330f729Sjoerg public: 12097330f729Sjoerg PeepholeProtection() : Inst(nullptr) {} 12107330f729Sjoerg }; 12117330f729Sjoerg 12127330f729Sjoerg /// A non-RAII class containing all the information about a bound 12137330f729Sjoerg /// opaque value. OpaqueValueMapping, below, is a RAII wrapper for 12147330f729Sjoerg /// this which makes individual mappings very simple; using this 12157330f729Sjoerg /// class directly is useful when you have a variable number of 12167330f729Sjoerg /// opaque values or don't want the RAII functionality for some 12177330f729Sjoerg /// reason. 12187330f729Sjoerg class OpaqueValueMappingData { 12197330f729Sjoerg const OpaqueValueExpr *OpaqueValue; 12207330f729Sjoerg bool BoundLValue; 12217330f729Sjoerg CodeGenFunction::PeepholeProtection Protection; 12227330f729Sjoerg 12237330f729Sjoerg OpaqueValueMappingData(const OpaqueValueExpr *ov, 12247330f729Sjoerg bool boundLValue) 12257330f729Sjoerg : OpaqueValue(ov), BoundLValue(boundLValue) {} 12267330f729Sjoerg public: 12277330f729Sjoerg OpaqueValueMappingData() : OpaqueValue(nullptr) {} 12287330f729Sjoerg 12297330f729Sjoerg static bool shouldBindAsLValue(const Expr *expr) { 12307330f729Sjoerg // gl-values should be bound as l-values for obvious reasons. 12317330f729Sjoerg // Records should be bound as l-values because IR generation 12327330f729Sjoerg // always keeps them in memory. Expressions of function type 12337330f729Sjoerg // act exactly like l-values but are formally required to be 12347330f729Sjoerg // r-values in C. 12357330f729Sjoerg return expr->isGLValue() || 12367330f729Sjoerg expr->getType()->isFunctionType() || 12377330f729Sjoerg hasAggregateEvaluationKind(expr->getType()); 12387330f729Sjoerg } 12397330f729Sjoerg 12407330f729Sjoerg static OpaqueValueMappingData bind(CodeGenFunction &CGF, 12417330f729Sjoerg const OpaqueValueExpr *ov, 12427330f729Sjoerg const Expr *e) { 12437330f729Sjoerg if (shouldBindAsLValue(ov)) 12447330f729Sjoerg return bind(CGF, ov, CGF.EmitLValue(e)); 12457330f729Sjoerg return bind(CGF, ov, CGF.EmitAnyExpr(e)); 12467330f729Sjoerg } 12477330f729Sjoerg 12487330f729Sjoerg static OpaqueValueMappingData bind(CodeGenFunction &CGF, 12497330f729Sjoerg const OpaqueValueExpr *ov, 12507330f729Sjoerg const LValue &lv) { 12517330f729Sjoerg assert(shouldBindAsLValue(ov)); 12527330f729Sjoerg CGF.OpaqueLValues.insert(std::make_pair(ov, lv)); 12537330f729Sjoerg return OpaqueValueMappingData(ov, true); 12547330f729Sjoerg } 12557330f729Sjoerg 12567330f729Sjoerg static OpaqueValueMappingData bind(CodeGenFunction &CGF, 12577330f729Sjoerg const OpaqueValueExpr *ov, 12587330f729Sjoerg const RValue &rv) { 12597330f729Sjoerg assert(!shouldBindAsLValue(ov)); 12607330f729Sjoerg CGF.OpaqueRValues.insert(std::make_pair(ov, rv)); 12617330f729Sjoerg 12627330f729Sjoerg OpaqueValueMappingData data(ov, false); 12637330f729Sjoerg 12647330f729Sjoerg // Work around an extremely aggressive peephole optimization in 12657330f729Sjoerg // EmitScalarConversion which assumes that all other uses of a 12667330f729Sjoerg // value are extant. 12677330f729Sjoerg data.Protection = CGF.protectFromPeepholes(rv); 12687330f729Sjoerg 12697330f729Sjoerg return data; 12707330f729Sjoerg } 12717330f729Sjoerg 12727330f729Sjoerg bool isValid() const { return OpaqueValue != nullptr; } 12737330f729Sjoerg void clear() { OpaqueValue = nullptr; } 12747330f729Sjoerg 12757330f729Sjoerg void unbind(CodeGenFunction &CGF) { 12767330f729Sjoerg assert(OpaqueValue && "no data to unbind!"); 12777330f729Sjoerg 12787330f729Sjoerg if (BoundLValue) { 12797330f729Sjoerg CGF.OpaqueLValues.erase(OpaqueValue); 12807330f729Sjoerg } else { 12817330f729Sjoerg CGF.OpaqueRValues.erase(OpaqueValue); 12827330f729Sjoerg CGF.unprotectFromPeepholes(Protection); 12837330f729Sjoerg } 12847330f729Sjoerg } 12857330f729Sjoerg }; 12867330f729Sjoerg 12877330f729Sjoerg /// An RAII object to set (and then clear) a mapping for an OpaqueValueExpr. 12887330f729Sjoerg class OpaqueValueMapping { 12897330f729Sjoerg CodeGenFunction &CGF; 12907330f729Sjoerg OpaqueValueMappingData Data; 12917330f729Sjoerg 12927330f729Sjoerg public: 12937330f729Sjoerg static bool shouldBindAsLValue(const Expr *expr) { 12947330f729Sjoerg return OpaqueValueMappingData::shouldBindAsLValue(expr); 12957330f729Sjoerg } 12967330f729Sjoerg 12977330f729Sjoerg /// Build the opaque value mapping for the given conditional 12987330f729Sjoerg /// operator if it's the GNU ?: extension. This is a common 12997330f729Sjoerg /// enough pattern that the convenience operator is really 13007330f729Sjoerg /// helpful. 13017330f729Sjoerg /// 13027330f729Sjoerg OpaqueValueMapping(CodeGenFunction &CGF, 13037330f729Sjoerg const AbstractConditionalOperator *op) : CGF(CGF) { 13047330f729Sjoerg if (isa<ConditionalOperator>(op)) 13057330f729Sjoerg // Leave Data empty. 13067330f729Sjoerg return; 13077330f729Sjoerg 13087330f729Sjoerg const BinaryConditionalOperator *e = cast<BinaryConditionalOperator>(op); 13097330f729Sjoerg Data = OpaqueValueMappingData::bind(CGF, e->getOpaqueValue(), 13107330f729Sjoerg e->getCommon()); 13117330f729Sjoerg } 13127330f729Sjoerg 13137330f729Sjoerg /// Build the opaque value mapping for an OpaqueValueExpr whose source 13147330f729Sjoerg /// expression is set to the expression the OVE represents. 13157330f729Sjoerg OpaqueValueMapping(CodeGenFunction &CGF, const OpaqueValueExpr *OV) 13167330f729Sjoerg : CGF(CGF) { 13177330f729Sjoerg if (OV) { 13187330f729Sjoerg assert(OV->getSourceExpr() && "wrong form of OpaqueValueMapping used " 13197330f729Sjoerg "for OVE with no source expression"); 13207330f729Sjoerg Data = OpaqueValueMappingData::bind(CGF, OV, OV->getSourceExpr()); 13217330f729Sjoerg } 13227330f729Sjoerg } 13237330f729Sjoerg 13247330f729Sjoerg OpaqueValueMapping(CodeGenFunction &CGF, 13257330f729Sjoerg const OpaqueValueExpr *opaqueValue, 13267330f729Sjoerg LValue lvalue) 13277330f729Sjoerg : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, lvalue)) { 13287330f729Sjoerg } 13297330f729Sjoerg 13307330f729Sjoerg OpaqueValueMapping(CodeGenFunction &CGF, 13317330f729Sjoerg const OpaqueValueExpr *opaqueValue, 13327330f729Sjoerg RValue rvalue) 13337330f729Sjoerg : CGF(CGF), Data(OpaqueValueMappingData::bind(CGF, opaqueValue, rvalue)) { 13347330f729Sjoerg } 13357330f729Sjoerg 13367330f729Sjoerg void pop() { 13377330f729Sjoerg Data.unbind(CGF); 13387330f729Sjoerg Data.clear(); 13397330f729Sjoerg } 13407330f729Sjoerg 13417330f729Sjoerg ~OpaqueValueMapping() { 13427330f729Sjoerg if (Data.isValid()) Data.unbind(CGF); 13437330f729Sjoerg } 13447330f729Sjoerg }; 13457330f729Sjoerg 13467330f729Sjoerg private: 13477330f729Sjoerg CGDebugInfo *DebugInfo; 13487330f729Sjoerg /// Used to create unique names for artificial VLA size debug info variables. 13497330f729Sjoerg unsigned VLAExprCounter = 0; 13507330f729Sjoerg bool DisableDebugInfo = false; 13517330f729Sjoerg 13527330f729Sjoerg /// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid 13537330f729Sjoerg /// calling llvm.stacksave for multiple VLAs in the same scope. 13547330f729Sjoerg bool DidCallStackSave = false; 13557330f729Sjoerg 13567330f729Sjoerg /// IndirectBranch - The first time an indirect goto is seen we create a block 13577330f729Sjoerg /// with an indirect branch. Every time we see the address of a label taken, 13587330f729Sjoerg /// we add the label to the indirect goto. Every subsequent indirect goto is 13597330f729Sjoerg /// codegen'd as a jump to the IndirectBranch's basic block. 13607330f729Sjoerg llvm::IndirectBrInst *IndirectBranch = nullptr; 13617330f729Sjoerg 13627330f729Sjoerg /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C 13637330f729Sjoerg /// decls. 13647330f729Sjoerg DeclMapTy LocalDeclMap; 13657330f729Sjoerg 13667330f729Sjoerg // Keep track of the cleanups for callee-destructed parameters pushed to the 13677330f729Sjoerg // cleanup stack so that they can be deactivated later. 13687330f729Sjoerg llvm::DenseMap<const ParmVarDecl *, EHScopeStack::stable_iterator> 13697330f729Sjoerg CalleeDestructedParamCleanups; 13707330f729Sjoerg 13717330f729Sjoerg /// SizeArguments - If a ParmVarDecl had the pass_object_size attribute, this 13727330f729Sjoerg /// will contain a mapping from said ParmVarDecl to its implicit "object_size" 13737330f729Sjoerg /// parameter. 13747330f729Sjoerg llvm::SmallDenseMap<const ParmVarDecl *, const ImplicitParamDecl *, 2> 13757330f729Sjoerg SizeArguments; 13767330f729Sjoerg 13777330f729Sjoerg /// Track escaped local variables with auto storage. Used during SEH 13787330f729Sjoerg /// outlining to produce a call to llvm.localescape. 13797330f729Sjoerg llvm::DenseMap<llvm::AllocaInst *, int> EscapedLocals; 13807330f729Sjoerg 13817330f729Sjoerg /// LabelMap - This keeps track of the LLVM basic block for each C label. 13827330f729Sjoerg llvm::DenseMap<const LabelDecl*, JumpDest> LabelMap; 13837330f729Sjoerg 13847330f729Sjoerg // BreakContinueStack - This keeps track of where break and continue 13857330f729Sjoerg // statements should jump to. 13867330f729Sjoerg struct BreakContinue { 13877330f729Sjoerg BreakContinue(JumpDest Break, JumpDest Continue) 13887330f729Sjoerg : BreakBlock(Break), ContinueBlock(Continue) {} 13897330f729Sjoerg 13907330f729Sjoerg JumpDest BreakBlock; 13917330f729Sjoerg JumpDest ContinueBlock; 13927330f729Sjoerg }; 13937330f729Sjoerg SmallVector<BreakContinue, 8> BreakContinueStack; 13947330f729Sjoerg 13957330f729Sjoerg /// Handles cancellation exit points in OpenMP-related constructs. 13967330f729Sjoerg class OpenMPCancelExitStack { 13977330f729Sjoerg /// Tracks cancellation exit point and join point for cancel-related exit 13987330f729Sjoerg /// and normal exit. 13997330f729Sjoerg struct CancelExit { 14007330f729Sjoerg CancelExit() = default; 14017330f729Sjoerg CancelExit(OpenMPDirectiveKind Kind, JumpDest ExitBlock, 14027330f729Sjoerg JumpDest ContBlock) 14037330f729Sjoerg : Kind(Kind), ExitBlock(ExitBlock), ContBlock(ContBlock) {} 1404*e038c9c4Sjoerg OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown; 14057330f729Sjoerg /// true if the exit block has been emitted already by the special 14067330f729Sjoerg /// emitExit() call, false if the default codegen is used. 14077330f729Sjoerg bool HasBeenEmitted = false; 14087330f729Sjoerg JumpDest ExitBlock; 14097330f729Sjoerg JumpDest ContBlock; 14107330f729Sjoerg }; 14117330f729Sjoerg 14127330f729Sjoerg SmallVector<CancelExit, 8> Stack; 14137330f729Sjoerg 14147330f729Sjoerg public: 14157330f729Sjoerg OpenMPCancelExitStack() : Stack(1) {} 14167330f729Sjoerg ~OpenMPCancelExitStack() = default; 14177330f729Sjoerg /// Fetches the exit block for the current OpenMP construct. 14187330f729Sjoerg JumpDest getExitBlock() const { return Stack.back().ExitBlock; } 14197330f729Sjoerg /// Emits exit block with special codegen procedure specific for the related 14207330f729Sjoerg /// OpenMP construct + emits code for normal construct cleanup. 14217330f729Sjoerg void emitExit(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, 14227330f729Sjoerg const llvm::function_ref<void(CodeGenFunction &)> CodeGen) { 14237330f729Sjoerg if (Stack.back().Kind == Kind && getExitBlock().isValid()) { 14247330f729Sjoerg assert(CGF.getOMPCancelDestination(Kind).isValid()); 14257330f729Sjoerg assert(CGF.HaveInsertPoint()); 14267330f729Sjoerg assert(!Stack.back().HasBeenEmitted); 14277330f729Sjoerg auto IP = CGF.Builder.saveAndClearIP(); 14287330f729Sjoerg CGF.EmitBlock(Stack.back().ExitBlock.getBlock()); 14297330f729Sjoerg CodeGen(CGF); 14307330f729Sjoerg CGF.EmitBranch(Stack.back().ContBlock.getBlock()); 14317330f729Sjoerg CGF.Builder.restoreIP(IP); 14327330f729Sjoerg Stack.back().HasBeenEmitted = true; 14337330f729Sjoerg } 14347330f729Sjoerg CodeGen(CGF); 14357330f729Sjoerg } 14367330f729Sjoerg /// Enter the cancel supporting \a Kind construct. 14377330f729Sjoerg /// \param Kind OpenMP directive that supports cancel constructs. 14387330f729Sjoerg /// \param HasCancel true, if the construct has inner cancel directive, 14397330f729Sjoerg /// false otherwise. 14407330f729Sjoerg void enter(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, bool HasCancel) { 14417330f729Sjoerg Stack.push_back({Kind, 14427330f729Sjoerg HasCancel ? CGF.getJumpDestInCurrentScope("cancel.exit") 14437330f729Sjoerg : JumpDest(), 14447330f729Sjoerg HasCancel ? CGF.getJumpDestInCurrentScope("cancel.cont") 14457330f729Sjoerg : JumpDest()}); 14467330f729Sjoerg } 14477330f729Sjoerg /// Emits default exit point for the cancel construct (if the special one 14487330f729Sjoerg /// has not be used) + join point for cancel/normal exits. 14497330f729Sjoerg void exit(CodeGenFunction &CGF) { 14507330f729Sjoerg if (getExitBlock().isValid()) { 14517330f729Sjoerg assert(CGF.getOMPCancelDestination(Stack.back().Kind).isValid()); 14527330f729Sjoerg bool HaveIP = CGF.HaveInsertPoint(); 14537330f729Sjoerg if (!Stack.back().HasBeenEmitted) { 14547330f729Sjoerg if (HaveIP) 14557330f729Sjoerg CGF.EmitBranchThroughCleanup(Stack.back().ContBlock); 14567330f729Sjoerg CGF.EmitBlock(Stack.back().ExitBlock.getBlock()); 14577330f729Sjoerg CGF.EmitBranchThroughCleanup(Stack.back().ContBlock); 14587330f729Sjoerg } 14597330f729Sjoerg CGF.EmitBlock(Stack.back().ContBlock.getBlock()); 14607330f729Sjoerg if (!HaveIP) { 14617330f729Sjoerg CGF.Builder.CreateUnreachable(); 14627330f729Sjoerg CGF.Builder.ClearInsertionPoint(); 14637330f729Sjoerg } 14647330f729Sjoerg } 14657330f729Sjoerg Stack.pop_back(); 14667330f729Sjoerg } 14677330f729Sjoerg }; 14687330f729Sjoerg OpenMPCancelExitStack OMPCancelStack; 14697330f729Sjoerg 1470*e038c9c4Sjoerg /// Lower the Likelihood knowledge about the \p Cond via llvm.expect intrin. 1471*e038c9c4Sjoerg llvm::Value *emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond, 1472*e038c9c4Sjoerg Stmt::Likelihood LH); 1473*e038c9c4Sjoerg 14747330f729Sjoerg CodeGenPGO PGO; 14757330f729Sjoerg 14767330f729Sjoerg /// Calculate branch weights appropriate for PGO data 1477*e038c9c4Sjoerg llvm::MDNode *createProfileWeights(uint64_t TrueCount, 1478*e038c9c4Sjoerg uint64_t FalseCount) const; 1479*e038c9c4Sjoerg llvm::MDNode *createProfileWeights(ArrayRef<uint64_t> Weights) const; 14807330f729Sjoerg llvm::MDNode *createProfileWeightsForLoop(const Stmt *Cond, 1481*e038c9c4Sjoerg uint64_t LoopCount) const; 14827330f729Sjoerg 14837330f729Sjoerg public: 14847330f729Sjoerg /// Increment the profiler's counter for the given statement by \p StepV. 14857330f729Sjoerg /// If \p StepV is null, the default increment is 1. 14867330f729Sjoerg void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) { 1487*e038c9c4Sjoerg if (CGM.getCodeGenOpts().hasProfileClangInstr() && 1488*e038c9c4Sjoerg !CurFn->hasFnAttribute(llvm::Attribute::NoProfile)) 14897330f729Sjoerg PGO.emitCounterIncrement(Builder, S, StepV); 14907330f729Sjoerg PGO.setCurrentStmt(S); 14917330f729Sjoerg } 14927330f729Sjoerg 14937330f729Sjoerg /// Get the profiler's count for the given statement. 14947330f729Sjoerg uint64_t getProfileCount(const Stmt *S) { 14957330f729Sjoerg Optional<uint64_t> Count = PGO.getStmtCount(S); 14967330f729Sjoerg if (!Count.hasValue()) 14977330f729Sjoerg return 0; 14987330f729Sjoerg return *Count; 14997330f729Sjoerg } 15007330f729Sjoerg 15017330f729Sjoerg /// Set the profiler's current count. 15027330f729Sjoerg void setCurrentProfileCount(uint64_t Count) { 15037330f729Sjoerg PGO.setCurrentRegionCount(Count); 15047330f729Sjoerg } 15057330f729Sjoerg 15067330f729Sjoerg /// Get the profiler's current count. This is generally the count for the most 15077330f729Sjoerg /// recently incremented counter. 15087330f729Sjoerg uint64_t getCurrentProfileCount() { 15097330f729Sjoerg return PGO.getCurrentRegionCount(); 15107330f729Sjoerg } 15117330f729Sjoerg 15127330f729Sjoerg private: 15137330f729Sjoerg 15147330f729Sjoerg /// SwitchInsn - This is nearest current switch instruction. It is null if 15157330f729Sjoerg /// current context is not in a switch. 15167330f729Sjoerg llvm::SwitchInst *SwitchInsn = nullptr; 15177330f729Sjoerg /// The branch weights of SwitchInsn when doing instrumentation based PGO. 15187330f729Sjoerg SmallVector<uint64_t, 16> *SwitchWeights = nullptr; 15197330f729Sjoerg 1520*e038c9c4Sjoerg /// The likelihood attributes of the SwitchCase. 1521*e038c9c4Sjoerg SmallVector<Stmt::Likelihood, 16> *SwitchLikelihood = nullptr; 1522*e038c9c4Sjoerg 15237330f729Sjoerg /// CaseRangeBlock - This block holds if condition check for last case 15247330f729Sjoerg /// statement range in current switch instruction. 15257330f729Sjoerg llvm::BasicBlock *CaseRangeBlock = nullptr; 15267330f729Sjoerg 15277330f729Sjoerg /// OpaqueLValues - Keeps track of the current set of opaque value 15287330f729Sjoerg /// expressions. 15297330f729Sjoerg llvm::DenseMap<const OpaqueValueExpr *, LValue> OpaqueLValues; 15307330f729Sjoerg llvm::DenseMap<const OpaqueValueExpr *, RValue> OpaqueRValues; 15317330f729Sjoerg 15327330f729Sjoerg // VLASizeMap - This keeps track of the associated size for each VLA type. 15337330f729Sjoerg // We track this by the size expression rather than the type itself because 15347330f729Sjoerg // in certain situations, like a const qualifier applied to an VLA typedef, 15357330f729Sjoerg // multiple VLA types can share the same size expression. 15367330f729Sjoerg // FIXME: Maybe this could be a stack of maps that is pushed/popped as we 15377330f729Sjoerg // enter/leave scopes. 15387330f729Sjoerg llvm::DenseMap<const Expr*, llvm::Value*> VLASizeMap; 15397330f729Sjoerg 15407330f729Sjoerg /// A block containing a single 'unreachable' instruction. Created 15417330f729Sjoerg /// lazily by getUnreachableBlock(). 15427330f729Sjoerg llvm::BasicBlock *UnreachableBlock = nullptr; 15437330f729Sjoerg 15447330f729Sjoerg /// Counts of the number return expressions in the function. 15457330f729Sjoerg unsigned NumReturnExprs = 0; 15467330f729Sjoerg 15477330f729Sjoerg /// Count the number of simple (constant) return expressions in the function. 15487330f729Sjoerg unsigned NumSimpleReturnExprs = 0; 15497330f729Sjoerg 15507330f729Sjoerg /// The last regular (non-return) debug location (breakpoint) in the function. 15517330f729Sjoerg SourceLocation LastStopPoint; 15527330f729Sjoerg 15537330f729Sjoerg public: 15547330f729Sjoerg /// Source location information about the default argument or member 15557330f729Sjoerg /// initializer expression we're evaluating, if any. 15567330f729Sjoerg CurrentSourceLocExprScope CurSourceLocExprScope; 15577330f729Sjoerg using SourceLocExprScopeGuard = 15587330f729Sjoerg CurrentSourceLocExprScope::SourceLocExprScopeGuard; 15597330f729Sjoerg 15607330f729Sjoerg /// A scope within which we are constructing the fields of an object which 15617330f729Sjoerg /// might use a CXXDefaultInitExpr. This stashes away a 'this' value to use 15627330f729Sjoerg /// if we need to evaluate a CXXDefaultInitExpr within the evaluation. 15637330f729Sjoerg class FieldConstructionScope { 15647330f729Sjoerg public: 15657330f729Sjoerg FieldConstructionScope(CodeGenFunction &CGF, Address This) 15667330f729Sjoerg : CGF(CGF), OldCXXDefaultInitExprThis(CGF.CXXDefaultInitExprThis) { 15677330f729Sjoerg CGF.CXXDefaultInitExprThis = This; 15687330f729Sjoerg } 15697330f729Sjoerg ~FieldConstructionScope() { 15707330f729Sjoerg CGF.CXXDefaultInitExprThis = OldCXXDefaultInitExprThis; 15717330f729Sjoerg } 15727330f729Sjoerg 15737330f729Sjoerg private: 15747330f729Sjoerg CodeGenFunction &CGF; 15757330f729Sjoerg Address OldCXXDefaultInitExprThis; 15767330f729Sjoerg }; 15777330f729Sjoerg 15787330f729Sjoerg /// The scope of a CXXDefaultInitExpr. Within this scope, the value of 'this' 15797330f729Sjoerg /// is overridden to be the object under construction. 15807330f729Sjoerg class CXXDefaultInitExprScope { 15817330f729Sjoerg public: 15827330f729Sjoerg CXXDefaultInitExprScope(CodeGenFunction &CGF, const CXXDefaultInitExpr *E) 15837330f729Sjoerg : CGF(CGF), OldCXXThisValue(CGF.CXXThisValue), 15847330f729Sjoerg OldCXXThisAlignment(CGF.CXXThisAlignment), 15857330f729Sjoerg SourceLocScope(E, CGF.CurSourceLocExprScope) { 15867330f729Sjoerg CGF.CXXThisValue = CGF.CXXDefaultInitExprThis.getPointer(); 15877330f729Sjoerg CGF.CXXThisAlignment = CGF.CXXDefaultInitExprThis.getAlignment(); 15887330f729Sjoerg } 15897330f729Sjoerg ~CXXDefaultInitExprScope() { 15907330f729Sjoerg CGF.CXXThisValue = OldCXXThisValue; 15917330f729Sjoerg CGF.CXXThisAlignment = OldCXXThisAlignment; 15927330f729Sjoerg } 15937330f729Sjoerg 15947330f729Sjoerg public: 15957330f729Sjoerg CodeGenFunction &CGF; 15967330f729Sjoerg llvm::Value *OldCXXThisValue; 15977330f729Sjoerg CharUnits OldCXXThisAlignment; 15987330f729Sjoerg SourceLocExprScopeGuard SourceLocScope; 15997330f729Sjoerg }; 16007330f729Sjoerg 16017330f729Sjoerg struct CXXDefaultArgExprScope : SourceLocExprScopeGuard { 16027330f729Sjoerg CXXDefaultArgExprScope(CodeGenFunction &CGF, const CXXDefaultArgExpr *E) 16037330f729Sjoerg : SourceLocExprScopeGuard(E, CGF.CurSourceLocExprScope) {} 16047330f729Sjoerg }; 16057330f729Sjoerg 16067330f729Sjoerg /// The scope of an ArrayInitLoopExpr. Within this scope, the value of the 16077330f729Sjoerg /// current loop index is overridden. 16087330f729Sjoerg class ArrayInitLoopExprScope { 16097330f729Sjoerg public: 16107330f729Sjoerg ArrayInitLoopExprScope(CodeGenFunction &CGF, llvm::Value *Index) 16117330f729Sjoerg : CGF(CGF), OldArrayInitIndex(CGF.ArrayInitIndex) { 16127330f729Sjoerg CGF.ArrayInitIndex = Index; 16137330f729Sjoerg } 16147330f729Sjoerg ~ArrayInitLoopExprScope() { 16157330f729Sjoerg CGF.ArrayInitIndex = OldArrayInitIndex; 16167330f729Sjoerg } 16177330f729Sjoerg 16187330f729Sjoerg private: 16197330f729Sjoerg CodeGenFunction &CGF; 16207330f729Sjoerg llvm::Value *OldArrayInitIndex; 16217330f729Sjoerg }; 16227330f729Sjoerg 16237330f729Sjoerg class InlinedInheritingConstructorScope { 16247330f729Sjoerg public: 16257330f729Sjoerg InlinedInheritingConstructorScope(CodeGenFunction &CGF, GlobalDecl GD) 16267330f729Sjoerg : CGF(CGF), OldCurGD(CGF.CurGD), OldCurFuncDecl(CGF.CurFuncDecl), 16277330f729Sjoerg OldCurCodeDecl(CGF.CurCodeDecl), 16287330f729Sjoerg OldCXXABIThisDecl(CGF.CXXABIThisDecl), 16297330f729Sjoerg OldCXXABIThisValue(CGF.CXXABIThisValue), 16307330f729Sjoerg OldCXXThisValue(CGF.CXXThisValue), 16317330f729Sjoerg OldCXXABIThisAlignment(CGF.CXXABIThisAlignment), 16327330f729Sjoerg OldCXXThisAlignment(CGF.CXXThisAlignment), 16337330f729Sjoerg OldReturnValue(CGF.ReturnValue), OldFnRetTy(CGF.FnRetTy), 16347330f729Sjoerg OldCXXInheritedCtorInitExprArgs( 16357330f729Sjoerg std::move(CGF.CXXInheritedCtorInitExprArgs)) { 16367330f729Sjoerg CGF.CurGD = GD; 16377330f729Sjoerg CGF.CurFuncDecl = CGF.CurCodeDecl = 16387330f729Sjoerg cast<CXXConstructorDecl>(GD.getDecl()); 16397330f729Sjoerg CGF.CXXABIThisDecl = nullptr; 16407330f729Sjoerg CGF.CXXABIThisValue = nullptr; 16417330f729Sjoerg CGF.CXXThisValue = nullptr; 16427330f729Sjoerg CGF.CXXABIThisAlignment = CharUnits(); 16437330f729Sjoerg CGF.CXXThisAlignment = CharUnits(); 16447330f729Sjoerg CGF.ReturnValue = Address::invalid(); 16457330f729Sjoerg CGF.FnRetTy = QualType(); 16467330f729Sjoerg CGF.CXXInheritedCtorInitExprArgs.clear(); 16477330f729Sjoerg } 16487330f729Sjoerg ~InlinedInheritingConstructorScope() { 16497330f729Sjoerg CGF.CurGD = OldCurGD; 16507330f729Sjoerg CGF.CurFuncDecl = OldCurFuncDecl; 16517330f729Sjoerg CGF.CurCodeDecl = OldCurCodeDecl; 16527330f729Sjoerg CGF.CXXABIThisDecl = OldCXXABIThisDecl; 16537330f729Sjoerg CGF.CXXABIThisValue = OldCXXABIThisValue; 16547330f729Sjoerg CGF.CXXThisValue = OldCXXThisValue; 16557330f729Sjoerg CGF.CXXABIThisAlignment = OldCXXABIThisAlignment; 16567330f729Sjoerg CGF.CXXThisAlignment = OldCXXThisAlignment; 16577330f729Sjoerg CGF.ReturnValue = OldReturnValue; 16587330f729Sjoerg CGF.FnRetTy = OldFnRetTy; 16597330f729Sjoerg CGF.CXXInheritedCtorInitExprArgs = 16607330f729Sjoerg std::move(OldCXXInheritedCtorInitExprArgs); 16617330f729Sjoerg } 16627330f729Sjoerg 16637330f729Sjoerg private: 16647330f729Sjoerg CodeGenFunction &CGF; 16657330f729Sjoerg GlobalDecl OldCurGD; 16667330f729Sjoerg const Decl *OldCurFuncDecl; 16677330f729Sjoerg const Decl *OldCurCodeDecl; 16687330f729Sjoerg ImplicitParamDecl *OldCXXABIThisDecl; 16697330f729Sjoerg llvm::Value *OldCXXABIThisValue; 16707330f729Sjoerg llvm::Value *OldCXXThisValue; 16717330f729Sjoerg CharUnits OldCXXABIThisAlignment; 16727330f729Sjoerg CharUnits OldCXXThisAlignment; 16737330f729Sjoerg Address OldReturnValue; 16747330f729Sjoerg QualType OldFnRetTy; 16757330f729Sjoerg CallArgList OldCXXInheritedCtorInitExprArgs; 16767330f729Sjoerg }; 16777330f729Sjoerg 1678*e038c9c4Sjoerg // Helper class for the OpenMP IR Builder. Allows reusability of code used for 1679*e038c9c4Sjoerg // region body, and finalization codegen callbacks. This will class will also 1680*e038c9c4Sjoerg // contain privatization functions used by the privatization call backs 1681*e038c9c4Sjoerg // 1682*e038c9c4Sjoerg // TODO: this is temporary class for things that are being moved out of 1683*e038c9c4Sjoerg // CGOpenMPRuntime, new versions of current CodeGenFunction methods, or 1684*e038c9c4Sjoerg // utility function for use with the OMPBuilder. Once that move to use the 1685*e038c9c4Sjoerg // OMPBuilder is done, everything here will either become part of CodeGenFunc. 1686*e038c9c4Sjoerg // directly, or a new helper class that will contain functions used by both 1687*e038c9c4Sjoerg // this and the OMPBuilder 1688*e038c9c4Sjoerg 1689*e038c9c4Sjoerg struct OMPBuilderCBHelpers { 1690*e038c9c4Sjoerg 1691*e038c9c4Sjoerg OMPBuilderCBHelpers() = delete; 1692*e038c9c4Sjoerg OMPBuilderCBHelpers(const OMPBuilderCBHelpers &) = delete; 1693*e038c9c4Sjoerg OMPBuilderCBHelpers &operator=(const OMPBuilderCBHelpers &) = delete; 1694*e038c9c4Sjoerg 1695*e038c9c4Sjoerg using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; 1696*e038c9c4Sjoerg 1697*e038c9c4Sjoerg /// Cleanup action for allocate support. 1698*e038c9c4Sjoerg class OMPAllocateCleanupTy final : public EHScopeStack::Cleanup { 1699*e038c9c4Sjoerg 1700*e038c9c4Sjoerg private: 1701*e038c9c4Sjoerg llvm::CallInst *RTLFnCI; 1702*e038c9c4Sjoerg 1703*e038c9c4Sjoerg public: 1704*e038c9c4Sjoerg OMPAllocateCleanupTy(llvm::CallInst *RLFnCI) : RTLFnCI(RLFnCI) { 1705*e038c9c4Sjoerg RLFnCI->removeFromParent(); 1706*e038c9c4Sjoerg } 1707*e038c9c4Sjoerg 1708*e038c9c4Sjoerg void Emit(CodeGenFunction &CGF, Flags /*flags*/) override { 1709*e038c9c4Sjoerg if (!CGF.HaveInsertPoint()) 1710*e038c9c4Sjoerg return; 1711*e038c9c4Sjoerg CGF.Builder.Insert(RTLFnCI); 1712*e038c9c4Sjoerg } 1713*e038c9c4Sjoerg }; 1714*e038c9c4Sjoerg 1715*e038c9c4Sjoerg /// Returns address of the threadprivate variable for the current 1716*e038c9c4Sjoerg /// thread. This Also create any necessary OMP runtime calls. 1717*e038c9c4Sjoerg /// 1718*e038c9c4Sjoerg /// \param VD VarDecl for Threadprivate variable. 1719*e038c9c4Sjoerg /// \param VDAddr Address of the Vardecl 1720*e038c9c4Sjoerg /// \param Loc The location where the barrier directive was encountered 1721*e038c9c4Sjoerg static Address getAddrOfThreadPrivate(CodeGenFunction &CGF, 1722*e038c9c4Sjoerg const VarDecl *VD, Address VDAddr, 1723*e038c9c4Sjoerg SourceLocation Loc); 1724*e038c9c4Sjoerg 1725*e038c9c4Sjoerg /// Gets the OpenMP-specific address of the local variable /p VD. 1726*e038c9c4Sjoerg static Address getAddressOfLocalVariable(CodeGenFunction &CGF, 1727*e038c9c4Sjoerg const VarDecl *VD); 1728*e038c9c4Sjoerg /// Get the platform-specific name separator. 1729*e038c9c4Sjoerg /// \param Parts different parts of the final name that needs separation 1730*e038c9c4Sjoerg /// \param FirstSeparator First separator used between the initial two 1731*e038c9c4Sjoerg /// parts of the name. 1732*e038c9c4Sjoerg /// \param Separator separator used between all of the rest consecutinve 1733*e038c9c4Sjoerg /// parts of the name 1734*e038c9c4Sjoerg static std::string getNameWithSeparators(ArrayRef<StringRef> Parts, 1735*e038c9c4Sjoerg StringRef FirstSeparator = ".", 1736*e038c9c4Sjoerg StringRef Separator = "."); 1737*e038c9c4Sjoerg /// Emit the Finalization for an OMP region 1738*e038c9c4Sjoerg /// \param CGF The Codegen function this belongs to 1739*e038c9c4Sjoerg /// \param IP Insertion point for generating the finalization code. 1740*e038c9c4Sjoerg static void FinalizeOMPRegion(CodeGenFunction &CGF, InsertPointTy IP) { 1741*e038c9c4Sjoerg CGBuilderTy::InsertPointGuard IPG(CGF.Builder); 1742*e038c9c4Sjoerg assert(IP.getBlock()->end() != IP.getPoint() && 1743*e038c9c4Sjoerg "OpenMP IR Builder should cause terminated block!"); 1744*e038c9c4Sjoerg 1745*e038c9c4Sjoerg llvm::BasicBlock *IPBB = IP.getBlock(); 1746*e038c9c4Sjoerg llvm::BasicBlock *DestBB = IPBB->getUniqueSuccessor(); 1747*e038c9c4Sjoerg assert(DestBB && "Finalization block should have one successor!"); 1748*e038c9c4Sjoerg 1749*e038c9c4Sjoerg // erase and replace with cleanup branch. 1750*e038c9c4Sjoerg IPBB->getTerminator()->eraseFromParent(); 1751*e038c9c4Sjoerg CGF.Builder.SetInsertPoint(IPBB); 1752*e038c9c4Sjoerg CodeGenFunction::JumpDest Dest = CGF.getJumpDestInCurrentScope(DestBB); 1753*e038c9c4Sjoerg CGF.EmitBranchThroughCleanup(Dest); 1754*e038c9c4Sjoerg } 1755*e038c9c4Sjoerg 1756*e038c9c4Sjoerg /// Emit the body of an OMP region 1757*e038c9c4Sjoerg /// \param CGF The Codegen function this belongs to 1758*e038c9c4Sjoerg /// \param RegionBodyStmt The body statement for the OpenMP region being 1759*e038c9c4Sjoerg /// generated 1760*e038c9c4Sjoerg /// \param CodeGenIP Insertion point for generating the body code. 1761*e038c9c4Sjoerg /// \param FiniBB The finalization basic block 1762*e038c9c4Sjoerg static void EmitOMPRegionBody(CodeGenFunction &CGF, 1763*e038c9c4Sjoerg const Stmt *RegionBodyStmt, 1764*e038c9c4Sjoerg InsertPointTy CodeGenIP, 1765*e038c9c4Sjoerg llvm::BasicBlock &FiniBB) { 1766*e038c9c4Sjoerg llvm::BasicBlock *CodeGenIPBB = CodeGenIP.getBlock(); 1767*e038c9c4Sjoerg if (llvm::Instruction *CodeGenIPBBTI = CodeGenIPBB->getTerminator()) 1768*e038c9c4Sjoerg CodeGenIPBBTI->eraseFromParent(); 1769*e038c9c4Sjoerg 1770*e038c9c4Sjoerg CGF.Builder.SetInsertPoint(CodeGenIPBB); 1771*e038c9c4Sjoerg 1772*e038c9c4Sjoerg CGF.EmitStmt(RegionBodyStmt); 1773*e038c9c4Sjoerg 1774*e038c9c4Sjoerg if (CGF.Builder.saveIP().isSet()) 1775*e038c9c4Sjoerg CGF.Builder.CreateBr(&FiniBB); 1776*e038c9c4Sjoerg } 1777*e038c9c4Sjoerg 1778*e038c9c4Sjoerg /// RAII for preserving necessary info during Outlined region body codegen. 1779*e038c9c4Sjoerg class OutlinedRegionBodyRAII { 1780*e038c9c4Sjoerg 1781*e038c9c4Sjoerg llvm::AssertingVH<llvm::Instruction> OldAllocaIP; 1782*e038c9c4Sjoerg CodeGenFunction::JumpDest OldReturnBlock; 1783*e038c9c4Sjoerg CGBuilderTy::InsertPoint IP; 1784*e038c9c4Sjoerg CodeGenFunction &CGF; 1785*e038c9c4Sjoerg 1786*e038c9c4Sjoerg public: 1787*e038c9c4Sjoerg OutlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP, 1788*e038c9c4Sjoerg llvm::BasicBlock &RetBB) 1789*e038c9c4Sjoerg : CGF(cgf) { 1790*e038c9c4Sjoerg assert(AllocaIP.isSet() && 1791*e038c9c4Sjoerg "Must specify Insertion point for allocas of outlined function"); 1792*e038c9c4Sjoerg OldAllocaIP = CGF.AllocaInsertPt; 1793*e038c9c4Sjoerg CGF.AllocaInsertPt = &*AllocaIP.getPoint(); 1794*e038c9c4Sjoerg IP = CGF.Builder.saveIP(); 1795*e038c9c4Sjoerg 1796*e038c9c4Sjoerg OldReturnBlock = CGF.ReturnBlock; 1797*e038c9c4Sjoerg CGF.ReturnBlock = CGF.getJumpDestInCurrentScope(&RetBB); 1798*e038c9c4Sjoerg } 1799*e038c9c4Sjoerg 1800*e038c9c4Sjoerg ~OutlinedRegionBodyRAII() { 1801*e038c9c4Sjoerg CGF.AllocaInsertPt = OldAllocaIP; 1802*e038c9c4Sjoerg CGF.ReturnBlock = OldReturnBlock; 1803*e038c9c4Sjoerg CGF.Builder.restoreIP(IP); 1804*e038c9c4Sjoerg } 1805*e038c9c4Sjoerg }; 1806*e038c9c4Sjoerg 1807*e038c9c4Sjoerg /// RAII for preserving necessary info during inlined region body codegen. 1808*e038c9c4Sjoerg class InlinedRegionBodyRAII { 1809*e038c9c4Sjoerg 1810*e038c9c4Sjoerg llvm::AssertingVH<llvm::Instruction> OldAllocaIP; 1811*e038c9c4Sjoerg CodeGenFunction &CGF; 1812*e038c9c4Sjoerg 1813*e038c9c4Sjoerg public: 1814*e038c9c4Sjoerg InlinedRegionBodyRAII(CodeGenFunction &cgf, InsertPointTy &AllocaIP, 1815*e038c9c4Sjoerg llvm::BasicBlock &FiniBB) 1816*e038c9c4Sjoerg : CGF(cgf) { 1817*e038c9c4Sjoerg // Alloca insertion block should be in the entry block of the containing 1818*e038c9c4Sjoerg // function so it expects an empty AllocaIP in which case will reuse the 1819*e038c9c4Sjoerg // old alloca insertion point, or a new AllocaIP in the same block as 1820*e038c9c4Sjoerg // the old one 1821*e038c9c4Sjoerg assert((!AllocaIP.isSet() || 1822*e038c9c4Sjoerg CGF.AllocaInsertPt->getParent() == AllocaIP.getBlock()) && 1823*e038c9c4Sjoerg "Insertion point should be in the entry block of containing " 1824*e038c9c4Sjoerg "function!"); 1825*e038c9c4Sjoerg OldAllocaIP = CGF.AllocaInsertPt; 1826*e038c9c4Sjoerg if (AllocaIP.isSet()) 1827*e038c9c4Sjoerg CGF.AllocaInsertPt = &*AllocaIP.getPoint(); 1828*e038c9c4Sjoerg 1829*e038c9c4Sjoerg // TODO: Remove the call, after making sure the counter is not used by 1830*e038c9c4Sjoerg // the EHStack. 1831*e038c9c4Sjoerg // Since this is an inlined region, it should not modify the 1832*e038c9c4Sjoerg // ReturnBlock, and should reuse the one for the enclosing outlined 1833*e038c9c4Sjoerg // region. So, the JumpDest being return by the function is discarded 1834*e038c9c4Sjoerg (void)CGF.getJumpDestInCurrentScope(&FiniBB); 1835*e038c9c4Sjoerg } 1836*e038c9c4Sjoerg 1837*e038c9c4Sjoerg ~InlinedRegionBodyRAII() { CGF.AllocaInsertPt = OldAllocaIP; } 1838*e038c9c4Sjoerg }; 1839*e038c9c4Sjoerg }; 1840*e038c9c4Sjoerg 18417330f729Sjoerg private: 18427330f729Sjoerg /// CXXThisDecl - When generating code for a C++ member function, 18437330f729Sjoerg /// this will hold the implicit 'this' declaration. 18447330f729Sjoerg ImplicitParamDecl *CXXABIThisDecl = nullptr; 18457330f729Sjoerg llvm::Value *CXXABIThisValue = nullptr; 18467330f729Sjoerg llvm::Value *CXXThisValue = nullptr; 18477330f729Sjoerg CharUnits CXXABIThisAlignment; 18487330f729Sjoerg CharUnits CXXThisAlignment; 18497330f729Sjoerg 18507330f729Sjoerg /// The value of 'this' to use when evaluating CXXDefaultInitExprs within 18517330f729Sjoerg /// this expression. 18527330f729Sjoerg Address CXXDefaultInitExprThis = Address::invalid(); 18537330f729Sjoerg 18547330f729Sjoerg /// The current array initialization index when evaluating an 18557330f729Sjoerg /// ArrayInitIndexExpr within an ArrayInitLoopExpr. 18567330f729Sjoerg llvm::Value *ArrayInitIndex = nullptr; 18577330f729Sjoerg 18587330f729Sjoerg /// The values of function arguments to use when evaluating 18597330f729Sjoerg /// CXXInheritedCtorInitExprs within this context. 18607330f729Sjoerg CallArgList CXXInheritedCtorInitExprArgs; 18617330f729Sjoerg 18627330f729Sjoerg /// CXXStructorImplicitParamDecl - When generating code for a constructor or 18637330f729Sjoerg /// destructor, this will hold the implicit argument (e.g. VTT). 18647330f729Sjoerg ImplicitParamDecl *CXXStructorImplicitParamDecl = nullptr; 18657330f729Sjoerg llvm::Value *CXXStructorImplicitParamValue = nullptr; 18667330f729Sjoerg 18677330f729Sjoerg /// OutermostConditional - Points to the outermost active 18687330f729Sjoerg /// conditional control. This is used so that we know if a 18697330f729Sjoerg /// temporary should be destroyed conditionally. 18707330f729Sjoerg ConditionalEvaluation *OutermostConditional = nullptr; 18717330f729Sjoerg 18727330f729Sjoerg /// The current lexical scope. 18737330f729Sjoerg LexicalScope *CurLexicalScope = nullptr; 18747330f729Sjoerg 18757330f729Sjoerg /// The current source location that should be used for exception 18767330f729Sjoerg /// handling code. 18777330f729Sjoerg SourceLocation CurEHLocation; 18787330f729Sjoerg 18797330f729Sjoerg /// BlockByrefInfos - For each __block variable, contains 18807330f729Sjoerg /// information about the layout of the variable. 18817330f729Sjoerg llvm::DenseMap<const ValueDecl *, BlockByrefInfo> BlockByrefInfos; 18827330f729Sjoerg 18837330f729Sjoerg /// Used by -fsanitize=nullability-return to determine whether the return 18847330f729Sjoerg /// value can be checked. 18857330f729Sjoerg llvm::Value *RetValNullabilityPrecondition = nullptr; 18867330f729Sjoerg 18877330f729Sjoerg /// Check if -fsanitize=nullability-return instrumentation is required for 18887330f729Sjoerg /// this function. 18897330f729Sjoerg bool requiresReturnValueNullabilityCheck() const { 18907330f729Sjoerg return RetValNullabilityPrecondition; 18917330f729Sjoerg } 18927330f729Sjoerg 18937330f729Sjoerg /// Used to store precise source locations for return statements by the 18947330f729Sjoerg /// runtime return value checks. 18957330f729Sjoerg Address ReturnLocation = Address::invalid(); 18967330f729Sjoerg 18977330f729Sjoerg /// Check if the return value of this function requires sanitization. 1898*e038c9c4Sjoerg bool requiresReturnValueCheck() const; 18997330f729Sjoerg 19007330f729Sjoerg llvm::BasicBlock *TerminateLandingPad = nullptr; 19017330f729Sjoerg llvm::BasicBlock *TerminateHandler = nullptr; 1902*e038c9c4Sjoerg llvm::SmallVector<llvm::BasicBlock *, 2> TrapBBs; 19037330f729Sjoerg 19047330f729Sjoerg /// Terminate funclets keyed by parent funclet pad. 19057330f729Sjoerg llvm::MapVector<llvm::Value *, llvm::BasicBlock *> TerminateFunclets; 19067330f729Sjoerg 19077330f729Sjoerg /// Largest vector width used in ths function. Will be used to create a 19087330f729Sjoerg /// function attribute. 19097330f729Sjoerg unsigned LargestVectorWidth = 0; 19107330f729Sjoerg 1911*e038c9c4Sjoerg /// True if we need emit the life-time markers. This is initially set in 1912*e038c9c4Sjoerg /// the constructor, but could be overwritten to true if this is a coroutine. 1913*e038c9c4Sjoerg bool ShouldEmitLifetimeMarkers; 19147330f729Sjoerg 19157330f729Sjoerg /// Add OpenCL kernel arg metadata and the kernel attribute metadata to 19167330f729Sjoerg /// the function metadata. 19177330f729Sjoerg void EmitOpenCLKernelMetadata(const FunctionDecl *FD, 19187330f729Sjoerg llvm::Function *Fn); 19197330f729Sjoerg 19207330f729Sjoerg public: 19217330f729Sjoerg CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext=false); 19227330f729Sjoerg ~CodeGenFunction(); 19237330f729Sjoerg 19247330f729Sjoerg CodeGenTypes &getTypes() const { return CGM.getTypes(); } 19257330f729Sjoerg ASTContext &getContext() const { return CGM.getContext(); } 19267330f729Sjoerg CGDebugInfo *getDebugInfo() { 19277330f729Sjoerg if (DisableDebugInfo) 19287330f729Sjoerg return nullptr; 19297330f729Sjoerg return DebugInfo; 19307330f729Sjoerg } 19317330f729Sjoerg void disableDebugInfo() { DisableDebugInfo = true; } 19327330f729Sjoerg void enableDebugInfo() { DisableDebugInfo = false; } 19337330f729Sjoerg 19347330f729Sjoerg bool shouldUseFusedARCCalls() { 19357330f729Sjoerg return CGM.getCodeGenOpts().OptimizationLevel == 0; 19367330f729Sjoerg } 19377330f729Sjoerg 19387330f729Sjoerg const LangOptions &getLangOpts() const { return CGM.getLangOpts(); } 19397330f729Sjoerg 19407330f729Sjoerg /// Returns a pointer to the function's exception object and selector slot, 19417330f729Sjoerg /// which is assigned in every landing pad. 19427330f729Sjoerg Address getExceptionSlot(); 19437330f729Sjoerg Address getEHSelectorSlot(); 19447330f729Sjoerg 19457330f729Sjoerg /// Returns the contents of the function's exception object and selector 19467330f729Sjoerg /// slots. 19477330f729Sjoerg llvm::Value *getExceptionFromSlot(); 19487330f729Sjoerg llvm::Value *getSelectorFromSlot(); 19497330f729Sjoerg 19507330f729Sjoerg Address getNormalCleanupDestSlot(); 19517330f729Sjoerg 19527330f729Sjoerg llvm::BasicBlock *getUnreachableBlock() { 19537330f729Sjoerg if (!UnreachableBlock) { 19547330f729Sjoerg UnreachableBlock = createBasicBlock("unreachable"); 19557330f729Sjoerg new llvm::UnreachableInst(getLLVMContext(), UnreachableBlock); 19567330f729Sjoerg } 19577330f729Sjoerg return UnreachableBlock; 19587330f729Sjoerg } 19597330f729Sjoerg 19607330f729Sjoerg llvm::BasicBlock *getInvokeDest() { 19617330f729Sjoerg if (!EHStack.requiresLandingPad()) return nullptr; 19627330f729Sjoerg return getInvokeDestImpl(); 19637330f729Sjoerg } 19647330f729Sjoerg 19657330f729Sjoerg bool currentFunctionUsesSEHTry() const { return CurSEHParent != nullptr; } 19667330f729Sjoerg 19677330f729Sjoerg const TargetInfo &getTarget() const { return Target; } 19687330f729Sjoerg llvm::LLVMContext &getLLVMContext() { return CGM.getLLVMContext(); } 19697330f729Sjoerg const TargetCodeGenInfo &getTargetHooks() const { 19707330f729Sjoerg return CGM.getTargetCodeGenInfo(); 19717330f729Sjoerg } 19727330f729Sjoerg 19737330f729Sjoerg //===--------------------------------------------------------------------===// 19747330f729Sjoerg // Cleanups 19757330f729Sjoerg //===--------------------------------------------------------------------===// 19767330f729Sjoerg 19777330f729Sjoerg typedef void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty); 19787330f729Sjoerg 19797330f729Sjoerg void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, 19807330f729Sjoerg Address arrayEndPointer, 19817330f729Sjoerg QualType elementType, 19827330f729Sjoerg CharUnits elementAlignment, 19837330f729Sjoerg Destroyer *destroyer); 19847330f729Sjoerg void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, 19857330f729Sjoerg llvm::Value *arrayEnd, 19867330f729Sjoerg QualType elementType, 19877330f729Sjoerg CharUnits elementAlignment, 19887330f729Sjoerg Destroyer *destroyer); 19897330f729Sjoerg 19907330f729Sjoerg void pushDestroy(QualType::DestructionKind dtorKind, 19917330f729Sjoerg Address addr, QualType type); 19927330f729Sjoerg void pushEHDestroy(QualType::DestructionKind dtorKind, 19937330f729Sjoerg Address addr, QualType type); 19947330f729Sjoerg void pushDestroy(CleanupKind kind, Address addr, QualType type, 19957330f729Sjoerg Destroyer *destroyer, bool useEHCleanupForArray); 19967330f729Sjoerg void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, 19977330f729Sjoerg QualType type, Destroyer *destroyer, 19987330f729Sjoerg bool useEHCleanupForArray); 19997330f729Sjoerg void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, 20007330f729Sjoerg llvm::Value *CompletePtr, 20017330f729Sjoerg QualType ElementType); 20027330f729Sjoerg void pushStackRestore(CleanupKind kind, Address SPMem); 20037330f729Sjoerg void emitDestroy(Address addr, QualType type, Destroyer *destroyer, 20047330f729Sjoerg bool useEHCleanupForArray); 20057330f729Sjoerg llvm::Function *generateDestroyHelper(Address addr, QualType type, 20067330f729Sjoerg Destroyer *destroyer, 20077330f729Sjoerg bool useEHCleanupForArray, 20087330f729Sjoerg const VarDecl *VD); 20097330f729Sjoerg void emitArrayDestroy(llvm::Value *begin, llvm::Value *end, 20107330f729Sjoerg QualType elementType, CharUnits elementAlign, 20117330f729Sjoerg Destroyer *destroyer, 20127330f729Sjoerg bool checkZeroLength, bool useEHCleanup); 20137330f729Sjoerg 20147330f729Sjoerg Destroyer *getDestroyer(QualType::DestructionKind destructionKind); 20157330f729Sjoerg 20167330f729Sjoerg /// Determines whether an EH cleanup is required to destroy a type 20177330f729Sjoerg /// with the given destruction kind. 20187330f729Sjoerg bool needsEHCleanup(QualType::DestructionKind kind) { 20197330f729Sjoerg switch (kind) { 20207330f729Sjoerg case QualType::DK_none: 20217330f729Sjoerg return false; 20227330f729Sjoerg case QualType::DK_cxx_destructor: 20237330f729Sjoerg case QualType::DK_objc_weak_lifetime: 20247330f729Sjoerg case QualType::DK_nontrivial_c_struct: 20257330f729Sjoerg return getLangOpts().Exceptions; 20267330f729Sjoerg case QualType::DK_objc_strong_lifetime: 20277330f729Sjoerg return getLangOpts().Exceptions && 20287330f729Sjoerg CGM.getCodeGenOpts().ObjCAutoRefCountExceptions; 20297330f729Sjoerg } 20307330f729Sjoerg llvm_unreachable("bad destruction kind"); 20317330f729Sjoerg } 20327330f729Sjoerg 20337330f729Sjoerg CleanupKind getCleanupKind(QualType::DestructionKind kind) { 20347330f729Sjoerg return (needsEHCleanup(kind) ? NormalAndEHCleanup : NormalCleanup); 20357330f729Sjoerg } 20367330f729Sjoerg 20377330f729Sjoerg //===--------------------------------------------------------------------===// 20387330f729Sjoerg // Objective-C 20397330f729Sjoerg //===--------------------------------------------------------------------===// 20407330f729Sjoerg 20417330f729Sjoerg void GenerateObjCMethod(const ObjCMethodDecl *OMD); 20427330f729Sjoerg 20437330f729Sjoerg void StartObjCMethod(const ObjCMethodDecl *MD, const ObjCContainerDecl *CD); 20447330f729Sjoerg 20457330f729Sjoerg /// GenerateObjCGetter - Synthesize an Objective-C property getter function. 20467330f729Sjoerg void GenerateObjCGetter(ObjCImplementationDecl *IMP, 20477330f729Sjoerg const ObjCPropertyImplDecl *PID); 20487330f729Sjoerg void generateObjCGetterBody(const ObjCImplementationDecl *classImpl, 20497330f729Sjoerg const ObjCPropertyImplDecl *propImpl, 20507330f729Sjoerg const ObjCMethodDecl *GetterMothodDecl, 20517330f729Sjoerg llvm::Constant *AtomicHelperFn); 20527330f729Sjoerg 20537330f729Sjoerg void GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, 20547330f729Sjoerg ObjCMethodDecl *MD, bool ctor); 20557330f729Sjoerg 20567330f729Sjoerg /// GenerateObjCSetter - Synthesize an Objective-C property setter function 20577330f729Sjoerg /// for the given property. 20587330f729Sjoerg void GenerateObjCSetter(ObjCImplementationDecl *IMP, 20597330f729Sjoerg const ObjCPropertyImplDecl *PID); 20607330f729Sjoerg void generateObjCSetterBody(const ObjCImplementationDecl *classImpl, 20617330f729Sjoerg const ObjCPropertyImplDecl *propImpl, 20627330f729Sjoerg llvm::Constant *AtomicHelperFn); 20637330f729Sjoerg 20647330f729Sjoerg //===--------------------------------------------------------------------===// 20657330f729Sjoerg // Block Bits 20667330f729Sjoerg //===--------------------------------------------------------------------===// 20677330f729Sjoerg 20687330f729Sjoerg /// Emit block literal. 20697330f729Sjoerg /// \return an LLVM value which is a pointer to a struct which contains 20707330f729Sjoerg /// information about the block, including the block invoke function, the 20717330f729Sjoerg /// captured variables, etc. 20727330f729Sjoerg llvm::Value *EmitBlockLiteral(const BlockExpr *); 20737330f729Sjoerg 20747330f729Sjoerg llvm::Function *GenerateBlockFunction(GlobalDecl GD, 20757330f729Sjoerg const CGBlockInfo &Info, 20767330f729Sjoerg const DeclMapTy &ldm, 20777330f729Sjoerg bool IsLambdaConversionToBlock, 20787330f729Sjoerg bool BuildGlobalBlock); 20797330f729Sjoerg 20807330f729Sjoerg /// Check if \p T is a C++ class that has a destructor that can throw. 20817330f729Sjoerg static bool cxxDestructorCanThrow(QualType T); 20827330f729Sjoerg 20837330f729Sjoerg llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo); 20847330f729Sjoerg llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo); 20857330f729Sjoerg llvm::Constant *GenerateObjCAtomicSetterCopyHelperFunction( 20867330f729Sjoerg const ObjCPropertyImplDecl *PID); 20877330f729Sjoerg llvm::Constant *GenerateObjCAtomicGetterCopyHelperFunction( 20887330f729Sjoerg const ObjCPropertyImplDecl *PID); 20897330f729Sjoerg llvm::Value *EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty); 20907330f729Sjoerg 20917330f729Sjoerg void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags, 20927330f729Sjoerg bool CanThrow); 20937330f729Sjoerg 20947330f729Sjoerg class AutoVarEmission; 20957330f729Sjoerg 20967330f729Sjoerg void emitByrefStructureInit(const AutoVarEmission &emission); 20977330f729Sjoerg 20987330f729Sjoerg /// Enter a cleanup to destroy a __block variable. Note that this 20997330f729Sjoerg /// cleanup should be a no-op if the variable hasn't left the stack 21007330f729Sjoerg /// yet; if a cleanup is required for the variable itself, that needs 21017330f729Sjoerg /// to be done externally. 21027330f729Sjoerg /// 21037330f729Sjoerg /// \param Kind Cleanup kind. 21047330f729Sjoerg /// 21057330f729Sjoerg /// \param Addr When \p LoadBlockVarAddr is false, the address of the __block 21067330f729Sjoerg /// structure that will be passed to _Block_object_dispose. When 21077330f729Sjoerg /// \p LoadBlockVarAddr is true, the address of the field of the block 21087330f729Sjoerg /// structure that holds the address of the __block structure. 21097330f729Sjoerg /// 21107330f729Sjoerg /// \param Flags The flag that will be passed to _Block_object_dispose. 21117330f729Sjoerg /// 21127330f729Sjoerg /// \param LoadBlockVarAddr Indicates whether we need to emit a load from 21137330f729Sjoerg /// \p Addr to get the address of the __block structure. 21147330f729Sjoerg void enterByrefCleanup(CleanupKind Kind, Address Addr, BlockFieldFlags Flags, 21157330f729Sjoerg bool LoadBlockVarAddr, bool CanThrow); 21167330f729Sjoerg 21177330f729Sjoerg void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum, 21187330f729Sjoerg llvm::Value *ptr); 21197330f729Sjoerg 21207330f729Sjoerg Address LoadBlockStruct(); 21217330f729Sjoerg Address GetAddrOfBlockDecl(const VarDecl *var); 21227330f729Sjoerg 21237330f729Sjoerg /// BuildBlockByrefAddress - Computes the location of the 21247330f729Sjoerg /// data in a variable which is declared as __block. 21257330f729Sjoerg Address emitBlockByrefAddress(Address baseAddr, const VarDecl *V, 21267330f729Sjoerg bool followForward = true); 21277330f729Sjoerg Address emitBlockByrefAddress(Address baseAddr, 21287330f729Sjoerg const BlockByrefInfo &info, 21297330f729Sjoerg bool followForward, 21307330f729Sjoerg const llvm::Twine &name); 21317330f729Sjoerg 21327330f729Sjoerg const BlockByrefInfo &getBlockByrefInfo(const VarDecl *var); 21337330f729Sjoerg 21347330f729Sjoerg QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args); 21357330f729Sjoerg 21367330f729Sjoerg void GenerateCode(GlobalDecl GD, llvm::Function *Fn, 21377330f729Sjoerg const CGFunctionInfo &FnInfo); 21387330f729Sjoerg 21397330f729Sjoerg /// Annotate the function with an attribute that disables TSan checking at 21407330f729Sjoerg /// runtime. 21417330f729Sjoerg void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn); 21427330f729Sjoerg 21437330f729Sjoerg /// Emit code for the start of a function. 21447330f729Sjoerg /// \param Loc The location to be associated with the function. 21457330f729Sjoerg /// \param StartLoc The location of the function body. 21467330f729Sjoerg void StartFunction(GlobalDecl GD, 21477330f729Sjoerg QualType RetTy, 21487330f729Sjoerg llvm::Function *Fn, 21497330f729Sjoerg const CGFunctionInfo &FnInfo, 21507330f729Sjoerg const FunctionArgList &Args, 21517330f729Sjoerg SourceLocation Loc = SourceLocation(), 21527330f729Sjoerg SourceLocation StartLoc = SourceLocation()); 21537330f729Sjoerg 21547330f729Sjoerg static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor); 21557330f729Sjoerg 21567330f729Sjoerg void EmitConstructorBody(FunctionArgList &Args); 21577330f729Sjoerg void EmitDestructorBody(FunctionArgList &Args); 21587330f729Sjoerg void emitImplicitAssignmentOperatorBody(FunctionArgList &Args); 21597330f729Sjoerg void EmitFunctionBody(const Stmt *Body); 21607330f729Sjoerg void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S); 21617330f729Sjoerg 21627330f729Sjoerg void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator, 21637330f729Sjoerg CallArgList &CallArgs); 21647330f729Sjoerg void EmitLambdaBlockInvokeBody(); 21657330f729Sjoerg void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD); 21667330f729Sjoerg void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD); 21677330f729Sjoerg void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV) { 21687330f729Sjoerg EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV); 21697330f729Sjoerg } 21707330f729Sjoerg void EmitAsanPrologueOrEpilogue(bool Prologue); 21717330f729Sjoerg 21727330f729Sjoerg /// Emit the unified return block, trying to avoid its emission when 21737330f729Sjoerg /// possible. 21747330f729Sjoerg /// \return The debug location of the user written return statement if the 21757330f729Sjoerg /// return block is is avoided. 21767330f729Sjoerg llvm::DebugLoc EmitReturnBlock(); 21777330f729Sjoerg 21787330f729Sjoerg /// FinishFunction - Complete IR generation of the current function. It is 21797330f729Sjoerg /// legal to call this function even if there is no current insertion point. 21807330f729Sjoerg void FinishFunction(SourceLocation EndLoc=SourceLocation()); 21817330f729Sjoerg 21827330f729Sjoerg void StartThunk(llvm::Function *Fn, GlobalDecl GD, 21837330f729Sjoerg const CGFunctionInfo &FnInfo, bool IsUnprototyped); 21847330f729Sjoerg 21857330f729Sjoerg void EmitCallAndReturnForThunk(llvm::FunctionCallee Callee, 21867330f729Sjoerg const ThunkInfo *Thunk, bool IsUnprototyped); 21877330f729Sjoerg 21887330f729Sjoerg void FinishThunk(); 21897330f729Sjoerg 21907330f729Sjoerg /// Emit a musttail call for a thunk with a potentially adjusted this pointer. 21917330f729Sjoerg void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, 21927330f729Sjoerg llvm::FunctionCallee Callee); 21937330f729Sjoerg 21947330f729Sjoerg /// Generate a thunk for the given method. 21957330f729Sjoerg void generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo, 21967330f729Sjoerg GlobalDecl GD, const ThunkInfo &Thunk, 21977330f729Sjoerg bool IsUnprototyped); 21987330f729Sjoerg 21997330f729Sjoerg llvm::Function *GenerateVarArgsThunk(llvm::Function *Fn, 22007330f729Sjoerg const CGFunctionInfo &FnInfo, 22017330f729Sjoerg GlobalDecl GD, const ThunkInfo &Thunk); 22027330f729Sjoerg 22037330f729Sjoerg void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type, 22047330f729Sjoerg FunctionArgList &Args); 22057330f729Sjoerg 22067330f729Sjoerg void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init); 22077330f729Sjoerg 22087330f729Sjoerg /// Struct with all information about dynamic [sub]class needed to set vptr. 22097330f729Sjoerg struct VPtr { 22107330f729Sjoerg BaseSubobject Base; 22117330f729Sjoerg const CXXRecordDecl *NearestVBase; 22127330f729Sjoerg CharUnits OffsetFromNearestVBase; 22137330f729Sjoerg const CXXRecordDecl *VTableClass; 22147330f729Sjoerg }; 22157330f729Sjoerg 22167330f729Sjoerg /// Initialize the vtable pointer of the given subobject. 22177330f729Sjoerg void InitializeVTablePointer(const VPtr &vptr); 22187330f729Sjoerg 22197330f729Sjoerg typedef llvm::SmallVector<VPtr, 4> VPtrsVector; 22207330f729Sjoerg 22217330f729Sjoerg typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy; 22227330f729Sjoerg VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass); 22237330f729Sjoerg 22247330f729Sjoerg void getVTablePointers(BaseSubobject Base, const CXXRecordDecl *NearestVBase, 22257330f729Sjoerg CharUnits OffsetFromNearestVBase, 22267330f729Sjoerg bool BaseIsNonVirtualPrimaryBase, 22277330f729Sjoerg const CXXRecordDecl *VTableClass, 22287330f729Sjoerg VisitedVirtualBasesSetTy &VBases, VPtrsVector &vptrs); 22297330f729Sjoerg 22307330f729Sjoerg void InitializeVTablePointers(const CXXRecordDecl *ClassDecl); 22317330f729Sjoerg 22327330f729Sjoerg /// GetVTablePtr - Return the Value of the vtable pointer member pointed 22337330f729Sjoerg /// to by This. 22347330f729Sjoerg llvm::Value *GetVTablePtr(Address This, llvm::Type *VTableTy, 22357330f729Sjoerg const CXXRecordDecl *VTableClass); 22367330f729Sjoerg 22377330f729Sjoerg enum CFITypeCheckKind { 22387330f729Sjoerg CFITCK_VCall, 22397330f729Sjoerg CFITCK_NVCall, 22407330f729Sjoerg CFITCK_DerivedCast, 22417330f729Sjoerg CFITCK_UnrelatedCast, 22427330f729Sjoerg CFITCK_ICall, 22437330f729Sjoerg CFITCK_NVMFCall, 22447330f729Sjoerg CFITCK_VMFCall, 22457330f729Sjoerg }; 22467330f729Sjoerg 22477330f729Sjoerg /// Derived is the presumed address of an object of type T after a 22487330f729Sjoerg /// cast. If T is a polymorphic class type, emit a check that the virtual 22497330f729Sjoerg /// table for Derived belongs to a class derived from T. 22507330f729Sjoerg void EmitVTablePtrCheckForCast(QualType T, llvm::Value *Derived, 22517330f729Sjoerg bool MayBeNull, CFITypeCheckKind TCK, 22527330f729Sjoerg SourceLocation Loc); 22537330f729Sjoerg 22547330f729Sjoerg /// EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable. 22557330f729Sjoerg /// If vptr CFI is enabled, emit a check that VTable is valid. 22567330f729Sjoerg void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable, 22577330f729Sjoerg CFITypeCheckKind TCK, SourceLocation Loc); 22587330f729Sjoerg 22597330f729Sjoerg /// EmitVTablePtrCheck - Emit a check that VTable is a valid virtual table for 22607330f729Sjoerg /// RD using llvm.type.test. 22617330f729Sjoerg void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable, 22627330f729Sjoerg CFITypeCheckKind TCK, SourceLocation Loc); 22637330f729Sjoerg 22647330f729Sjoerg /// If whole-program virtual table optimization is enabled, emit an assumption 22657330f729Sjoerg /// that VTable is a member of RD's type identifier. Or, if vptr CFI is 22667330f729Sjoerg /// enabled, emit a check that VTable is a member of RD's type identifier. 22677330f729Sjoerg void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, 22687330f729Sjoerg llvm::Value *VTable, SourceLocation Loc); 22697330f729Sjoerg 22707330f729Sjoerg /// Returns whether we should perform a type checked load when loading a 22717330f729Sjoerg /// virtual function for virtual calls to members of RD. This is generally 22727330f729Sjoerg /// true when both vcall CFI and whole-program-vtables are enabled. 22737330f729Sjoerg bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD); 22747330f729Sjoerg 22757330f729Sjoerg /// Emit a type checked load from the given vtable. 22767330f729Sjoerg llvm::Value *EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, 22777330f729Sjoerg uint64_t VTableByteOffset); 22787330f729Sjoerg 22797330f729Sjoerg /// EnterDtorCleanups - Enter the cleanups necessary to complete the 22807330f729Sjoerg /// given phase of destruction for a destructor. The end result 22817330f729Sjoerg /// should call destructors on members and base classes in reverse 22827330f729Sjoerg /// order of their construction. 22837330f729Sjoerg void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type); 22847330f729Sjoerg 22857330f729Sjoerg /// ShouldInstrumentFunction - Return true if the current function should be 22867330f729Sjoerg /// instrumented with __cyg_profile_func_* calls 22877330f729Sjoerg bool ShouldInstrumentFunction(); 22887330f729Sjoerg 22897330f729Sjoerg /// ShouldXRayInstrument - Return true if the current function should be 22907330f729Sjoerg /// instrumented with XRay nop sleds. 22917330f729Sjoerg bool ShouldXRayInstrumentFunction() const; 22927330f729Sjoerg 22937330f729Sjoerg /// AlwaysEmitXRayCustomEvents - Return true if we must unconditionally emit 22947330f729Sjoerg /// XRay custom event handling calls. 22957330f729Sjoerg bool AlwaysEmitXRayCustomEvents() const; 22967330f729Sjoerg 22977330f729Sjoerg /// AlwaysEmitXRayTypedEvents - Return true if clang must unconditionally emit 22987330f729Sjoerg /// XRay typed event handling calls. 22997330f729Sjoerg bool AlwaysEmitXRayTypedEvents() const; 23007330f729Sjoerg 23017330f729Sjoerg /// Encode an address into a form suitable for use in a function prologue. 23027330f729Sjoerg llvm::Constant *EncodeAddrForUseInPrologue(llvm::Function *F, 23037330f729Sjoerg llvm::Constant *Addr); 23047330f729Sjoerg 23057330f729Sjoerg /// Decode an address used in a function prologue, encoded by \c 23067330f729Sjoerg /// EncodeAddrForUseInPrologue. 23077330f729Sjoerg llvm::Value *DecodeAddrUsedInPrologue(llvm::Value *F, 23087330f729Sjoerg llvm::Value *EncodedAddr); 23097330f729Sjoerg 23107330f729Sjoerg /// EmitFunctionProlog - Emit the target specific LLVM code to load the 23117330f729Sjoerg /// arguments for the given function. This is also responsible for naming the 23127330f729Sjoerg /// LLVM function arguments. 23137330f729Sjoerg void EmitFunctionProlog(const CGFunctionInfo &FI, 23147330f729Sjoerg llvm::Function *Fn, 23157330f729Sjoerg const FunctionArgList &Args); 23167330f729Sjoerg 23177330f729Sjoerg /// EmitFunctionEpilog - Emit the target specific LLVM code to return the 23187330f729Sjoerg /// given temporary. 23197330f729Sjoerg void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc, 23207330f729Sjoerg SourceLocation EndLoc); 23217330f729Sjoerg 23227330f729Sjoerg /// Emit a test that checks if the return value \p RV is nonnull. 23237330f729Sjoerg void EmitReturnValueCheck(llvm::Value *RV); 23247330f729Sjoerg 23257330f729Sjoerg /// EmitStartEHSpec - Emit the start of the exception spec. 23267330f729Sjoerg void EmitStartEHSpec(const Decl *D); 23277330f729Sjoerg 23287330f729Sjoerg /// EmitEndEHSpec - Emit the end of the exception spec. 23297330f729Sjoerg void EmitEndEHSpec(const Decl *D); 23307330f729Sjoerg 23317330f729Sjoerg /// getTerminateLandingPad - Return a landing pad that just calls terminate. 23327330f729Sjoerg llvm::BasicBlock *getTerminateLandingPad(); 23337330f729Sjoerg 23347330f729Sjoerg /// getTerminateLandingPad - Return a cleanup funclet that just calls 23357330f729Sjoerg /// terminate. 23367330f729Sjoerg llvm::BasicBlock *getTerminateFunclet(); 23377330f729Sjoerg 23387330f729Sjoerg /// getTerminateHandler - Return a handler (not a landing pad, just 23397330f729Sjoerg /// a catch handler) that just calls terminate. This is used when 23407330f729Sjoerg /// a terminate scope encloses a try. 23417330f729Sjoerg llvm::BasicBlock *getTerminateHandler(); 23427330f729Sjoerg 23437330f729Sjoerg llvm::Type *ConvertTypeForMem(QualType T); 23447330f729Sjoerg llvm::Type *ConvertType(QualType T); 23457330f729Sjoerg llvm::Type *ConvertType(const TypeDecl *T) { 23467330f729Sjoerg return ConvertType(getContext().getTypeDeclType(T)); 23477330f729Sjoerg } 23487330f729Sjoerg 23497330f729Sjoerg /// LoadObjCSelf - Load the value of self. This function is only valid while 23507330f729Sjoerg /// generating code for an Objective-C method. 23517330f729Sjoerg llvm::Value *LoadObjCSelf(); 23527330f729Sjoerg 23537330f729Sjoerg /// TypeOfSelfObject - Return type of object that this self represents. 23547330f729Sjoerg QualType TypeOfSelfObject(); 23557330f729Sjoerg 23567330f729Sjoerg /// getEvaluationKind - Return the TypeEvaluationKind of QualType \c T. 23577330f729Sjoerg static TypeEvaluationKind getEvaluationKind(QualType T); 23587330f729Sjoerg 23597330f729Sjoerg static bool hasScalarEvaluationKind(QualType T) { 23607330f729Sjoerg return getEvaluationKind(T) == TEK_Scalar; 23617330f729Sjoerg } 23627330f729Sjoerg 23637330f729Sjoerg static bool hasAggregateEvaluationKind(QualType T) { 23647330f729Sjoerg return getEvaluationKind(T) == TEK_Aggregate; 23657330f729Sjoerg } 23667330f729Sjoerg 23677330f729Sjoerg /// createBasicBlock - Create an LLVM basic block. 23687330f729Sjoerg llvm::BasicBlock *createBasicBlock(const Twine &name = "", 23697330f729Sjoerg llvm::Function *parent = nullptr, 23707330f729Sjoerg llvm::BasicBlock *before = nullptr) { 23717330f729Sjoerg return llvm::BasicBlock::Create(getLLVMContext(), name, parent, before); 23727330f729Sjoerg } 23737330f729Sjoerg 23747330f729Sjoerg /// getBasicBlockForLabel - Return the LLVM basicblock that the specified 23757330f729Sjoerg /// label maps to. 23767330f729Sjoerg JumpDest getJumpDestForLabel(const LabelDecl *S); 23777330f729Sjoerg 23787330f729Sjoerg /// SimplifyForwardingBlocks - If the given basic block is only a branch to 23797330f729Sjoerg /// another basic block, simplify it. This assumes that no other code could 23807330f729Sjoerg /// potentially reference the basic block. 23817330f729Sjoerg void SimplifyForwardingBlocks(llvm::BasicBlock *BB); 23827330f729Sjoerg 23837330f729Sjoerg /// EmitBlock - Emit the given block \arg BB and set it as the insert point, 23847330f729Sjoerg /// adding a fall-through branch from the current insert block if 23857330f729Sjoerg /// necessary. It is legal to call this function even if there is no current 23867330f729Sjoerg /// insertion point. 23877330f729Sjoerg /// 23887330f729Sjoerg /// IsFinished - If true, indicates that the caller has finished emitting 23897330f729Sjoerg /// branches to the given block and does not expect to emit code into it. This 23907330f729Sjoerg /// means the block can be ignored if it is unreachable. 23917330f729Sjoerg void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false); 23927330f729Sjoerg 23937330f729Sjoerg /// EmitBlockAfterUses - Emit the given block somewhere hopefully 23947330f729Sjoerg /// near its uses, and leave the insertion point in it. 23957330f729Sjoerg void EmitBlockAfterUses(llvm::BasicBlock *BB); 23967330f729Sjoerg 23977330f729Sjoerg /// EmitBranch - Emit a branch to the specified basic block from the current 23987330f729Sjoerg /// insert block, taking care to avoid creation of branches from dummy 23997330f729Sjoerg /// blocks. It is legal to call this function even if there is no current 24007330f729Sjoerg /// insertion point. 24017330f729Sjoerg /// 24027330f729Sjoerg /// This function clears the current insertion point. The caller should follow 24037330f729Sjoerg /// calls to this function with calls to Emit*Block prior to generation new 24047330f729Sjoerg /// code. 24057330f729Sjoerg void EmitBranch(llvm::BasicBlock *Block); 24067330f729Sjoerg 24077330f729Sjoerg /// HaveInsertPoint - True if an insertion point is defined. If not, this 24087330f729Sjoerg /// indicates that the current code being emitted is unreachable. 24097330f729Sjoerg bool HaveInsertPoint() const { 24107330f729Sjoerg return Builder.GetInsertBlock() != nullptr; 24117330f729Sjoerg } 24127330f729Sjoerg 24137330f729Sjoerg /// EnsureInsertPoint - Ensure that an insertion point is defined so that 24147330f729Sjoerg /// emitted IR has a place to go. Note that by definition, if this function 24157330f729Sjoerg /// creates a block then that block is unreachable; callers may do better to 24167330f729Sjoerg /// detect when no insertion point is defined and simply skip IR generation. 24177330f729Sjoerg void EnsureInsertPoint() { 24187330f729Sjoerg if (!HaveInsertPoint()) 24197330f729Sjoerg EmitBlock(createBasicBlock()); 24207330f729Sjoerg } 24217330f729Sjoerg 24227330f729Sjoerg /// ErrorUnsupported - Print out an error that codegen doesn't support the 24237330f729Sjoerg /// specified stmt yet. 24247330f729Sjoerg void ErrorUnsupported(const Stmt *S, const char *Type); 24257330f729Sjoerg 24267330f729Sjoerg //===--------------------------------------------------------------------===// 24277330f729Sjoerg // Helpers 24287330f729Sjoerg //===--------------------------------------------------------------------===// 24297330f729Sjoerg 24307330f729Sjoerg LValue MakeAddrLValue(Address Addr, QualType T, 24317330f729Sjoerg AlignmentSource Source = AlignmentSource::Type) { 24327330f729Sjoerg return LValue::MakeAddr(Addr, T, getContext(), LValueBaseInfo(Source), 24337330f729Sjoerg CGM.getTBAAAccessInfo(T)); 24347330f729Sjoerg } 24357330f729Sjoerg 24367330f729Sjoerg LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo, 24377330f729Sjoerg TBAAAccessInfo TBAAInfo) { 24387330f729Sjoerg return LValue::MakeAddr(Addr, T, getContext(), BaseInfo, TBAAInfo); 24397330f729Sjoerg } 24407330f729Sjoerg 24417330f729Sjoerg LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, 24427330f729Sjoerg AlignmentSource Source = AlignmentSource::Type) { 24437330f729Sjoerg return LValue::MakeAddr(Address(V, Alignment), T, getContext(), 24447330f729Sjoerg LValueBaseInfo(Source), CGM.getTBAAAccessInfo(T)); 24457330f729Sjoerg } 24467330f729Sjoerg 24477330f729Sjoerg LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, 24487330f729Sjoerg LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo) { 24497330f729Sjoerg return LValue::MakeAddr(Address(V, Alignment), T, getContext(), 24507330f729Sjoerg BaseInfo, TBAAInfo); 24517330f729Sjoerg } 24527330f729Sjoerg 24537330f729Sjoerg LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T); 24547330f729Sjoerg LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T); 24557330f729Sjoerg 24567330f729Sjoerg Address EmitLoadOfReference(LValue RefLVal, 24577330f729Sjoerg LValueBaseInfo *PointeeBaseInfo = nullptr, 24587330f729Sjoerg TBAAAccessInfo *PointeeTBAAInfo = nullptr); 24597330f729Sjoerg LValue EmitLoadOfReferenceLValue(LValue RefLVal); 24607330f729Sjoerg LValue EmitLoadOfReferenceLValue(Address RefAddr, QualType RefTy, 24617330f729Sjoerg AlignmentSource Source = 24627330f729Sjoerg AlignmentSource::Type) { 24637330f729Sjoerg LValue RefLVal = MakeAddrLValue(RefAddr, RefTy, LValueBaseInfo(Source), 24647330f729Sjoerg CGM.getTBAAAccessInfo(RefTy)); 24657330f729Sjoerg return EmitLoadOfReferenceLValue(RefLVal); 24667330f729Sjoerg } 24677330f729Sjoerg 24687330f729Sjoerg Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, 24697330f729Sjoerg LValueBaseInfo *BaseInfo = nullptr, 24707330f729Sjoerg TBAAAccessInfo *TBAAInfo = nullptr); 24717330f729Sjoerg LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy); 24727330f729Sjoerg 24737330f729Sjoerg /// CreateTempAlloca - This creates an alloca and inserts it into the entry 24747330f729Sjoerg /// block if \p ArraySize is nullptr, otherwise inserts it at the current 24757330f729Sjoerg /// insertion point of the builder. The caller is responsible for setting an 24767330f729Sjoerg /// appropriate alignment on 24777330f729Sjoerg /// the alloca. 24787330f729Sjoerg /// 24797330f729Sjoerg /// \p ArraySize is the number of array elements to be allocated if it 24807330f729Sjoerg /// is not nullptr. 24817330f729Sjoerg /// 24827330f729Sjoerg /// LangAS::Default is the address space of pointers to local variables and 24837330f729Sjoerg /// temporaries, as exposed in the source language. In certain 24847330f729Sjoerg /// configurations, this is not the same as the alloca address space, and a 24857330f729Sjoerg /// cast is needed to lift the pointer from the alloca AS into 24867330f729Sjoerg /// LangAS::Default. This can happen when the target uses a restricted 24877330f729Sjoerg /// address space for the stack but the source language requires 24887330f729Sjoerg /// LangAS::Default to be a generic address space. The latter condition is 24897330f729Sjoerg /// common for most programming languages; OpenCL is an exception in that 24907330f729Sjoerg /// LangAS::Default is the private address space, which naturally maps 24917330f729Sjoerg /// to the stack. 24927330f729Sjoerg /// 24937330f729Sjoerg /// Because the address of a temporary is often exposed to the program in 24947330f729Sjoerg /// various ways, this function will perform the cast. The original alloca 24957330f729Sjoerg /// instruction is returned through \p Alloca if it is not nullptr. 24967330f729Sjoerg /// 24977330f729Sjoerg /// The cast is not performaed in CreateTempAllocaWithoutCast. This is 24987330f729Sjoerg /// more efficient if the caller knows that the address will not be exposed. 24997330f729Sjoerg llvm::AllocaInst *CreateTempAlloca(llvm::Type *Ty, const Twine &Name = "tmp", 25007330f729Sjoerg llvm::Value *ArraySize = nullptr); 25017330f729Sjoerg Address CreateTempAlloca(llvm::Type *Ty, CharUnits align, 25027330f729Sjoerg const Twine &Name = "tmp", 25037330f729Sjoerg llvm::Value *ArraySize = nullptr, 25047330f729Sjoerg Address *Alloca = nullptr); 25057330f729Sjoerg Address CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align, 25067330f729Sjoerg const Twine &Name = "tmp", 25077330f729Sjoerg llvm::Value *ArraySize = nullptr); 25087330f729Sjoerg 25097330f729Sjoerg /// CreateDefaultAlignedTempAlloca - This creates an alloca with the 25107330f729Sjoerg /// default ABI alignment of the given LLVM type. 25117330f729Sjoerg /// 25127330f729Sjoerg /// IMPORTANT NOTE: This is *not* generally the right alignment for 25137330f729Sjoerg /// any given AST type that happens to have been lowered to the 25147330f729Sjoerg /// given IR type. This should only ever be used for function-local, 25157330f729Sjoerg /// IR-driven manipulations like saving and restoring a value. Do 25167330f729Sjoerg /// not hand this address off to arbitrary IRGen routines, and especially 25177330f729Sjoerg /// do not pass it as an argument to a function that might expect a 25187330f729Sjoerg /// properly ABI-aligned value. 25197330f729Sjoerg Address CreateDefaultAlignTempAlloca(llvm::Type *Ty, 25207330f729Sjoerg const Twine &Name = "tmp"); 25217330f729Sjoerg 25227330f729Sjoerg /// InitTempAlloca - Provide an initial value for the given alloca which 25237330f729Sjoerg /// will be observable at all locations in the function. 25247330f729Sjoerg /// 25257330f729Sjoerg /// The address should be something that was returned from one of 25267330f729Sjoerg /// the CreateTempAlloca or CreateMemTemp routines, and the 25277330f729Sjoerg /// initializer must be valid in the entry block (i.e. it must 25287330f729Sjoerg /// either be a constant or an argument value). 25297330f729Sjoerg void InitTempAlloca(Address Alloca, llvm::Value *Value); 25307330f729Sjoerg 25317330f729Sjoerg /// CreateIRTemp - Create a temporary IR object of the given type, with 25327330f729Sjoerg /// appropriate alignment. This routine should only be used when an temporary 25337330f729Sjoerg /// value needs to be stored into an alloca (for example, to avoid explicit 25347330f729Sjoerg /// PHI construction), but the type is the IR type, not the type appropriate 25357330f729Sjoerg /// for storing in memory. 25367330f729Sjoerg /// 25377330f729Sjoerg /// That is, this is exactly equivalent to CreateMemTemp, but calling 25387330f729Sjoerg /// ConvertType instead of ConvertTypeForMem. 25397330f729Sjoerg Address CreateIRTemp(QualType T, const Twine &Name = "tmp"); 25407330f729Sjoerg 25417330f729Sjoerg /// CreateMemTemp - Create a temporary memory object of the given type, with 25427330f729Sjoerg /// appropriate alignmen and cast it to the default address space. Returns 25437330f729Sjoerg /// the original alloca instruction by \p Alloca if it is not nullptr. 25447330f729Sjoerg Address CreateMemTemp(QualType T, const Twine &Name = "tmp", 25457330f729Sjoerg Address *Alloca = nullptr); 25467330f729Sjoerg Address CreateMemTemp(QualType T, CharUnits Align, const Twine &Name = "tmp", 25477330f729Sjoerg Address *Alloca = nullptr); 25487330f729Sjoerg 25497330f729Sjoerg /// CreateMemTemp - Create a temporary memory object of the given type, with 25507330f729Sjoerg /// appropriate alignmen without casting it to the default address space. 25517330f729Sjoerg Address CreateMemTempWithoutCast(QualType T, const Twine &Name = "tmp"); 25527330f729Sjoerg Address CreateMemTempWithoutCast(QualType T, CharUnits Align, 25537330f729Sjoerg const Twine &Name = "tmp"); 25547330f729Sjoerg 25557330f729Sjoerg /// CreateAggTemp - Create a temporary memory object for the given 25567330f729Sjoerg /// aggregate type. 2557*e038c9c4Sjoerg AggValueSlot CreateAggTemp(QualType T, const Twine &Name = "tmp", 2558*e038c9c4Sjoerg Address *Alloca = nullptr) { 2559*e038c9c4Sjoerg return AggValueSlot::forAddr(CreateMemTemp(T, Name, Alloca), 25607330f729Sjoerg T.getQualifiers(), 25617330f729Sjoerg AggValueSlot::IsNotDestructed, 25627330f729Sjoerg AggValueSlot::DoesNotNeedGCBarriers, 25637330f729Sjoerg AggValueSlot::IsNotAliased, 25647330f729Sjoerg AggValueSlot::DoesNotOverlap); 25657330f729Sjoerg } 25667330f729Sjoerg 25677330f729Sjoerg /// Emit a cast to void* in the appropriate address space. 25687330f729Sjoerg llvm::Value *EmitCastToVoidPtr(llvm::Value *value); 25697330f729Sjoerg 25707330f729Sjoerg /// EvaluateExprAsBool - Perform the usual unary conversions on the specified 25717330f729Sjoerg /// expression and compare the result against zero, returning an Int1Ty value. 25727330f729Sjoerg llvm::Value *EvaluateExprAsBool(const Expr *E); 25737330f729Sjoerg 25747330f729Sjoerg /// EmitIgnoredExpr - Emit an expression in a context which ignores the result. 25757330f729Sjoerg void EmitIgnoredExpr(const Expr *E); 25767330f729Sjoerg 25777330f729Sjoerg /// EmitAnyExpr - Emit code to compute the specified expression which can have 25787330f729Sjoerg /// any type. The result is returned as an RValue struct. If this is an 25797330f729Sjoerg /// aggregate expression, the aggloc/agglocvolatile arguments indicate where 25807330f729Sjoerg /// the result should be returned. 25817330f729Sjoerg /// 25827330f729Sjoerg /// \param ignoreResult True if the resulting value isn't used. 25837330f729Sjoerg RValue EmitAnyExpr(const Expr *E, 25847330f729Sjoerg AggValueSlot aggSlot = AggValueSlot::ignored(), 25857330f729Sjoerg bool ignoreResult = false); 25867330f729Sjoerg 25877330f729Sjoerg // EmitVAListRef - Emit a "reference" to a va_list; this is either the address 25887330f729Sjoerg // or the value of the expression, depending on how va_list is defined. 25897330f729Sjoerg Address EmitVAListRef(const Expr *E); 25907330f729Sjoerg 25917330f729Sjoerg /// Emit a "reference" to a __builtin_ms_va_list; this is 25927330f729Sjoerg /// always the value of the expression, because a __builtin_ms_va_list is a 25937330f729Sjoerg /// pointer to a char. 25947330f729Sjoerg Address EmitMSVAListRef(const Expr *E); 25957330f729Sjoerg 25967330f729Sjoerg /// EmitAnyExprToTemp - Similarly to EmitAnyExpr(), however, the result will 25977330f729Sjoerg /// always be accessible even if no aggregate location is provided. 25987330f729Sjoerg RValue EmitAnyExprToTemp(const Expr *E); 25997330f729Sjoerg 26007330f729Sjoerg /// EmitAnyExprToMem - Emits the code necessary to evaluate an 26017330f729Sjoerg /// arbitrary expression into the given memory location. 26027330f729Sjoerg void EmitAnyExprToMem(const Expr *E, Address Location, 26037330f729Sjoerg Qualifiers Quals, bool IsInitializer); 26047330f729Sjoerg 26057330f729Sjoerg void EmitAnyExprToExn(const Expr *E, Address Addr); 26067330f729Sjoerg 26077330f729Sjoerg /// EmitExprAsInit - Emits the code necessary to initialize a 26087330f729Sjoerg /// location in memory with the given initializer. 26097330f729Sjoerg void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, 26107330f729Sjoerg bool capturedByInit); 26117330f729Sjoerg 26127330f729Sjoerg /// hasVolatileMember - returns true if aggregate type has a volatile 26137330f729Sjoerg /// member. 26147330f729Sjoerg bool hasVolatileMember(QualType T) { 26157330f729Sjoerg if (const RecordType *RT = T->getAs<RecordType>()) { 26167330f729Sjoerg const RecordDecl *RD = cast<RecordDecl>(RT->getDecl()); 26177330f729Sjoerg return RD->hasVolatileMember(); 26187330f729Sjoerg } 26197330f729Sjoerg return false; 26207330f729Sjoerg } 26217330f729Sjoerg 26227330f729Sjoerg /// Determine whether a return value slot may overlap some other object. 26237330f729Sjoerg AggValueSlot::Overlap_t getOverlapForReturnValue() { 26247330f729Sjoerg // FIXME: Assuming no overlap here breaks guaranteed copy elision for base 26257330f729Sjoerg // class subobjects. These cases may need to be revisited depending on the 26267330f729Sjoerg // resolution of the relevant core issue. 26277330f729Sjoerg return AggValueSlot::DoesNotOverlap; 26287330f729Sjoerg } 26297330f729Sjoerg 26307330f729Sjoerg /// Determine whether a field initialization may overlap some other object. 26317330f729Sjoerg AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD); 26327330f729Sjoerg 26337330f729Sjoerg /// Determine whether a base class initialization may overlap some other 26347330f729Sjoerg /// object. 26357330f729Sjoerg AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *RD, 26367330f729Sjoerg const CXXRecordDecl *BaseRD, 26377330f729Sjoerg bool IsVirtual); 26387330f729Sjoerg 26397330f729Sjoerg /// Emit an aggregate assignment. 26407330f729Sjoerg void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy) { 26417330f729Sjoerg bool IsVolatile = hasVolatileMember(EltTy); 26427330f729Sjoerg EmitAggregateCopy(Dest, Src, EltTy, AggValueSlot::MayOverlap, IsVolatile); 26437330f729Sjoerg } 26447330f729Sjoerg 26457330f729Sjoerg void EmitAggregateCopyCtor(LValue Dest, LValue Src, 26467330f729Sjoerg AggValueSlot::Overlap_t MayOverlap) { 26477330f729Sjoerg EmitAggregateCopy(Dest, Src, Src.getType(), MayOverlap); 26487330f729Sjoerg } 26497330f729Sjoerg 26507330f729Sjoerg /// EmitAggregateCopy - Emit an aggregate copy. 26517330f729Sjoerg /// 26527330f729Sjoerg /// \param isVolatile \c true iff either the source or the destination is 26537330f729Sjoerg /// volatile. 26547330f729Sjoerg /// \param MayOverlap Whether the tail padding of the destination might be 26557330f729Sjoerg /// occupied by some other object. More efficient code can often be 26567330f729Sjoerg /// generated if not. 26577330f729Sjoerg void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, 26587330f729Sjoerg AggValueSlot::Overlap_t MayOverlap, 26597330f729Sjoerg bool isVolatile = false); 26607330f729Sjoerg 26617330f729Sjoerg /// GetAddrOfLocalVar - Return the address of a local variable. 26627330f729Sjoerg Address GetAddrOfLocalVar(const VarDecl *VD) { 26637330f729Sjoerg auto it = LocalDeclMap.find(VD); 26647330f729Sjoerg assert(it != LocalDeclMap.end() && 26657330f729Sjoerg "Invalid argument to GetAddrOfLocalVar(), no decl!"); 26667330f729Sjoerg return it->second; 26677330f729Sjoerg } 26687330f729Sjoerg 26697330f729Sjoerg /// Given an opaque value expression, return its LValue mapping if it exists, 26707330f729Sjoerg /// otherwise create one. 26717330f729Sjoerg LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e); 26727330f729Sjoerg 26737330f729Sjoerg /// Given an opaque value expression, return its RValue mapping if it exists, 26747330f729Sjoerg /// otherwise create one. 26757330f729Sjoerg RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e); 26767330f729Sjoerg 26777330f729Sjoerg /// Get the index of the current ArrayInitLoopExpr, if any. 26787330f729Sjoerg llvm::Value *getArrayInitIndex() { return ArrayInitIndex; } 26797330f729Sjoerg 26807330f729Sjoerg /// getAccessedFieldNo - Given an encoded value and a result number, return 26817330f729Sjoerg /// the input field number being accessed. 26827330f729Sjoerg static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts); 26837330f729Sjoerg 26847330f729Sjoerg llvm::BlockAddress *GetAddrOfLabel(const LabelDecl *L); 26857330f729Sjoerg llvm::BasicBlock *GetIndirectGotoBlock(); 26867330f729Sjoerg 26877330f729Sjoerg /// Check if \p E is a C++ "this" pointer wrapped in value-preserving casts. 26887330f729Sjoerg static bool IsWrappedCXXThis(const Expr *E); 26897330f729Sjoerg 26907330f729Sjoerg /// EmitNullInitialization - Generate code to set a value of the given type to 26917330f729Sjoerg /// null, If the type contains data member pointers, they will be initialized 26927330f729Sjoerg /// to -1 in accordance with the Itanium C++ ABI. 26937330f729Sjoerg void EmitNullInitialization(Address DestPtr, QualType Ty); 26947330f729Sjoerg 26957330f729Sjoerg /// Emits a call to an LLVM variable-argument intrinsic, either 26967330f729Sjoerg /// \c llvm.va_start or \c llvm.va_end. 26977330f729Sjoerg /// \param ArgValue A reference to the \c va_list as emitted by either 26987330f729Sjoerg /// \c EmitVAListRef or \c EmitMSVAListRef. 26997330f729Sjoerg /// \param IsStart If \c true, emits a call to \c llvm.va_start; otherwise, 27007330f729Sjoerg /// calls \c llvm.va_end. 27017330f729Sjoerg llvm::Value *EmitVAStartEnd(llvm::Value *ArgValue, bool IsStart); 27027330f729Sjoerg 27037330f729Sjoerg /// Generate code to get an argument from the passed in pointer 27047330f729Sjoerg /// and update it accordingly. 27057330f729Sjoerg /// \param VE The \c VAArgExpr for which to generate code. 27067330f729Sjoerg /// \param VAListAddr Receives a reference to the \c va_list as emitted by 27077330f729Sjoerg /// either \c EmitVAListRef or \c EmitMSVAListRef. 27087330f729Sjoerg /// \returns A pointer to the argument. 27097330f729Sjoerg // FIXME: We should be able to get rid of this method and use the va_arg 27107330f729Sjoerg // instruction in LLVM instead once it works well enough. 27117330f729Sjoerg Address EmitVAArg(VAArgExpr *VE, Address &VAListAddr); 27127330f729Sjoerg 27137330f729Sjoerg /// emitArrayLength - Compute the length of an array, even if it's a 27147330f729Sjoerg /// VLA, and drill down to the base element type. 27157330f729Sjoerg llvm::Value *emitArrayLength(const ArrayType *arrayType, 27167330f729Sjoerg QualType &baseType, 27177330f729Sjoerg Address &addr); 27187330f729Sjoerg 27197330f729Sjoerg /// EmitVLASize - Capture all the sizes for the VLA expressions in 27207330f729Sjoerg /// the given variably-modified type and store them in the VLASizeMap. 27217330f729Sjoerg /// 27227330f729Sjoerg /// This function can be called with a null (unreachable) insert point. 27237330f729Sjoerg void EmitVariablyModifiedType(QualType Ty); 27247330f729Sjoerg 27257330f729Sjoerg struct VlaSizePair { 27267330f729Sjoerg llvm::Value *NumElts; 27277330f729Sjoerg QualType Type; 27287330f729Sjoerg 27297330f729Sjoerg VlaSizePair(llvm::Value *NE, QualType T) : NumElts(NE), Type(T) {} 27307330f729Sjoerg }; 27317330f729Sjoerg 27327330f729Sjoerg /// Return the number of elements for a single dimension 27337330f729Sjoerg /// for the given array type. 27347330f729Sjoerg VlaSizePair getVLAElements1D(const VariableArrayType *vla); 27357330f729Sjoerg VlaSizePair getVLAElements1D(QualType vla); 27367330f729Sjoerg 27377330f729Sjoerg /// Returns an LLVM value that corresponds to the size, 27387330f729Sjoerg /// in non-variably-sized elements, of a variable length array type, 27397330f729Sjoerg /// plus that largest non-variably-sized element type. Assumes that 27407330f729Sjoerg /// the type has already been emitted with EmitVariablyModifiedType. 27417330f729Sjoerg VlaSizePair getVLASize(const VariableArrayType *vla); 27427330f729Sjoerg VlaSizePair getVLASize(QualType vla); 27437330f729Sjoerg 27447330f729Sjoerg /// LoadCXXThis - Load the value of 'this'. This function is only valid while 27457330f729Sjoerg /// generating code for an C++ member function. 27467330f729Sjoerg llvm::Value *LoadCXXThis() { 27477330f729Sjoerg assert(CXXThisValue && "no 'this' value for this function"); 27487330f729Sjoerg return CXXThisValue; 27497330f729Sjoerg } 27507330f729Sjoerg Address LoadCXXThisAddress(); 27517330f729Sjoerg 27527330f729Sjoerg /// LoadCXXVTT - Load the VTT parameter to base constructors/destructors have 27537330f729Sjoerg /// virtual bases. 27547330f729Sjoerg // FIXME: Every place that calls LoadCXXVTT is something 27557330f729Sjoerg // that needs to be abstracted properly. 27567330f729Sjoerg llvm::Value *LoadCXXVTT() { 27577330f729Sjoerg assert(CXXStructorImplicitParamValue && "no VTT value for this function"); 27587330f729Sjoerg return CXXStructorImplicitParamValue; 27597330f729Sjoerg } 27607330f729Sjoerg 27617330f729Sjoerg /// GetAddressOfBaseOfCompleteClass - Convert the given pointer to a 27627330f729Sjoerg /// complete class to the given direct base. 27637330f729Sjoerg Address 27647330f729Sjoerg GetAddressOfDirectBaseInCompleteClass(Address Value, 27657330f729Sjoerg const CXXRecordDecl *Derived, 27667330f729Sjoerg const CXXRecordDecl *Base, 27677330f729Sjoerg bool BaseIsVirtual); 27687330f729Sjoerg 27697330f729Sjoerg static bool ShouldNullCheckClassCastValue(const CastExpr *Cast); 27707330f729Sjoerg 27717330f729Sjoerg /// GetAddressOfBaseClass - This function will add the necessary delta to the 27727330f729Sjoerg /// load of 'this' and returns address of the base class. 27737330f729Sjoerg Address GetAddressOfBaseClass(Address Value, 27747330f729Sjoerg const CXXRecordDecl *Derived, 27757330f729Sjoerg CastExpr::path_const_iterator PathBegin, 27767330f729Sjoerg CastExpr::path_const_iterator PathEnd, 27777330f729Sjoerg bool NullCheckValue, SourceLocation Loc); 27787330f729Sjoerg 27797330f729Sjoerg Address GetAddressOfDerivedClass(Address Value, 27807330f729Sjoerg const CXXRecordDecl *Derived, 27817330f729Sjoerg CastExpr::path_const_iterator PathBegin, 27827330f729Sjoerg CastExpr::path_const_iterator PathEnd, 27837330f729Sjoerg bool NullCheckValue); 27847330f729Sjoerg 27857330f729Sjoerg /// GetVTTParameter - Return the VTT parameter that should be passed to a 27867330f729Sjoerg /// base constructor/destructor with virtual bases. 27877330f729Sjoerg /// FIXME: VTTs are Itanium ABI-specific, so the definition should move 27887330f729Sjoerg /// to ItaniumCXXABI.cpp together with all the references to VTT. 27897330f729Sjoerg llvm::Value *GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, 27907330f729Sjoerg bool Delegating); 27917330f729Sjoerg 27927330f729Sjoerg void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, 27937330f729Sjoerg CXXCtorType CtorType, 27947330f729Sjoerg const FunctionArgList &Args, 27957330f729Sjoerg SourceLocation Loc); 27967330f729Sjoerg // It's important not to confuse this and the previous function. Delegating 27977330f729Sjoerg // constructors are the C++0x feature. The constructor delegate optimization 27987330f729Sjoerg // is used to reduce duplication in the base and complete consturctors where 27997330f729Sjoerg // they are substantially the same. 28007330f729Sjoerg void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, 28017330f729Sjoerg const FunctionArgList &Args); 28027330f729Sjoerg 28037330f729Sjoerg /// Emit a call to an inheriting constructor (that is, one that invokes a 28047330f729Sjoerg /// constructor inherited from a base class) by inlining its definition. This 28057330f729Sjoerg /// is necessary if the ABI does not support forwarding the arguments to the 28067330f729Sjoerg /// base class constructor (because they're variadic or similar). 28077330f729Sjoerg void EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor, 28087330f729Sjoerg CXXCtorType CtorType, 28097330f729Sjoerg bool ForVirtualBase, 28107330f729Sjoerg bool Delegating, 28117330f729Sjoerg CallArgList &Args); 28127330f729Sjoerg 28137330f729Sjoerg /// Emit a call to a constructor inherited from a base class, passing the 28147330f729Sjoerg /// current constructor's arguments along unmodified (without even making 28157330f729Sjoerg /// a copy). 28167330f729Sjoerg void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D, 28177330f729Sjoerg bool ForVirtualBase, Address This, 28187330f729Sjoerg bool InheritedFromVBase, 28197330f729Sjoerg const CXXInheritedCtorInitExpr *E); 28207330f729Sjoerg 28217330f729Sjoerg void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, 28227330f729Sjoerg bool ForVirtualBase, bool Delegating, 28237330f729Sjoerg AggValueSlot ThisAVS, const CXXConstructExpr *E); 28247330f729Sjoerg 28257330f729Sjoerg void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, 28267330f729Sjoerg bool ForVirtualBase, bool Delegating, 28277330f729Sjoerg Address This, CallArgList &Args, 28287330f729Sjoerg AggValueSlot::Overlap_t Overlap, 28297330f729Sjoerg SourceLocation Loc, bool NewPointerIsChecked); 28307330f729Sjoerg 28317330f729Sjoerg /// Emit assumption load for all bases. Requires to be be called only on 28327330f729Sjoerg /// most-derived class and not under construction of the object. 28337330f729Sjoerg void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This); 28347330f729Sjoerg 28357330f729Sjoerg /// Emit assumption that vptr load == global vtable. 28367330f729Sjoerg void EmitVTableAssumptionLoad(const VPtr &vptr, Address This); 28377330f729Sjoerg 28387330f729Sjoerg void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, 28397330f729Sjoerg Address This, Address Src, 28407330f729Sjoerg const CXXConstructExpr *E); 28417330f729Sjoerg 28427330f729Sjoerg void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, 28437330f729Sjoerg const ArrayType *ArrayTy, 28447330f729Sjoerg Address ArrayPtr, 28457330f729Sjoerg const CXXConstructExpr *E, 28467330f729Sjoerg bool NewPointerIsChecked, 28477330f729Sjoerg bool ZeroInitialization = false); 28487330f729Sjoerg 28497330f729Sjoerg void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, 28507330f729Sjoerg llvm::Value *NumElements, 28517330f729Sjoerg Address ArrayPtr, 28527330f729Sjoerg const CXXConstructExpr *E, 28537330f729Sjoerg bool NewPointerIsChecked, 28547330f729Sjoerg bool ZeroInitialization = false); 28557330f729Sjoerg 28567330f729Sjoerg static Destroyer destroyCXXObject; 28577330f729Sjoerg 28587330f729Sjoerg void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, 28597330f729Sjoerg bool ForVirtualBase, bool Delegating, Address This, 28607330f729Sjoerg QualType ThisTy); 28617330f729Sjoerg 28627330f729Sjoerg void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType, 28637330f729Sjoerg llvm::Type *ElementTy, Address NewPtr, 28647330f729Sjoerg llvm::Value *NumElements, 28657330f729Sjoerg llvm::Value *AllocSizeWithoutCookie); 28667330f729Sjoerg 28677330f729Sjoerg void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType, 28687330f729Sjoerg Address Ptr); 28697330f729Sjoerg 2870*e038c9c4Sjoerg void EmitSehCppScopeBegin(); 2871*e038c9c4Sjoerg void EmitSehCppScopeEnd(); 2872*e038c9c4Sjoerg void EmitSehTryScopeBegin(); 2873*e038c9c4Sjoerg void EmitSehTryScopeEnd(); 2874*e038c9c4Sjoerg 28757330f729Sjoerg llvm::Value *EmitLifetimeStart(uint64_t Size, llvm::Value *Addr); 28767330f729Sjoerg void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr); 28777330f729Sjoerg 28787330f729Sjoerg llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E); 28797330f729Sjoerg void EmitCXXDeleteExpr(const CXXDeleteExpr *E); 28807330f729Sjoerg 28817330f729Sjoerg void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, 28827330f729Sjoerg QualType DeleteTy, llvm::Value *NumElements = nullptr, 28837330f729Sjoerg CharUnits CookieSize = CharUnits()); 28847330f729Sjoerg 28857330f729Sjoerg RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type, 28867330f729Sjoerg const CallExpr *TheCallExpr, bool IsDelete); 28877330f729Sjoerg 28887330f729Sjoerg llvm::Value *EmitCXXTypeidExpr(const CXXTypeidExpr *E); 28897330f729Sjoerg llvm::Value *EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE); 28907330f729Sjoerg Address EmitCXXUuidofExpr(const CXXUuidofExpr *E); 28917330f729Sjoerg 28927330f729Sjoerg /// Situations in which we might emit a check for the suitability of a 2893*e038c9c4Sjoerg /// pointer or glvalue. Needs to be kept in sync with ubsan_handlers.cpp in 2894*e038c9c4Sjoerg /// compiler-rt. 28957330f729Sjoerg enum TypeCheckKind { 28967330f729Sjoerg /// Checking the operand of a load. Must be suitably sized and aligned. 28977330f729Sjoerg TCK_Load, 28987330f729Sjoerg /// Checking the destination of a store. Must be suitably sized and aligned. 28997330f729Sjoerg TCK_Store, 29007330f729Sjoerg /// Checking the bound value in a reference binding. Must be suitably sized 29017330f729Sjoerg /// and aligned, but is not required to refer to an object (until the 29027330f729Sjoerg /// reference is used), per core issue 453. 29037330f729Sjoerg TCK_ReferenceBinding, 29047330f729Sjoerg /// Checking the object expression in a non-static data member access. Must 29057330f729Sjoerg /// be an object within its lifetime. 29067330f729Sjoerg TCK_MemberAccess, 29077330f729Sjoerg /// Checking the 'this' pointer for a call to a non-static member function. 29087330f729Sjoerg /// Must be an object within its lifetime. 29097330f729Sjoerg TCK_MemberCall, 29107330f729Sjoerg /// Checking the 'this' pointer for a constructor call. 29117330f729Sjoerg TCK_ConstructorCall, 29127330f729Sjoerg /// Checking the operand of a static_cast to a derived pointer type. Must be 29137330f729Sjoerg /// null or an object within its lifetime. 29147330f729Sjoerg TCK_DowncastPointer, 29157330f729Sjoerg /// Checking the operand of a static_cast to a derived reference type. Must 29167330f729Sjoerg /// be an object within its lifetime. 29177330f729Sjoerg TCK_DowncastReference, 29187330f729Sjoerg /// Checking the operand of a cast to a base object. Must be suitably sized 29197330f729Sjoerg /// and aligned. 29207330f729Sjoerg TCK_Upcast, 29217330f729Sjoerg /// Checking the operand of a cast to a virtual base object. Must be an 29227330f729Sjoerg /// object within its lifetime. 29237330f729Sjoerg TCK_UpcastToVirtualBase, 29247330f729Sjoerg /// Checking the value assigned to a _Nonnull pointer. Must not be null. 29257330f729Sjoerg TCK_NonnullAssign, 29267330f729Sjoerg /// Checking the operand of a dynamic_cast or a typeid expression. Must be 29277330f729Sjoerg /// null or an object within its lifetime. 29287330f729Sjoerg TCK_DynamicOperation 29297330f729Sjoerg }; 29307330f729Sjoerg 29317330f729Sjoerg /// Determine whether the pointer type check \p TCK permits null pointers. 29327330f729Sjoerg static bool isNullPointerAllowed(TypeCheckKind TCK); 29337330f729Sjoerg 29347330f729Sjoerg /// Determine whether the pointer type check \p TCK requires a vptr check. 29357330f729Sjoerg static bool isVptrCheckRequired(TypeCheckKind TCK, QualType Ty); 29367330f729Sjoerg 29377330f729Sjoerg /// Whether any type-checking sanitizers are enabled. If \c false, 29387330f729Sjoerg /// calls to EmitTypeCheck can be skipped. 29397330f729Sjoerg bool sanitizePerformTypeCheck() const; 29407330f729Sjoerg 29417330f729Sjoerg /// Emit a check that \p V is the address of storage of the 29427330f729Sjoerg /// appropriate size and alignment for an object of type \p Type 29437330f729Sjoerg /// (or if ArraySize is provided, for an array of that bound). 29447330f729Sjoerg void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V, 29457330f729Sjoerg QualType Type, CharUnits Alignment = CharUnits::Zero(), 29467330f729Sjoerg SanitizerSet SkippedChecks = SanitizerSet(), 29477330f729Sjoerg llvm::Value *ArraySize = nullptr); 29487330f729Sjoerg 29497330f729Sjoerg /// Emit a check that \p Base points into an array object, which 29507330f729Sjoerg /// we can access at index \p Index. \p Accessed should be \c false if we 29517330f729Sjoerg /// this expression is used as an lvalue, for instance in "&Arr[Idx]". 29527330f729Sjoerg void EmitBoundsCheck(const Expr *E, const Expr *Base, llvm::Value *Index, 29537330f729Sjoerg QualType IndexType, bool Accessed); 29547330f729Sjoerg 29557330f729Sjoerg llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, 29567330f729Sjoerg bool isInc, bool isPre); 29577330f729Sjoerg ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, 29587330f729Sjoerg bool isInc, bool isPre); 29597330f729Sjoerg 29607330f729Sjoerg /// Converts Location to a DebugLoc, if debug information is enabled. 29617330f729Sjoerg llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location); 29627330f729Sjoerg 29637330f729Sjoerg /// Get the record field index as represented in debug info. 29647330f729Sjoerg unsigned getDebugInfoFIndex(const RecordDecl *Rec, unsigned FieldIndex); 29657330f729Sjoerg 29667330f729Sjoerg 29677330f729Sjoerg //===--------------------------------------------------------------------===// 29687330f729Sjoerg // Declaration Emission 29697330f729Sjoerg //===--------------------------------------------------------------------===// 29707330f729Sjoerg 29717330f729Sjoerg /// EmitDecl - Emit a declaration. 29727330f729Sjoerg /// 29737330f729Sjoerg /// This function can be called with a null (unreachable) insert point. 29747330f729Sjoerg void EmitDecl(const Decl &D); 29757330f729Sjoerg 29767330f729Sjoerg /// EmitVarDecl - Emit a local variable declaration. 29777330f729Sjoerg /// 29787330f729Sjoerg /// This function can be called with a null (unreachable) insert point. 29797330f729Sjoerg void EmitVarDecl(const VarDecl &D); 29807330f729Sjoerg 29817330f729Sjoerg void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, 29827330f729Sjoerg bool capturedByInit); 29837330f729Sjoerg 29847330f729Sjoerg typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D, 29857330f729Sjoerg llvm::Value *Address); 29867330f729Sjoerg 29877330f729Sjoerg /// Determine whether the given initializer is trivial in the sense 29887330f729Sjoerg /// that it requires no code to be generated. 29897330f729Sjoerg bool isTrivialInitializer(const Expr *Init); 29907330f729Sjoerg 29917330f729Sjoerg /// EmitAutoVarDecl - Emit an auto variable declaration. 29927330f729Sjoerg /// 29937330f729Sjoerg /// This function can be called with a null (unreachable) insert point. 29947330f729Sjoerg void EmitAutoVarDecl(const VarDecl &D); 29957330f729Sjoerg 29967330f729Sjoerg class AutoVarEmission { 29977330f729Sjoerg friend class CodeGenFunction; 29987330f729Sjoerg 29997330f729Sjoerg const VarDecl *Variable; 30007330f729Sjoerg 30017330f729Sjoerg /// The address of the alloca for languages with explicit address space 30027330f729Sjoerg /// (e.g. OpenCL) or alloca casted to generic pointer for address space 30037330f729Sjoerg /// agnostic languages (e.g. C++). Invalid if the variable was emitted 30047330f729Sjoerg /// as a global constant. 30057330f729Sjoerg Address Addr; 30067330f729Sjoerg 30077330f729Sjoerg llvm::Value *NRVOFlag; 30087330f729Sjoerg 30097330f729Sjoerg /// True if the variable is a __block variable that is captured by an 30107330f729Sjoerg /// escaping block. 30117330f729Sjoerg bool IsEscapingByRef; 30127330f729Sjoerg 30137330f729Sjoerg /// True if the variable is of aggregate type and has a constant 30147330f729Sjoerg /// initializer. 30157330f729Sjoerg bool IsConstantAggregate; 30167330f729Sjoerg 30177330f729Sjoerg /// Non-null if we should use lifetime annotations. 30187330f729Sjoerg llvm::Value *SizeForLifetimeMarkers; 30197330f729Sjoerg 30207330f729Sjoerg /// Address with original alloca instruction. Invalid if the variable was 30217330f729Sjoerg /// emitted as a global constant. 30227330f729Sjoerg Address AllocaAddr; 30237330f729Sjoerg 30247330f729Sjoerg struct Invalid {}; 30257330f729Sjoerg AutoVarEmission(Invalid) 30267330f729Sjoerg : Variable(nullptr), Addr(Address::invalid()), 30277330f729Sjoerg AllocaAddr(Address::invalid()) {} 30287330f729Sjoerg 30297330f729Sjoerg AutoVarEmission(const VarDecl &variable) 30307330f729Sjoerg : Variable(&variable), Addr(Address::invalid()), NRVOFlag(nullptr), 30317330f729Sjoerg IsEscapingByRef(false), IsConstantAggregate(false), 30327330f729Sjoerg SizeForLifetimeMarkers(nullptr), AllocaAddr(Address::invalid()) {} 30337330f729Sjoerg 30347330f729Sjoerg bool wasEmittedAsGlobal() const { return !Addr.isValid(); } 30357330f729Sjoerg 30367330f729Sjoerg public: 30377330f729Sjoerg static AutoVarEmission invalid() { return AutoVarEmission(Invalid()); } 30387330f729Sjoerg 30397330f729Sjoerg bool useLifetimeMarkers() const { 30407330f729Sjoerg return SizeForLifetimeMarkers != nullptr; 30417330f729Sjoerg } 30427330f729Sjoerg llvm::Value *getSizeForLifetimeMarkers() const { 30437330f729Sjoerg assert(useLifetimeMarkers()); 30447330f729Sjoerg return SizeForLifetimeMarkers; 30457330f729Sjoerg } 30467330f729Sjoerg 30477330f729Sjoerg /// Returns the raw, allocated address, which is not necessarily 30487330f729Sjoerg /// the address of the object itself. It is casted to default 30497330f729Sjoerg /// address space for address space agnostic languages. 30507330f729Sjoerg Address getAllocatedAddress() const { 30517330f729Sjoerg return Addr; 30527330f729Sjoerg } 30537330f729Sjoerg 30547330f729Sjoerg /// Returns the address for the original alloca instruction. 30557330f729Sjoerg Address getOriginalAllocatedAddress() const { return AllocaAddr; } 30567330f729Sjoerg 30577330f729Sjoerg /// Returns the address of the object within this declaration. 30587330f729Sjoerg /// Note that this does not chase the forwarding pointer for 30597330f729Sjoerg /// __block decls. 30607330f729Sjoerg Address getObjectAddress(CodeGenFunction &CGF) const { 30617330f729Sjoerg if (!IsEscapingByRef) return Addr; 30627330f729Sjoerg 30637330f729Sjoerg return CGF.emitBlockByrefAddress(Addr, Variable, /*forward*/ false); 30647330f729Sjoerg } 30657330f729Sjoerg }; 30667330f729Sjoerg AutoVarEmission EmitAutoVarAlloca(const VarDecl &var); 30677330f729Sjoerg void EmitAutoVarInit(const AutoVarEmission &emission); 30687330f729Sjoerg void EmitAutoVarCleanups(const AutoVarEmission &emission); 30697330f729Sjoerg void emitAutoVarTypeCleanup(const AutoVarEmission &emission, 30707330f729Sjoerg QualType::DestructionKind dtorKind); 30717330f729Sjoerg 30727330f729Sjoerg /// Emits the alloca and debug information for the size expressions for each 30737330f729Sjoerg /// dimension of an array. It registers the association of its (1-dimensional) 30747330f729Sjoerg /// QualTypes and size expression's debug node, so that CGDebugInfo can 30757330f729Sjoerg /// reference this node when creating the DISubrange object to describe the 30767330f729Sjoerg /// array types. 30777330f729Sjoerg void EmitAndRegisterVariableArrayDimensions(CGDebugInfo *DI, 30787330f729Sjoerg const VarDecl &D, 30797330f729Sjoerg bool EmitDebugInfo); 30807330f729Sjoerg 30817330f729Sjoerg void EmitStaticVarDecl(const VarDecl &D, 30827330f729Sjoerg llvm::GlobalValue::LinkageTypes Linkage); 30837330f729Sjoerg 30847330f729Sjoerg class ParamValue { 30857330f729Sjoerg llvm::Value *Value; 30867330f729Sjoerg unsigned Alignment; 30877330f729Sjoerg ParamValue(llvm::Value *V, unsigned A) : Value(V), Alignment(A) {} 30887330f729Sjoerg public: 30897330f729Sjoerg static ParamValue forDirect(llvm::Value *value) { 30907330f729Sjoerg return ParamValue(value, 0); 30917330f729Sjoerg } 30927330f729Sjoerg static ParamValue forIndirect(Address addr) { 30937330f729Sjoerg assert(!addr.getAlignment().isZero()); 30947330f729Sjoerg return ParamValue(addr.getPointer(), addr.getAlignment().getQuantity()); 30957330f729Sjoerg } 30967330f729Sjoerg 30977330f729Sjoerg bool isIndirect() const { return Alignment != 0; } 30987330f729Sjoerg llvm::Value *getAnyValue() const { return Value; } 30997330f729Sjoerg 31007330f729Sjoerg llvm::Value *getDirectValue() const { 31017330f729Sjoerg assert(!isIndirect()); 31027330f729Sjoerg return Value; 31037330f729Sjoerg } 31047330f729Sjoerg 31057330f729Sjoerg Address getIndirectAddress() const { 31067330f729Sjoerg assert(isIndirect()); 31077330f729Sjoerg return Address(Value, CharUnits::fromQuantity(Alignment)); 31087330f729Sjoerg } 31097330f729Sjoerg }; 31107330f729Sjoerg 31117330f729Sjoerg /// EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl. 31127330f729Sjoerg void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo); 31137330f729Sjoerg 31147330f729Sjoerg /// protectFromPeepholes - Protect a value that we're intending to 31157330f729Sjoerg /// store to the side, but which will probably be used later, from 31167330f729Sjoerg /// aggressive peepholing optimizations that might delete it. 31177330f729Sjoerg /// 31187330f729Sjoerg /// Pass the result to unprotectFromPeepholes to declare that 31197330f729Sjoerg /// protection is no longer required. 31207330f729Sjoerg /// 31217330f729Sjoerg /// There's no particular reason why this shouldn't apply to 31227330f729Sjoerg /// l-values, it's just that no existing peepholes work on pointers. 31237330f729Sjoerg PeepholeProtection protectFromPeepholes(RValue rvalue); 31247330f729Sjoerg void unprotectFromPeepholes(PeepholeProtection protection); 31257330f729Sjoerg 3126*e038c9c4Sjoerg void emitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType Ty, 31277330f729Sjoerg SourceLocation Loc, 31287330f729Sjoerg SourceLocation AssumptionLoc, 31297330f729Sjoerg llvm::Value *Alignment, 31307330f729Sjoerg llvm::Value *OffsetValue, 31317330f729Sjoerg llvm::Value *TheCheck, 31327330f729Sjoerg llvm::Instruction *Assumption); 31337330f729Sjoerg 3134*e038c9c4Sjoerg void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, 31357330f729Sjoerg SourceLocation Loc, SourceLocation AssumptionLoc, 31367330f729Sjoerg llvm::Value *Alignment, 31377330f729Sjoerg llvm::Value *OffsetValue = nullptr); 31387330f729Sjoerg 3139*e038c9c4Sjoerg void emitAlignmentAssumption(llvm::Value *PtrValue, const Expr *E, 3140*e038c9c4Sjoerg SourceLocation AssumptionLoc, 3141*e038c9c4Sjoerg llvm::Value *Alignment, 31427330f729Sjoerg llvm::Value *OffsetValue = nullptr); 31437330f729Sjoerg 31447330f729Sjoerg //===--------------------------------------------------------------------===// 31457330f729Sjoerg // Statement Emission 31467330f729Sjoerg //===--------------------------------------------------------------------===// 31477330f729Sjoerg 31487330f729Sjoerg /// EmitStopPoint - Emit a debug stoppoint if we are emitting debug info. 31497330f729Sjoerg void EmitStopPoint(const Stmt *S); 31507330f729Sjoerg 31517330f729Sjoerg /// EmitStmt - Emit the code for the statement \arg S. It is legal to call 31527330f729Sjoerg /// this function even if there is no current insertion point. 31537330f729Sjoerg /// 31547330f729Sjoerg /// This function may clear the current insertion point; callers should use 31557330f729Sjoerg /// EnsureInsertPoint if they wish to subsequently generate code without first 31567330f729Sjoerg /// calling EmitBlock, EmitBranch, or EmitStmt. 31577330f729Sjoerg void EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs = None); 31587330f729Sjoerg 31597330f729Sjoerg /// EmitSimpleStmt - Try to emit a "simple" statement which does not 31607330f729Sjoerg /// necessarily require an insertion point or debug information; typically 31617330f729Sjoerg /// because the statement amounts to a jump or a container of other 31627330f729Sjoerg /// statements. 31637330f729Sjoerg /// 31647330f729Sjoerg /// \return True if the statement was handled. 3165*e038c9c4Sjoerg bool EmitSimpleStmt(const Stmt *S, ArrayRef<const Attr *> Attrs); 31667330f729Sjoerg 31677330f729Sjoerg Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false, 31687330f729Sjoerg AggValueSlot AVS = AggValueSlot::ignored()); 31697330f729Sjoerg Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, 31707330f729Sjoerg bool GetLast = false, 31717330f729Sjoerg AggValueSlot AVS = 31727330f729Sjoerg AggValueSlot::ignored()); 31737330f729Sjoerg 31747330f729Sjoerg /// EmitLabel - Emit the block for the given label. It is legal to call this 31757330f729Sjoerg /// function even if there is no current insertion point. 31767330f729Sjoerg void EmitLabel(const LabelDecl *D); // helper for EmitLabelStmt. 31777330f729Sjoerg 31787330f729Sjoerg void EmitLabelStmt(const LabelStmt &S); 31797330f729Sjoerg void EmitAttributedStmt(const AttributedStmt &S); 31807330f729Sjoerg void EmitGotoStmt(const GotoStmt &S); 31817330f729Sjoerg void EmitIndirectGotoStmt(const IndirectGotoStmt &S); 31827330f729Sjoerg void EmitIfStmt(const IfStmt &S); 31837330f729Sjoerg 31847330f729Sjoerg void EmitWhileStmt(const WhileStmt &S, 31857330f729Sjoerg ArrayRef<const Attr *> Attrs = None); 31867330f729Sjoerg void EmitDoStmt(const DoStmt &S, ArrayRef<const Attr *> Attrs = None); 31877330f729Sjoerg void EmitForStmt(const ForStmt &S, 31887330f729Sjoerg ArrayRef<const Attr *> Attrs = None); 31897330f729Sjoerg void EmitReturnStmt(const ReturnStmt &S); 31907330f729Sjoerg void EmitDeclStmt(const DeclStmt &S); 31917330f729Sjoerg void EmitBreakStmt(const BreakStmt &S); 31927330f729Sjoerg void EmitContinueStmt(const ContinueStmt &S); 31937330f729Sjoerg void EmitSwitchStmt(const SwitchStmt &S); 3194*e038c9c4Sjoerg void EmitDefaultStmt(const DefaultStmt &S, ArrayRef<const Attr *> Attrs); 3195*e038c9c4Sjoerg void EmitCaseStmt(const CaseStmt &S, ArrayRef<const Attr *> Attrs); 3196*e038c9c4Sjoerg void EmitCaseStmtRange(const CaseStmt &S, ArrayRef<const Attr *> Attrs); 31977330f729Sjoerg void EmitAsmStmt(const AsmStmt &S); 31987330f729Sjoerg 31997330f729Sjoerg void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S); 32007330f729Sjoerg void EmitObjCAtTryStmt(const ObjCAtTryStmt &S); 32017330f729Sjoerg void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S); 32027330f729Sjoerg void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S); 32037330f729Sjoerg void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S); 32047330f729Sjoerg 32057330f729Sjoerg void EmitCoroutineBody(const CoroutineBodyStmt &S); 32067330f729Sjoerg void EmitCoreturnStmt(const CoreturnStmt &S); 32077330f729Sjoerg RValue EmitCoawaitExpr(const CoawaitExpr &E, 32087330f729Sjoerg AggValueSlot aggSlot = AggValueSlot::ignored(), 32097330f729Sjoerg bool ignoreResult = false); 32107330f729Sjoerg LValue EmitCoawaitLValue(const CoawaitExpr *E); 32117330f729Sjoerg RValue EmitCoyieldExpr(const CoyieldExpr &E, 32127330f729Sjoerg AggValueSlot aggSlot = AggValueSlot::ignored(), 32137330f729Sjoerg bool ignoreResult = false); 32147330f729Sjoerg LValue EmitCoyieldLValue(const CoyieldExpr *E); 32157330f729Sjoerg RValue EmitCoroutineIntrinsic(const CallExpr *E, unsigned int IID); 32167330f729Sjoerg 32177330f729Sjoerg void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false); 32187330f729Sjoerg void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false); 32197330f729Sjoerg 32207330f729Sjoerg void EmitCXXTryStmt(const CXXTryStmt &S); 32217330f729Sjoerg void EmitSEHTryStmt(const SEHTryStmt &S); 32227330f729Sjoerg void EmitSEHLeaveStmt(const SEHLeaveStmt &S); 32237330f729Sjoerg void EnterSEHTryStmt(const SEHTryStmt &S); 32247330f729Sjoerg void ExitSEHTryStmt(const SEHTryStmt &S); 3225*e038c9c4Sjoerg void VolatilizeTryBlocks(llvm::BasicBlock *BB, 3226*e038c9c4Sjoerg llvm::SmallPtrSet<llvm::BasicBlock *, 10> &V); 32277330f729Sjoerg 32287330f729Sjoerg void pushSEHCleanup(CleanupKind kind, 32297330f729Sjoerg llvm::Function *FinallyFunc); 32307330f729Sjoerg void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, 32317330f729Sjoerg const Stmt *OutlinedStmt); 32327330f729Sjoerg 32337330f729Sjoerg llvm::Function *GenerateSEHFilterFunction(CodeGenFunction &ParentCGF, 32347330f729Sjoerg const SEHExceptStmt &Except); 32357330f729Sjoerg 32367330f729Sjoerg llvm::Function *GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF, 32377330f729Sjoerg const SEHFinallyStmt &Finally); 32387330f729Sjoerg 32397330f729Sjoerg void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, 32407330f729Sjoerg llvm::Value *ParentFP, 32417330f729Sjoerg llvm::Value *EntryEBP); 32427330f729Sjoerg llvm::Value *EmitSEHExceptionCode(); 32437330f729Sjoerg llvm::Value *EmitSEHExceptionInfo(); 32447330f729Sjoerg llvm::Value *EmitSEHAbnormalTermination(); 32457330f729Sjoerg 32467330f729Sjoerg /// Emit simple code for OpenMP directives in Simd-only mode. 32477330f729Sjoerg void EmitSimpleOMPExecutableDirective(const OMPExecutableDirective &D); 32487330f729Sjoerg 32497330f729Sjoerg /// Scan the outlined statement for captures from the parent function. For 32507330f729Sjoerg /// each capture, mark the capture as escaped and emit a call to 32517330f729Sjoerg /// llvm.localrecover. Insert the localrecover result into the LocalDeclMap. 32527330f729Sjoerg void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt, 32537330f729Sjoerg bool IsFilter); 32547330f729Sjoerg 32557330f729Sjoerg /// Recovers the address of a local in a parent function. ParentVar is the 32567330f729Sjoerg /// address of the variable used in the immediate parent function. It can 32577330f729Sjoerg /// either be an alloca or a call to llvm.localrecover if there are nested 32587330f729Sjoerg /// outlined functions. ParentFP is the frame pointer of the outermost parent 32597330f729Sjoerg /// frame. 32607330f729Sjoerg Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, 32617330f729Sjoerg Address ParentVar, 32627330f729Sjoerg llvm::Value *ParentFP); 32637330f729Sjoerg 32647330f729Sjoerg void EmitCXXForRangeStmt(const CXXForRangeStmt &S, 32657330f729Sjoerg ArrayRef<const Attr *> Attrs = None); 32667330f729Sjoerg 32677330f729Sjoerg /// Controls insertion of cancellation exit blocks in worksharing constructs. 32687330f729Sjoerg class OMPCancelStackRAII { 32697330f729Sjoerg CodeGenFunction &CGF; 32707330f729Sjoerg 32717330f729Sjoerg public: 32727330f729Sjoerg OMPCancelStackRAII(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, 32737330f729Sjoerg bool HasCancel) 32747330f729Sjoerg : CGF(CGF) { 32757330f729Sjoerg CGF.OMPCancelStack.enter(CGF, Kind, HasCancel); 32767330f729Sjoerg } 32777330f729Sjoerg ~OMPCancelStackRAII() { CGF.OMPCancelStack.exit(CGF); } 32787330f729Sjoerg }; 32797330f729Sjoerg 32807330f729Sjoerg /// Returns calculated size of the specified type. 32817330f729Sjoerg llvm::Value *getTypeSize(QualType Ty); 32827330f729Sjoerg LValue InitCapturedStruct(const CapturedStmt &S); 32837330f729Sjoerg llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K); 32847330f729Sjoerg llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S); 32857330f729Sjoerg Address GenerateCapturedStmtArgument(const CapturedStmt &S); 3286*e038c9c4Sjoerg llvm::Function *GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S, 3287*e038c9c4Sjoerg SourceLocation Loc); 32887330f729Sjoerg void GenerateOpenMPCapturedVars(const CapturedStmt &S, 32897330f729Sjoerg SmallVectorImpl<llvm::Value *> &CapturedVars); 32907330f729Sjoerg void emitOMPSimpleStore(LValue LVal, RValue RVal, QualType RValTy, 32917330f729Sjoerg SourceLocation Loc); 32927330f729Sjoerg /// Perform element by element copying of arrays with type \a 32937330f729Sjoerg /// OriginalType from \a SrcAddr to \a DestAddr using copying procedure 32947330f729Sjoerg /// generated by \a CopyGen. 32957330f729Sjoerg /// 32967330f729Sjoerg /// \param DestAddr Address of the destination array. 32977330f729Sjoerg /// \param SrcAddr Address of the source array. 32987330f729Sjoerg /// \param OriginalType Type of destination and source arrays. 32997330f729Sjoerg /// \param CopyGen Copying procedure that copies value of single array element 33007330f729Sjoerg /// to another single array element. 33017330f729Sjoerg void EmitOMPAggregateAssign( 33027330f729Sjoerg Address DestAddr, Address SrcAddr, QualType OriginalType, 33037330f729Sjoerg const llvm::function_ref<void(Address, Address)> CopyGen); 33047330f729Sjoerg /// Emit proper copying of data from one variable to another. 33057330f729Sjoerg /// 33067330f729Sjoerg /// \param OriginalType Original type of the copied variables. 33077330f729Sjoerg /// \param DestAddr Destination address. 33087330f729Sjoerg /// \param SrcAddr Source address. 33097330f729Sjoerg /// \param DestVD Destination variable used in \a CopyExpr (for arrays, has 33107330f729Sjoerg /// type of the base array element). 33117330f729Sjoerg /// \param SrcVD Source variable used in \a CopyExpr (for arrays, has type of 33127330f729Sjoerg /// the base array element). 33137330f729Sjoerg /// \param Copy Actual copygin expression for copying data from \a SrcVD to \a 33147330f729Sjoerg /// DestVD. 33157330f729Sjoerg void EmitOMPCopy(QualType OriginalType, 33167330f729Sjoerg Address DestAddr, Address SrcAddr, 33177330f729Sjoerg const VarDecl *DestVD, const VarDecl *SrcVD, 33187330f729Sjoerg const Expr *Copy); 33197330f729Sjoerg /// Emit atomic update code for constructs: \a X = \a X \a BO \a E or 33207330f729Sjoerg /// \a X = \a E \a BO \a E. 33217330f729Sjoerg /// 33227330f729Sjoerg /// \param X Value to be updated. 33237330f729Sjoerg /// \param E Update value. 33247330f729Sjoerg /// \param BO Binary operation for update operation. 33257330f729Sjoerg /// \param IsXLHSInRHSPart true if \a X is LHS in RHS part of the update 33267330f729Sjoerg /// expression, false otherwise. 33277330f729Sjoerg /// \param AO Atomic ordering of the generated atomic instructions. 33287330f729Sjoerg /// \param CommonGen Code generator for complex expressions that cannot be 33297330f729Sjoerg /// expressed through atomicrmw instruction. 33307330f729Sjoerg /// \returns <true, OldAtomicValue> if simple 'atomicrmw' instruction was 33317330f729Sjoerg /// generated, <false, RValue::get(nullptr)> otherwise. 33327330f729Sjoerg std::pair<bool, RValue> EmitOMPAtomicSimpleUpdateExpr( 33337330f729Sjoerg LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart, 33347330f729Sjoerg llvm::AtomicOrdering AO, SourceLocation Loc, 33357330f729Sjoerg const llvm::function_ref<RValue(RValue)> CommonGen); 33367330f729Sjoerg bool EmitOMPFirstprivateClause(const OMPExecutableDirective &D, 33377330f729Sjoerg OMPPrivateScope &PrivateScope); 33387330f729Sjoerg void EmitOMPPrivateClause(const OMPExecutableDirective &D, 33397330f729Sjoerg OMPPrivateScope &PrivateScope); 33407330f729Sjoerg void EmitOMPUseDevicePtrClause( 3341*e038c9c4Sjoerg const OMPUseDevicePtrClause &C, OMPPrivateScope &PrivateScope, 3342*e038c9c4Sjoerg const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap); 3343*e038c9c4Sjoerg void EmitOMPUseDeviceAddrClause( 3344*e038c9c4Sjoerg const OMPUseDeviceAddrClause &C, OMPPrivateScope &PrivateScope, 33457330f729Sjoerg const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap); 33467330f729Sjoerg /// Emit code for copyin clause in \a D directive. The next code is 33477330f729Sjoerg /// generated at the start of outlined functions for directives: 33487330f729Sjoerg /// \code 33497330f729Sjoerg /// threadprivate_var1 = master_threadprivate_var1; 33507330f729Sjoerg /// operator=(threadprivate_var2, master_threadprivate_var2); 33517330f729Sjoerg /// ... 33527330f729Sjoerg /// __kmpc_barrier(&loc, global_tid); 33537330f729Sjoerg /// \endcode 33547330f729Sjoerg /// 33557330f729Sjoerg /// \param D OpenMP directive possibly with 'copyin' clause(s). 33567330f729Sjoerg /// \returns true if at least one copyin variable is found, false otherwise. 33577330f729Sjoerg bool EmitOMPCopyinClause(const OMPExecutableDirective &D); 33587330f729Sjoerg /// Emit initial code for lastprivate variables. If some variable is 33597330f729Sjoerg /// not also firstprivate, then the default initialization is used. Otherwise 33607330f729Sjoerg /// initialization of this variable is performed by EmitOMPFirstprivateClause 33617330f729Sjoerg /// method. 33627330f729Sjoerg /// 33637330f729Sjoerg /// \param D Directive that may have 'lastprivate' directives. 33647330f729Sjoerg /// \param PrivateScope Private scope for capturing lastprivate variables for 33657330f729Sjoerg /// proper codegen in internal captured statement. 33667330f729Sjoerg /// 33677330f729Sjoerg /// \returns true if there is at least one lastprivate variable, false 33687330f729Sjoerg /// otherwise. 33697330f729Sjoerg bool EmitOMPLastprivateClauseInit(const OMPExecutableDirective &D, 33707330f729Sjoerg OMPPrivateScope &PrivateScope); 33717330f729Sjoerg /// Emit final copying of lastprivate values to original variables at 33727330f729Sjoerg /// the end of the worksharing or simd directive. 33737330f729Sjoerg /// 33747330f729Sjoerg /// \param D Directive that has at least one 'lastprivate' directives. 33757330f729Sjoerg /// \param IsLastIterCond Boolean condition that must be set to 'i1 true' if 33767330f729Sjoerg /// it is the last iteration of the loop code in associated directive, or to 33777330f729Sjoerg /// 'i1 false' otherwise. If this item is nullptr, no final check is required. 33787330f729Sjoerg void EmitOMPLastprivateClauseFinal(const OMPExecutableDirective &D, 33797330f729Sjoerg bool NoFinals, 33807330f729Sjoerg llvm::Value *IsLastIterCond = nullptr); 33817330f729Sjoerg /// Emit initial code for linear clauses. 33827330f729Sjoerg void EmitOMPLinearClause(const OMPLoopDirective &D, 33837330f729Sjoerg CodeGenFunction::OMPPrivateScope &PrivateScope); 33847330f729Sjoerg /// Emit final code for linear clauses. 33857330f729Sjoerg /// \param CondGen Optional conditional code for final part of codegen for 33867330f729Sjoerg /// linear clause. 33877330f729Sjoerg void EmitOMPLinearClauseFinal( 33887330f729Sjoerg const OMPLoopDirective &D, 33897330f729Sjoerg const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen); 33907330f729Sjoerg /// Emit initial code for reduction variables. Creates reduction copies 33917330f729Sjoerg /// and initializes them with the values according to OpenMP standard. 33927330f729Sjoerg /// 33937330f729Sjoerg /// \param D Directive (possibly) with the 'reduction' clause. 33947330f729Sjoerg /// \param PrivateScope Private scope for capturing reduction variables for 33957330f729Sjoerg /// proper codegen in internal captured statement. 33967330f729Sjoerg /// 33977330f729Sjoerg void EmitOMPReductionClauseInit(const OMPExecutableDirective &D, 3398*e038c9c4Sjoerg OMPPrivateScope &PrivateScope, 3399*e038c9c4Sjoerg bool ForInscan = false); 34007330f729Sjoerg /// Emit final update of reduction values to original variables at 34017330f729Sjoerg /// the end of the directive. 34027330f729Sjoerg /// 34037330f729Sjoerg /// \param D Directive that has at least one 'reduction' directives. 34047330f729Sjoerg /// \param ReductionKind The kind of reduction to perform. 34057330f729Sjoerg void EmitOMPReductionClauseFinal(const OMPExecutableDirective &D, 34067330f729Sjoerg const OpenMPDirectiveKind ReductionKind); 34077330f729Sjoerg /// Emit initial code for linear variables. Creates private copies 34087330f729Sjoerg /// and initializes them with the values according to OpenMP standard. 34097330f729Sjoerg /// 34107330f729Sjoerg /// \param D Directive (possibly) with the 'linear' clause. 34117330f729Sjoerg /// \return true if at least one linear variable is found that should be 34127330f729Sjoerg /// initialized with the value of the original variable, false otherwise. 34137330f729Sjoerg bool EmitOMPLinearClauseInit(const OMPLoopDirective &D); 34147330f729Sjoerg 34157330f729Sjoerg typedef const llvm::function_ref<void(CodeGenFunction & /*CGF*/, 34167330f729Sjoerg llvm::Function * /*OutlinedFn*/, 34177330f729Sjoerg const OMPTaskDataTy & /*Data*/)> 34187330f729Sjoerg TaskGenTy; 34197330f729Sjoerg void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S, 34207330f729Sjoerg const OpenMPDirectiveKind CapturedRegion, 34217330f729Sjoerg const RegionCodeGenTy &BodyGen, 34227330f729Sjoerg const TaskGenTy &TaskGen, OMPTaskDataTy &Data); 34237330f729Sjoerg struct OMPTargetDataInfo { 34247330f729Sjoerg Address BasePointersArray = Address::invalid(); 34257330f729Sjoerg Address PointersArray = Address::invalid(); 34267330f729Sjoerg Address SizesArray = Address::invalid(); 3427*e038c9c4Sjoerg Address MappersArray = Address::invalid(); 34287330f729Sjoerg unsigned NumberOfTargetItems = 0; 34297330f729Sjoerg explicit OMPTargetDataInfo() = default; 34307330f729Sjoerg OMPTargetDataInfo(Address BasePointersArray, Address PointersArray, 3431*e038c9c4Sjoerg Address SizesArray, Address MappersArray, 3432*e038c9c4Sjoerg unsigned NumberOfTargetItems) 34337330f729Sjoerg : BasePointersArray(BasePointersArray), PointersArray(PointersArray), 3434*e038c9c4Sjoerg SizesArray(SizesArray), MappersArray(MappersArray), 3435*e038c9c4Sjoerg NumberOfTargetItems(NumberOfTargetItems) {} 34367330f729Sjoerg }; 34377330f729Sjoerg void EmitOMPTargetTaskBasedDirective(const OMPExecutableDirective &S, 34387330f729Sjoerg const RegionCodeGenTy &BodyGen, 34397330f729Sjoerg OMPTargetDataInfo &InputInfo); 34407330f729Sjoerg 34417330f729Sjoerg void EmitOMPParallelDirective(const OMPParallelDirective &S); 34427330f729Sjoerg void EmitOMPSimdDirective(const OMPSimdDirective &S); 3443*e038c9c4Sjoerg void EmitOMPTileDirective(const OMPTileDirective &S); 34447330f729Sjoerg void EmitOMPForDirective(const OMPForDirective &S); 34457330f729Sjoerg void EmitOMPForSimdDirective(const OMPForSimdDirective &S); 34467330f729Sjoerg void EmitOMPSectionsDirective(const OMPSectionsDirective &S); 34477330f729Sjoerg void EmitOMPSectionDirective(const OMPSectionDirective &S); 34487330f729Sjoerg void EmitOMPSingleDirective(const OMPSingleDirective &S); 34497330f729Sjoerg void EmitOMPMasterDirective(const OMPMasterDirective &S); 3450*e038c9c4Sjoerg void EmitOMPMaskedDirective(const OMPMaskedDirective &S); 34517330f729Sjoerg void EmitOMPCriticalDirective(const OMPCriticalDirective &S); 34527330f729Sjoerg void EmitOMPParallelForDirective(const OMPParallelForDirective &S); 34537330f729Sjoerg void EmitOMPParallelForSimdDirective(const OMPParallelForSimdDirective &S); 34547330f729Sjoerg void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S); 3455*e038c9c4Sjoerg void EmitOMPParallelMasterDirective(const OMPParallelMasterDirective &S); 34567330f729Sjoerg void EmitOMPTaskDirective(const OMPTaskDirective &S); 34577330f729Sjoerg void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S); 34587330f729Sjoerg void EmitOMPBarrierDirective(const OMPBarrierDirective &S); 34597330f729Sjoerg void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S); 34607330f729Sjoerg void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S); 34617330f729Sjoerg void EmitOMPFlushDirective(const OMPFlushDirective &S); 3462*e038c9c4Sjoerg void EmitOMPDepobjDirective(const OMPDepobjDirective &S); 3463*e038c9c4Sjoerg void EmitOMPScanDirective(const OMPScanDirective &S); 34647330f729Sjoerg void EmitOMPOrderedDirective(const OMPOrderedDirective &S); 34657330f729Sjoerg void EmitOMPAtomicDirective(const OMPAtomicDirective &S); 34667330f729Sjoerg void EmitOMPTargetDirective(const OMPTargetDirective &S); 34677330f729Sjoerg void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S); 34687330f729Sjoerg void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S); 34697330f729Sjoerg void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S); 34707330f729Sjoerg void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S); 34717330f729Sjoerg void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S); 34727330f729Sjoerg void 34737330f729Sjoerg EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S); 34747330f729Sjoerg void EmitOMPTeamsDirective(const OMPTeamsDirective &S); 34757330f729Sjoerg void 34767330f729Sjoerg EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S); 34777330f729Sjoerg void EmitOMPCancelDirective(const OMPCancelDirective &S); 34787330f729Sjoerg void EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S); 34797330f729Sjoerg void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S); 34807330f729Sjoerg void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S); 34817330f729Sjoerg void EmitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective &S); 34827330f729Sjoerg void 34837330f729Sjoerg EmitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective &S); 34847330f729Sjoerg void EmitOMPParallelMasterTaskLoopDirective( 34857330f729Sjoerg const OMPParallelMasterTaskLoopDirective &S); 3486*e038c9c4Sjoerg void EmitOMPParallelMasterTaskLoopSimdDirective( 3487*e038c9c4Sjoerg const OMPParallelMasterTaskLoopSimdDirective &S); 34887330f729Sjoerg void EmitOMPDistributeDirective(const OMPDistributeDirective &S); 34897330f729Sjoerg void EmitOMPDistributeParallelForDirective( 34907330f729Sjoerg const OMPDistributeParallelForDirective &S); 34917330f729Sjoerg void EmitOMPDistributeParallelForSimdDirective( 34927330f729Sjoerg const OMPDistributeParallelForSimdDirective &S); 34937330f729Sjoerg void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S); 34947330f729Sjoerg void EmitOMPTargetParallelForSimdDirective( 34957330f729Sjoerg const OMPTargetParallelForSimdDirective &S); 34967330f729Sjoerg void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S); 34977330f729Sjoerg void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S); 34987330f729Sjoerg void 34997330f729Sjoerg EmitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &S); 35007330f729Sjoerg void EmitOMPTeamsDistributeParallelForSimdDirective( 35017330f729Sjoerg const OMPTeamsDistributeParallelForSimdDirective &S); 35027330f729Sjoerg void EmitOMPTeamsDistributeParallelForDirective( 35037330f729Sjoerg const OMPTeamsDistributeParallelForDirective &S); 35047330f729Sjoerg void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S); 35057330f729Sjoerg void EmitOMPTargetTeamsDistributeDirective( 35067330f729Sjoerg const OMPTargetTeamsDistributeDirective &S); 35077330f729Sjoerg void EmitOMPTargetTeamsDistributeParallelForDirective( 35087330f729Sjoerg const OMPTargetTeamsDistributeParallelForDirective &S); 35097330f729Sjoerg void EmitOMPTargetTeamsDistributeParallelForSimdDirective( 35107330f729Sjoerg const OMPTargetTeamsDistributeParallelForSimdDirective &S); 35117330f729Sjoerg void EmitOMPTargetTeamsDistributeSimdDirective( 35127330f729Sjoerg const OMPTargetTeamsDistributeSimdDirective &S); 35137330f729Sjoerg 35147330f729Sjoerg /// Emit device code for the target directive. 35157330f729Sjoerg static void EmitOMPTargetDeviceFunction(CodeGenModule &CGM, 35167330f729Sjoerg StringRef ParentName, 35177330f729Sjoerg const OMPTargetDirective &S); 35187330f729Sjoerg static void 35197330f729Sjoerg EmitOMPTargetParallelDeviceFunction(CodeGenModule &CGM, StringRef ParentName, 35207330f729Sjoerg const OMPTargetParallelDirective &S); 35217330f729Sjoerg /// Emit device code for the target parallel for directive. 35227330f729Sjoerg static void EmitOMPTargetParallelForDeviceFunction( 35237330f729Sjoerg CodeGenModule &CGM, StringRef ParentName, 35247330f729Sjoerg const OMPTargetParallelForDirective &S); 35257330f729Sjoerg /// Emit device code for the target parallel for simd directive. 35267330f729Sjoerg static void EmitOMPTargetParallelForSimdDeviceFunction( 35277330f729Sjoerg CodeGenModule &CGM, StringRef ParentName, 35287330f729Sjoerg const OMPTargetParallelForSimdDirective &S); 35297330f729Sjoerg /// Emit device code for the target teams directive. 35307330f729Sjoerg static void 35317330f729Sjoerg EmitOMPTargetTeamsDeviceFunction(CodeGenModule &CGM, StringRef ParentName, 35327330f729Sjoerg const OMPTargetTeamsDirective &S); 35337330f729Sjoerg /// Emit device code for the target teams distribute directive. 35347330f729Sjoerg static void EmitOMPTargetTeamsDistributeDeviceFunction( 35357330f729Sjoerg CodeGenModule &CGM, StringRef ParentName, 35367330f729Sjoerg const OMPTargetTeamsDistributeDirective &S); 35377330f729Sjoerg /// Emit device code for the target teams distribute simd directive. 35387330f729Sjoerg static void EmitOMPTargetTeamsDistributeSimdDeviceFunction( 35397330f729Sjoerg CodeGenModule &CGM, StringRef ParentName, 35407330f729Sjoerg const OMPTargetTeamsDistributeSimdDirective &S); 35417330f729Sjoerg /// Emit device code for the target simd directive. 35427330f729Sjoerg static void EmitOMPTargetSimdDeviceFunction(CodeGenModule &CGM, 35437330f729Sjoerg StringRef ParentName, 35447330f729Sjoerg const OMPTargetSimdDirective &S); 35457330f729Sjoerg /// Emit device code for the target teams distribute parallel for simd 35467330f729Sjoerg /// directive. 35477330f729Sjoerg static void EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction( 35487330f729Sjoerg CodeGenModule &CGM, StringRef ParentName, 35497330f729Sjoerg const OMPTargetTeamsDistributeParallelForSimdDirective &S); 35507330f729Sjoerg 35517330f729Sjoerg static void EmitOMPTargetTeamsDistributeParallelForDeviceFunction( 35527330f729Sjoerg CodeGenModule &CGM, StringRef ParentName, 35537330f729Sjoerg const OMPTargetTeamsDistributeParallelForDirective &S); 3554*e038c9c4Sjoerg 3555*e038c9c4Sjoerg /// Emit the Stmt \p S and return its topmost canonical loop, if any. 3556*e038c9c4Sjoerg /// TODO: The \p Depth paramter is not yet implemented and must be 1. In the 3557*e038c9c4Sjoerg /// future it is meant to be the number of loops expected in the loop nests 3558*e038c9c4Sjoerg /// (usually specified by the "collapse" clause) that are collapsed to a 3559*e038c9c4Sjoerg /// single loop by this function. 3560*e038c9c4Sjoerg llvm::CanonicalLoopInfo *EmitOMPCollapsedCanonicalLoopNest(const Stmt *S, 3561*e038c9c4Sjoerg int Depth); 3562*e038c9c4Sjoerg 3563*e038c9c4Sjoerg /// Emit an OMPCanonicalLoop using the OpenMPIRBuilder. 3564*e038c9c4Sjoerg void EmitOMPCanonicalLoop(const OMPCanonicalLoop *S); 3565*e038c9c4Sjoerg 35667330f729Sjoerg /// Emit inner loop of the worksharing/simd construct. 35677330f729Sjoerg /// 35687330f729Sjoerg /// \param S Directive, for which the inner loop must be emitted. 35697330f729Sjoerg /// \param RequiresCleanup true, if directive has some associated private 35707330f729Sjoerg /// variables. 35717330f729Sjoerg /// \param LoopCond Bollean condition for loop continuation. 35727330f729Sjoerg /// \param IncExpr Increment expression for loop control variable. 35737330f729Sjoerg /// \param BodyGen Generator for the inner body of the inner loop. 35747330f729Sjoerg /// \param PostIncGen Genrator for post-increment code (required for ordered 35757330f729Sjoerg /// loop directvies). 35767330f729Sjoerg void EmitOMPInnerLoop( 3577*e038c9c4Sjoerg const OMPExecutableDirective &S, bool RequiresCleanup, 3578*e038c9c4Sjoerg const Expr *LoopCond, const Expr *IncExpr, 35797330f729Sjoerg const llvm::function_ref<void(CodeGenFunction &)> BodyGen, 35807330f729Sjoerg const llvm::function_ref<void(CodeGenFunction &)> PostIncGen); 35817330f729Sjoerg 35827330f729Sjoerg JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind); 35837330f729Sjoerg /// Emit initial code for loop counters of loop-based directives. 35847330f729Sjoerg void EmitOMPPrivateLoopCounters(const OMPLoopDirective &S, 35857330f729Sjoerg OMPPrivateScope &LoopScope); 35867330f729Sjoerg 35877330f729Sjoerg /// Helper for the OpenMP loop directives. 35887330f729Sjoerg void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit); 35897330f729Sjoerg 35907330f729Sjoerg /// Emit code for the worksharing loop-based directive. 35917330f729Sjoerg /// \return true, if this construct has any lastprivate clause, false - 35927330f729Sjoerg /// otherwise. 35937330f729Sjoerg bool EmitOMPWorksharingLoop(const OMPLoopDirective &S, Expr *EUB, 35947330f729Sjoerg const CodeGenLoopBoundsTy &CodeGenLoopBounds, 35957330f729Sjoerg const CodeGenDispatchBoundsTy &CGDispatchBounds); 35967330f729Sjoerg 35977330f729Sjoerg /// Emit code for the distribute loop-based directive. 35987330f729Sjoerg void EmitOMPDistributeLoop(const OMPLoopDirective &S, 35997330f729Sjoerg const CodeGenLoopTy &CodeGenLoop, Expr *IncExpr); 36007330f729Sjoerg 36017330f729Sjoerg /// Helpers for the OpenMP loop directives. 36027330f729Sjoerg void EmitOMPSimdInit(const OMPLoopDirective &D, bool IsMonotonic = false); 36037330f729Sjoerg void EmitOMPSimdFinal( 36047330f729Sjoerg const OMPLoopDirective &D, 36057330f729Sjoerg const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen); 36067330f729Sjoerg 36077330f729Sjoerg /// Emits the lvalue for the expression with possibly captured variable. 36087330f729Sjoerg LValue EmitOMPSharedLValue(const Expr *E); 36097330f729Sjoerg 36107330f729Sjoerg private: 36117330f729Sjoerg /// Helpers for blocks. 36127330f729Sjoerg llvm::Value *EmitBlockLiteral(const CGBlockInfo &Info); 36137330f729Sjoerg 36147330f729Sjoerg /// struct with the values to be passed to the OpenMP loop-related functions 36157330f729Sjoerg struct OMPLoopArguments { 36167330f729Sjoerg /// loop lower bound 36177330f729Sjoerg Address LB = Address::invalid(); 36187330f729Sjoerg /// loop upper bound 36197330f729Sjoerg Address UB = Address::invalid(); 36207330f729Sjoerg /// loop stride 36217330f729Sjoerg Address ST = Address::invalid(); 36227330f729Sjoerg /// isLastIteration argument for runtime functions 36237330f729Sjoerg Address IL = Address::invalid(); 36247330f729Sjoerg /// Chunk value generated by sema 36257330f729Sjoerg llvm::Value *Chunk = nullptr; 36267330f729Sjoerg /// EnsureUpperBound 36277330f729Sjoerg Expr *EUB = nullptr; 36287330f729Sjoerg /// IncrementExpression 36297330f729Sjoerg Expr *IncExpr = nullptr; 36307330f729Sjoerg /// Loop initialization 36317330f729Sjoerg Expr *Init = nullptr; 36327330f729Sjoerg /// Loop exit condition 36337330f729Sjoerg Expr *Cond = nullptr; 36347330f729Sjoerg /// Update of LB after a whole chunk has been executed 36357330f729Sjoerg Expr *NextLB = nullptr; 36367330f729Sjoerg /// Update of UB after a whole chunk has been executed 36377330f729Sjoerg Expr *NextUB = nullptr; 36387330f729Sjoerg OMPLoopArguments() = default; 36397330f729Sjoerg OMPLoopArguments(Address LB, Address UB, Address ST, Address IL, 36407330f729Sjoerg llvm::Value *Chunk = nullptr, Expr *EUB = nullptr, 36417330f729Sjoerg Expr *IncExpr = nullptr, Expr *Init = nullptr, 36427330f729Sjoerg Expr *Cond = nullptr, Expr *NextLB = nullptr, 36437330f729Sjoerg Expr *NextUB = nullptr) 36447330f729Sjoerg : LB(LB), UB(UB), ST(ST), IL(IL), Chunk(Chunk), EUB(EUB), 36457330f729Sjoerg IncExpr(IncExpr), Init(Init), Cond(Cond), NextLB(NextLB), 36467330f729Sjoerg NextUB(NextUB) {} 36477330f729Sjoerg }; 36487330f729Sjoerg void EmitOMPOuterLoop(bool DynamicOrOrdered, bool IsMonotonic, 36497330f729Sjoerg const OMPLoopDirective &S, OMPPrivateScope &LoopScope, 36507330f729Sjoerg const OMPLoopArguments &LoopArgs, 36517330f729Sjoerg const CodeGenLoopTy &CodeGenLoop, 36527330f729Sjoerg const CodeGenOrderedTy &CodeGenOrdered); 36537330f729Sjoerg void EmitOMPForOuterLoop(const OpenMPScheduleTy &ScheduleKind, 36547330f729Sjoerg bool IsMonotonic, const OMPLoopDirective &S, 36557330f729Sjoerg OMPPrivateScope &LoopScope, bool Ordered, 36567330f729Sjoerg const OMPLoopArguments &LoopArgs, 36577330f729Sjoerg const CodeGenDispatchBoundsTy &CGDispatchBounds); 36587330f729Sjoerg void EmitOMPDistributeOuterLoop(OpenMPDistScheduleClauseKind ScheduleKind, 36597330f729Sjoerg const OMPLoopDirective &S, 36607330f729Sjoerg OMPPrivateScope &LoopScope, 36617330f729Sjoerg const OMPLoopArguments &LoopArgs, 36627330f729Sjoerg const CodeGenLoopTy &CodeGenLoopContent); 36637330f729Sjoerg /// Emit code for sections directive. 36647330f729Sjoerg void EmitSections(const OMPExecutableDirective &S); 36657330f729Sjoerg 36667330f729Sjoerg public: 36677330f729Sjoerg 36687330f729Sjoerg //===--------------------------------------------------------------------===// 36697330f729Sjoerg // LValue Expression Emission 36707330f729Sjoerg //===--------------------------------------------------------------------===// 36717330f729Sjoerg 3672*e038c9c4Sjoerg /// Create a check that a scalar RValue is non-null. 3673*e038c9c4Sjoerg llvm::Value *EmitNonNullRValueCheck(RValue RV, QualType T); 3674*e038c9c4Sjoerg 36757330f729Sjoerg /// GetUndefRValue - Get an appropriate 'undef' rvalue for the given type. 36767330f729Sjoerg RValue GetUndefRValue(QualType Ty); 36777330f729Sjoerg 36787330f729Sjoerg /// EmitUnsupportedRValue - Emit a dummy r-value using the type of E 36797330f729Sjoerg /// and issue an ErrorUnsupported style diagnostic (using the 36807330f729Sjoerg /// provided Name). 36817330f729Sjoerg RValue EmitUnsupportedRValue(const Expr *E, 36827330f729Sjoerg const char *Name); 36837330f729Sjoerg 36847330f729Sjoerg /// EmitUnsupportedLValue - Emit a dummy l-value using the type of E and issue 36857330f729Sjoerg /// an ErrorUnsupported style diagnostic (using the provided Name). 36867330f729Sjoerg LValue EmitUnsupportedLValue(const Expr *E, 36877330f729Sjoerg const char *Name); 36887330f729Sjoerg 36897330f729Sjoerg /// EmitLValue - Emit code to compute a designator that specifies the location 36907330f729Sjoerg /// of the expression. 36917330f729Sjoerg /// 36927330f729Sjoerg /// This can return one of two things: a simple address or a bitfield 36937330f729Sjoerg /// reference. In either case, the LLVM Value* in the LValue structure is 36947330f729Sjoerg /// guaranteed to be an LLVM pointer type. 36957330f729Sjoerg /// 36967330f729Sjoerg /// If this returns a bitfield reference, nothing about the pointee type of 36977330f729Sjoerg /// the LLVM value is known: For example, it may not be a pointer to an 36987330f729Sjoerg /// integer. 36997330f729Sjoerg /// 37007330f729Sjoerg /// If this returns a normal address, and if the lvalue's C type is fixed 37017330f729Sjoerg /// size, this method guarantees that the returned pointer type will point to 37027330f729Sjoerg /// an LLVM type of the same size of the lvalue's type. If the lvalue has a 37037330f729Sjoerg /// variable length type, this is not possible. 37047330f729Sjoerg /// 37057330f729Sjoerg LValue EmitLValue(const Expr *E); 37067330f729Sjoerg 37077330f729Sjoerg /// Same as EmitLValue but additionally we generate checking code to 37087330f729Sjoerg /// guard against undefined behavior. This is only suitable when we know 37097330f729Sjoerg /// that the address will be used to access the object. 37107330f729Sjoerg LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK); 37117330f729Sjoerg 37127330f729Sjoerg RValue convertTempToRValue(Address addr, QualType type, 37137330f729Sjoerg SourceLocation Loc); 37147330f729Sjoerg 37157330f729Sjoerg void EmitAtomicInit(Expr *E, LValue lvalue); 37167330f729Sjoerg 37177330f729Sjoerg bool LValueIsSuitableForInlineAtomic(LValue Src); 37187330f729Sjoerg 37197330f729Sjoerg RValue EmitAtomicLoad(LValue LV, SourceLocation SL, 37207330f729Sjoerg AggValueSlot Slot = AggValueSlot::ignored()); 37217330f729Sjoerg 37227330f729Sjoerg RValue EmitAtomicLoad(LValue lvalue, SourceLocation loc, 37237330f729Sjoerg llvm::AtomicOrdering AO, bool IsVolatile = false, 37247330f729Sjoerg AggValueSlot slot = AggValueSlot::ignored()); 37257330f729Sjoerg 37267330f729Sjoerg void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit); 37277330f729Sjoerg 37287330f729Sjoerg void EmitAtomicStore(RValue rvalue, LValue lvalue, llvm::AtomicOrdering AO, 37297330f729Sjoerg bool IsVolatile, bool isInit); 37307330f729Sjoerg 37317330f729Sjoerg std::pair<RValue, llvm::Value *> EmitAtomicCompareExchange( 37327330f729Sjoerg LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, 37337330f729Sjoerg llvm::AtomicOrdering Success = 37347330f729Sjoerg llvm::AtomicOrdering::SequentiallyConsistent, 37357330f729Sjoerg llvm::AtomicOrdering Failure = 37367330f729Sjoerg llvm::AtomicOrdering::SequentiallyConsistent, 37377330f729Sjoerg bool IsWeak = false, AggValueSlot Slot = AggValueSlot::ignored()); 37387330f729Sjoerg 37397330f729Sjoerg void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO, 37407330f729Sjoerg const llvm::function_ref<RValue(RValue)> &UpdateOp, 37417330f729Sjoerg bool IsVolatile); 37427330f729Sjoerg 37437330f729Sjoerg /// EmitToMemory - Change a scalar value from its value 37447330f729Sjoerg /// representation to its in-memory representation. 37457330f729Sjoerg llvm::Value *EmitToMemory(llvm::Value *Value, QualType Ty); 37467330f729Sjoerg 37477330f729Sjoerg /// EmitFromMemory - Change a scalar value from its memory 37487330f729Sjoerg /// representation to its value representation. 37497330f729Sjoerg llvm::Value *EmitFromMemory(llvm::Value *Value, QualType Ty); 37507330f729Sjoerg 37517330f729Sjoerg /// Check if the scalar \p Value is within the valid range for the given 37527330f729Sjoerg /// type \p Ty. 37537330f729Sjoerg /// 37547330f729Sjoerg /// Returns true if a check is needed (even if the range is unknown). 37557330f729Sjoerg bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, 37567330f729Sjoerg SourceLocation Loc); 37577330f729Sjoerg 37587330f729Sjoerg /// EmitLoadOfScalar - Load a scalar value from an address, taking 37597330f729Sjoerg /// care to appropriately convert from the memory representation to 37607330f729Sjoerg /// the LLVM value representation. 37617330f729Sjoerg llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, 37627330f729Sjoerg SourceLocation Loc, 37637330f729Sjoerg AlignmentSource Source = AlignmentSource::Type, 37647330f729Sjoerg bool isNontemporal = false) { 37657330f729Sjoerg return EmitLoadOfScalar(Addr, Volatile, Ty, Loc, LValueBaseInfo(Source), 37667330f729Sjoerg CGM.getTBAAAccessInfo(Ty), isNontemporal); 37677330f729Sjoerg } 37687330f729Sjoerg 37697330f729Sjoerg llvm::Value *EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, 37707330f729Sjoerg SourceLocation Loc, LValueBaseInfo BaseInfo, 37717330f729Sjoerg TBAAAccessInfo TBAAInfo, 37727330f729Sjoerg bool isNontemporal = false); 37737330f729Sjoerg 37747330f729Sjoerg /// EmitLoadOfScalar - Load a scalar value from an address, taking 37757330f729Sjoerg /// care to appropriately convert from the memory representation to 37767330f729Sjoerg /// the LLVM value representation. The l-value must be a simple 37777330f729Sjoerg /// l-value. 37787330f729Sjoerg llvm::Value *EmitLoadOfScalar(LValue lvalue, SourceLocation Loc); 37797330f729Sjoerg 37807330f729Sjoerg /// EmitStoreOfScalar - Store a scalar value to an address, taking 37817330f729Sjoerg /// care to appropriately convert from the memory representation to 37827330f729Sjoerg /// the LLVM value representation. 37837330f729Sjoerg void EmitStoreOfScalar(llvm::Value *Value, Address Addr, 37847330f729Sjoerg bool Volatile, QualType Ty, 37857330f729Sjoerg AlignmentSource Source = AlignmentSource::Type, 37867330f729Sjoerg bool isInit = false, bool isNontemporal = false) { 37877330f729Sjoerg EmitStoreOfScalar(Value, Addr, Volatile, Ty, LValueBaseInfo(Source), 37887330f729Sjoerg CGM.getTBAAAccessInfo(Ty), isInit, isNontemporal); 37897330f729Sjoerg } 37907330f729Sjoerg 37917330f729Sjoerg void EmitStoreOfScalar(llvm::Value *Value, Address Addr, 37927330f729Sjoerg bool Volatile, QualType Ty, 37937330f729Sjoerg LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo, 37947330f729Sjoerg bool isInit = false, bool isNontemporal = false); 37957330f729Sjoerg 37967330f729Sjoerg /// EmitStoreOfScalar - Store a scalar value to an address, taking 37977330f729Sjoerg /// care to appropriately convert from the memory representation to 37987330f729Sjoerg /// the LLVM value representation. The l-value must be a simple 37997330f729Sjoerg /// l-value. The isInit flag indicates whether this is an initialization. 38007330f729Sjoerg /// If so, atomic qualifiers are ignored and the store is always non-atomic. 38017330f729Sjoerg void EmitStoreOfScalar(llvm::Value *value, LValue lvalue, bool isInit=false); 38027330f729Sjoerg 38037330f729Sjoerg /// EmitLoadOfLValue - Given an expression that represents a value lvalue, 38047330f729Sjoerg /// this method emits the address of the lvalue, then loads the result as an 38057330f729Sjoerg /// rvalue, returning the rvalue. 38067330f729Sjoerg RValue EmitLoadOfLValue(LValue V, SourceLocation Loc); 38077330f729Sjoerg RValue EmitLoadOfExtVectorElementLValue(LValue V); 38087330f729Sjoerg RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc); 38097330f729Sjoerg RValue EmitLoadOfGlobalRegLValue(LValue LV); 38107330f729Sjoerg 38117330f729Sjoerg /// EmitStoreThroughLValue - Store the specified rvalue into the specified 38127330f729Sjoerg /// lvalue, where both are guaranteed to the have the same type, and that type 38137330f729Sjoerg /// is 'Ty'. 38147330f729Sjoerg void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit = false); 38157330f729Sjoerg void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst); 38167330f729Sjoerg void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst); 38177330f729Sjoerg 38187330f729Sjoerg /// EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints 38197330f729Sjoerg /// as EmitStoreThroughLValue. 38207330f729Sjoerg /// 38217330f729Sjoerg /// \param Result [out] - If non-null, this will be set to a Value* for the 38227330f729Sjoerg /// bit-field contents after the store, appropriate for use as the result of 38237330f729Sjoerg /// an assignment to the bit-field. 38247330f729Sjoerg void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, 38257330f729Sjoerg llvm::Value **Result=nullptr); 38267330f729Sjoerg 38277330f729Sjoerg /// Emit an l-value for an assignment (simple or compound) of complex type. 38287330f729Sjoerg LValue EmitComplexAssignmentLValue(const BinaryOperator *E); 38297330f729Sjoerg LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E); 38307330f729Sjoerg LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, 38317330f729Sjoerg llvm::Value *&Result); 38327330f729Sjoerg 38337330f729Sjoerg // Note: only available for agg return types 38347330f729Sjoerg LValue EmitBinaryOperatorLValue(const BinaryOperator *E); 38357330f729Sjoerg LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E); 38367330f729Sjoerg // Note: only available for agg return types 38377330f729Sjoerg LValue EmitCallExprLValue(const CallExpr *E); 38387330f729Sjoerg // Note: only available for agg return types 38397330f729Sjoerg LValue EmitVAArgExprLValue(const VAArgExpr *E); 38407330f729Sjoerg LValue EmitDeclRefLValue(const DeclRefExpr *E); 38417330f729Sjoerg LValue EmitStringLiteralLValue(const StringLiteral *E); 38427330f729Sjoerg LValue EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E); 38437330f729Sjoerg LValue EmitPredefinedLValue(const PredefinedExpr *E); 38447330f729Sjoerg LValue EmitUnaryOpLValue(const UnaryOperator *E); 38457330f729Sjoerg LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E, 38467330f729Sjoerg bool Accessed = false); 3847*e038c9c4Sjoerg LValue EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E); 38487330f729Sjoerg LValue EmitOMPArraySectionExpr(const OMPArraySectionExpr *E, 38497330f729Sjoerg bool IsLowerBound = true); 38507330f729Sjoerg LValue EmitExtVectorElementExpr(const ExtVectorElementExpr *E); 38517330f729Sjoerg LValue EmitMemberExpr(const MemberExpr *E); 38527330f729Sjoerg LValue EmitObjCIsaExpr(const ObjCIsaExpr *E); 38537330f729Sjoerg LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E); 38547330f729Sjoerg LValue EmitInitListLValue(const InitListExpr *E); 38557330f729Sjoerg LValue EmitConditionalOperatorLValue(const AbstractConditionalOperator *E); 38567330f729Sjoerg LValue EmitCastLValue(const CastExpr *E); 38577330f729Sjoerg LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E); 38587330f729Sjoerg LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e); 38597330f729Sjoerg 38607330f729Sjoerg Address EmitExtVectorElementLValue(LValue V); 38617330f729Sjoerg 38627330f729Sjoerg RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc); 38637330f729Sjoerg 38647330f729Sjoerg Address EmitArrayToPointerDecay(const Expr *Array, 38657330f729Sjoerg LValueBaseInfo *BaseInfo = nullptr, 38667330f729Sjoerg TBAAAccessInfo *TBAAInfo = nullptr); 38677330f729Sjoerg 38687330f729Sjoerg class ConstantEmission { 38697330f729Sjoerg llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference; 38707330f729Sjoerg ConstantEmission(llvm::Constant *C, bool isReference) 38717330f729Sjoerg : ValueAndIsReference(C, isReference) {} 38727330f729Sjoerg public: 38737330f729Sjoerg ConstantEmission() {} 38747330f729Sjoerg static ConstantEmission forReference(llvm::Constant *C) { 38757330f729Sjoerg return ConstantEmission(C, true); 38767330f729Sjoerg } 38777330f729Sjoerg static ConstantEmission forValue(llvm::Constant *C) { 38787330f729Sjoerg return ConstantEmission(C, false); 38797330f729Sjoerg } 38807330f729Sjoerg 38817330f729Sjoerg explicit operator bool() const { 38827330f729Sjoerg return ValueAndIsReference.getOpaqueValue() != nullptr; 38837330f729Sjoerg } 38847330f729Sjoerg 38857330f729Sjoerg bool isReference() const { return ValueAndIsReference.getInt(); } 38867330f729Sjoerg LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const { 38877330f729Sjoerg assert(isReference()); 38887330f729Sjoerg return CGF.MakeNaturalAlignAddrLValue(ValueAndIsReference.getPointer(), 38897330f729Sjoerg refExpr->getType()); 38907330f729Sjoerg } 38917330f729Sjoerg 38927330f729Sjoerg llvm::Constant *getValue() const { 38937330f729Sjoerg assert(!isReference()); 38947330f729Sjoerg return ValueAndIsReference.getPointer(); 38957330f729Sjoerg } 38967330f729Sjoerg }; 38977330f729Sjoerg 38987330f729Sjoerg ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr); 38997330f729Sjoerg ConstantEmission tryEmitAsConstant(const MemberExpr *ME); 39007330f729Sjoerg llvm::Value *emitScalarConstant(const ConstantEmission &Constant, Expr *E); 39017330f729Sjoerg 39027330f729Sjoerg RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, 39037330f729Sjoerg AggValueSlot slot = AggValueSlot::ignored()); 39047330f729Sjoerg LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e); 39057330f729Sjoerg 39067330f729Sjoerg llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface, 39077330f729Sjoerg const ObjCIvarDecl *Ivar); 39087330f729Sjoerg LValue EmitLValueForField(LValue Base, const FieldDecl* Field); 39097330f729Sjoerg LValue EmitLValueForLambdaField(const FieldDecl *Field); 39107330f729Sjoerg 39117330f729Sjoerg /// EmitLValueForFieldInitialization - Like EmitLValueForField, except that 39127330f729Sjoerg /// if the Field is a reference, this will return the address of the reference 39137330f729Sjoerg /// and not the address of the value stored in the reference. 39147330f729Sjoerg LValue EmitLValueForFieldInitialization(LValue Base, 39157330f729Sjoerg const FieldDecl* Field); 39167330f729Sjoerg 39177330f729Sjoerg LValue EmitLValueForIvar(QualType ObjectTy, 39187330f729Sjoerg llvm::Value* Base, const ObjCIvarDecl *Ivar, 39197330f729Sjoerg unsigned CVRQualifiers); 39207330f729Sjoerg 39217330f729Sjoerg LValue EmitCXXConstructLValue(const CXXConstructExpr *E); 39227330f729Sjoerg LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E); 39237330f729Sjoerg LValue EmitCXXTypeidLValue(const CXXTypeidExpr *E); 39247330f729Sjoerg LValue EmitCXXUuidofLValue(const CXXUuidofExpr *E); 39257330f729Sjoerg 39267330f729Sjoerg LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E); 39277330f729Sjoerg LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E); 39287330f729Sjoerg LValue EmitStmtExprLValue(const StmtExpr *E); 39297330f729Sjoerg LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E); 39307330f729Sjoerg LValue EmitObjCSelectorLValue(const ObjCSelectorExpr *E); 39317330f729Sjoerg void EmitDeclRefExprDbgValue(const DeclRefExpr *E, const APValue &Init); 39327330f729Sjoerg 39337330f729Sjoerg //===--------------------------------------------------------------------===// 39347330f729Sjoerg // Scalar Expression Emission 39357330f729Sjoerg //===--------------------------------------------------------------------===// 39367330f729Sjoerg 39377330f729Sjoerg /// EmitCall - Generate a call of the given function, expecting the given 39387330f729Sjoerg /// result type, and using the given argument list which specifies both the 39397330f729Sjoerg /// LLVM arguments and the types they were derived from. 39407330f729Sjoerg RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, 39417330f729Sjoerg ReturnValueSlot ReturnValue, const CallArgList &Args, 3942*e038c9c4Sjoerg llvm::CallBase **callOrInvoke, bool IsMustTail, 3943*e038c9c4Sjoerg SourceLocation Loc); 39447330f729Sjoerg RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, 39457330f729Sjoerg ReturnValueSlot ReturnValue, const CallArgList &Args, 3946*e038c9c4Sjoerg llvm::CallBase **callOrInvoke = nullptr, 3947*e038c9c4Sjoerg bool IsMustTail = false) { 39487330f729Sjoerg return EmitCall(CallInfo, Callee, ReturnValue, Args, callOrInvoke, 3949*e038c9c4Sjoerg IsMustTail, SourceLocation()); 39507330f729Sjoerg } 39517330f729Sjoerg RValue EmitCall(QualType FnType, const CGCallee &Callee, const CallExpr *E, 39527330f729Sjoerg ReturnValueSlot ReturnValue, llvm::Value *Chain = nullptr); 39537330f729Sjoerg RValue EmitCallExpr(const CallExpr *E, 39547330f729Sjoerg ReturnValueSlot ReturnValue = ReturnValueSlot()); 39557330f729Sjoerg RValue EmitSimpleCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue); 39567330f729Sjoerg CGCallee EmitCallee(const Expr *E); 39577330f729Sjoerg 39587330f729Sjoerg void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl); 39597330f729Sjoerg void checkTargetFeatures(SourceLocation Loc, const FunctionDecl *TargetDecl); 39607330f729Sjoerg 39617330f729Sjoerg llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee, 39627330f729Sjoerg const Twine &name = ""); 39637330f729Sjoerg llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee, 39647330f729Sjoerg ArrayRef<llvm::Value *> args, 39657330f729Sjoerg const Twine &name = ""); 39667330f729Sjoerg llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, 39677330f729Sjoerg const Twine &name = ""); 39687330f729Sjoerg llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, 39697330f729Sjoerg ArrayRef<llvm::Value *> args, 39707330f729Sjoerg const Twine &name = ""); 39717330f729Sjoerg 39727330f729Sjoerg SmallVector<llvm::OperandBundleDef, 1> 39737330f729Sjoerg getBundlesForFunclet(llvm::Value *Callee); 39747330f729Sjoerg 39757330f729Sjoerg llvm::CallBase *EmitCallOrInvoke(llvm::FunctionCallee Callee, 39767330f729Sjoerg ArrayRef<llvm::Value *> Args, 39777330f729Sjoerg const Twine &Name = ""); 39787330f729Sjoerg llvm::CallBase *EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, 39797330f729Sjoerg ArrayRef<llvm::Value *> args, 39807330f729Sjoerg const Twine &name = ""); 39817330f729Sjoerg llvm::CallBase *EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, 39827330f729Sjoerg const Twine &name = ""); 39837330f729Sjoerg void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, 39847330f729Sjoerg ArrayRef<llvm::Value *> args); 39857330f729Sjoerg 39867330f729Sjoerg CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD, 39877330f729Sjoerg NestedNameSpecifier *Qual, 39887330f729Sjoerg llvm::Type *Ty); 39897330f729Sjoerg 39907330f729Sjoerg CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, 39917330f729Sjoerg CXXDtorType Type, 39927330f729Sjoerg const CXXRecordDecl *RD); 39937330f729Sjoerg 39947330f729Sjoerg // Return the copy constructor name with the prefix "__copy_constructor_" 39957330f729Sjoerg // removed. 39967330f729Sjoerg static std::string getNonTrivialCopyConstructorStr(QualType QT, 39977330f729Sjoerg CharUnits Alignment, 39987330f729Sjoerg bool IsVolatile, 39997330f729Sjoerg ASTContext &Ctx); 40007330f729Sjoerg 40017330f729Sjoerg // Return the destructor name with the prefix "__destructor_" removed. 40027330f729Sjoerg static std::string getNonTrivialDestructorStr(QualType QT, 40037330f729Sjoerg CharUnits Alignment, 40047330f729Sjoerg bool IsVolatile, 40057330f729Sjoerg ASTContext &Ctx); 40067330f729Sjoerg 40077330f729Sjoerg // These functions emit calls to the special functions of non-trivial C 40087330f729Sjoerg // structs. 40097330f729Sjoerg void defaultInitNonTrivialCStructVar(LValue Dst); 40107330f729Sjoerg void callCStructDefaultConstructor(LValue Dst); 40117330f729Sjoerg void callCStructDestructor(LValue Dst); 40127330f729Sjoerg void callCStructCopyConstructor(LValue Dst, LValue Src); 40137330f729Sjoerg void callCStructMoveConstructor(LValue Dst, LValue Src); 40147330f729Sjoerg void callCStructCopyAssignmentOperator(LValue Dst, LValue Src); 40157330f729Sjoerg void callCStructMoveAssignmentOperator(LValue Dst, LValue Src); 40167330f729Sjoerg 40177330f729Sjoerg RValue 40187330f729Sjoerg EmitCXXMemberOrOperatorCall(const CXXMethodDecl *Method, 40197330f729Sjoerg const CGCallee &Callee, 40207330f729Sjoerg ReturnValueSlot ReturnValue, llvm::Value *This, 40217330f729Sjoerg llvm::Value *ImplicitParam, 40227330f729Sjoerg QualType ImplicitParamTy, const CallExpr *E, 40237330f729Sjoerg CallArgList *RtlArgs); 40247330f729Sjoerg RValue EmitCXXDestructorCall(GlobalDecl Dtor, const CGCallee &Callee, 40257330f729Sjoerg llvm::Value *This, QualType ThisTy, 40267330f729Sjoerg llvm::Value *ImplicitParam, 40277330f729Sjoerg QualType ImplicitParamTy, const CallExpr *E); 40287330f729Sjoerg RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E, 40297330f729Sjoerg ReturnValueSlot ReturnValue); 40307330f729Sjoerg RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE, 40317330f729Sjoerg const CXXMethodDecl *MD, 40327330f729Sjoerg ReturnValueSlot ReturnValue, 40337330f729Sjoerg bool HasQualifier, 40347330f729Sjoerg NestedNameSpecifier *Qualifier, 40357330f729Sjoerg bool IsArrow, const Expr *Base); 40367330f729Sjoerg // Compute the object pointer. 40377330f729Sjoerg Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base, 40387330f729Sjoerg llvm::Value *memberPtr, 40397330f729Sjoerg const MemberPointerType *memberPtrType, 40407330f729Sjoerg LValueBaseInfo *BaseInfo = nullptr, 40417330f729Sjoerg TBAAAccessInfo *TBAAInfo = nullptr); 40427330f729Sjoerg RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, 40437330f729Sjoerg ReturnValueSlot ReturnValue); 40447330f729Sjoerg 40457330f729Sjoerg RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, 40467330f729Sjoerg const CXXMethodDecl *MD, 40477330f729Sjoerg ReturnValueSlot ReturnValue); 40487330f729Sjoerg RValue EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E); 40497330f729Sjoerg 40507330f729Sjoerg RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E, 40517330f729Sjoerg ReturnValueSlot ReturnValue); 40527330f729Sjoerg 40537330f729Sjoerg RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E, 40547330f729Sjoerg ReturnValueSlot ReturnValue); 4055*e038c9c4Sjoerg RValue EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E, 4056*e038c9c4Sjoerg ReturnValueSlot ReturnValue); 40577330f729Sjoerg 40587330f729Sjoerg RValue EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, 40597330f729Sjoerg const CallExpr *E, ReturnValueSlot ReturnValue); 40607330f729Sjoerg 40617330f729Sjoerg RValue emitRotate(const CallExpr *E, bool IsRotateRight); 40627330f729Sjoerg 40637330f729Sjoerg /// Emit IR for __builtin_os_log_format. 40647330f729Sjoerg RValue emitBuiltinOSLogFormat(const CallExpr &E); 40657330f729Sjoerg 4066*e038c9c4Sjoerg /// Emit IR for __builtin_is_aligned. 4067*e038c9c4Sjoerg RValue EmitBuiltinIsAligned(const CallExpr *E); 4068*e038c9c4Sjoerg /// Emit IR for __builtin_align_up/__builtin_align_down. 4069*e038c9c4Sjoerg RValue EmitBuiltinAlignTo(const CallExpr *E, bool AlignUp); 4070*e038c9c4Sjoerg 40717330f729Sjoerg llvm::Function *generateBuiltinOSLogHelperFunction( 40727330f729Sjoerg const analyze_os_log::OSLogBufferLayout &Layout, 40737330f729Sjoerg CharUnits BufferAlignment); 40747330f729Sjoerg 40757330f729Sjoerg RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue); 40767330f729Sjoerg 40777330f729Sjoerg /// EmitTargetBuiltinExpr - Emit the given builtin call. Returns 0 if the call 40787330f729Sjoerg /// is unhandled by the current target. 40797330f729Sjoerg llvm::Value *EmitTargetBuiltinExpr(unsigned BuiltinID, const CallExpr *E, 40807330f729Sjoerg ReturnValueSlot ReturnValue); 40817330f729Sjoerg 40827330f729Sjoerg llvm::Value *EmitAArch64CompareBuiltinExpr(llvm::Value *Op, llvm::Type *Ty, 40837330f729Sjoerg const llvm::CmpInst::Predicate Fp, 40847330f729Sjoerg const llvm::CmpInst::Predicate Ip, 40857330f729Sjoerg const llvm::Twine &Name = ""); 40867330f729Sjoerg llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E, 40877330f729Sjoerg ReturnValueSlot ReturnValue, 40887330f729Sjoerg llvm::Triple::ArchType Arch); 40897330f729Sjoerg llvm::Value *EmitARMMVEBuiltinExpr(unsigned BuiltinID, const CallExpr *E, 40907330f729Sjoerg ReturnValueSlot ReturnValue, 40917330f729Sjoerg llvm::Triple::ArchType Arch); 4092*e038c9c4Sjoerg llvm::Value *EmitARMCDEBuiltinExpr(unsigned BuiltinID, const CallExpr *E, 4093*e038c9c4Sjoerg ReturnValueSlot ReturnValue, 4094*e038c9c4Sjoerg llvm::Triple::ArchType Arch); 4095*e038c9c4Sjoerg llvm::Value *EmitCMSEClearRecord(llvm::Value *V, llvm::IntegerType *ITy, 4096*e038c9c4Sjoerg QualType RTy); 4097*e038c9c4Sjoerg llvm::Value *EmitCMSEClearRecord(llvm::Value *V, llvm::ArrayType *ATy, 4098*e038c9c4Sjoerg QualType RTy); 40997330f729Sjoerg 41007330f729Sjoerg llvm::Value *EmitCommonNeonBuiltinExpr(unsigned BuiltinID, 41017330f729Sjoerg unsigned LLVMIntrinsic, 41027330f729Sjoerg unsigned AltLLVMIntrinsic, 41037330f729Sjoerg const char *NameHint, 41047330f729Sjoerg unsigned Modifier, 41057330f729Sjoerg const CallExpr *E, 41067330f729Sjoerg SmallVectorImpl<llvm::Value *> &Ops, 41077330f729Sjoerg Address PtrOp0, Address PtrOp1, 41087330f729Sjoerg llvm::Triple::ArchType Arch); 41097330f729Sjoerg 41107330f729Sjoerg llvm::Function *LookupNeonLLVMIntrinsic(unsigned IntrinsicID, 41117330f729Sjoerg unsigned Modifier, llvm::Type *ArgTy, 41127330f729Sjoerg const CallExpr *E); 41137330f729Sjoerg llvm::Value *EmitNeonCall(llvm::Function *F, 41147330f729Sjoerg SmallVectorImpl<llvm::Value*> &O, 41157330f729Sjoerg const char *name, 41167330f729Sjoerg unsigned shift = 0, bool rightshift = false); 4117*e038c9c4Sjoerg llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx, 4118*e038c9c4Sjoerg const llvm::ElementCount &Count); 41197330f729Sjoerg llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx); 41207330f729Sjoerg llvm::Value *EmitNeonShiftVector(llvm::Value *V, llvm::Type *Ty, 41217330f729Sjoerg bool negateForRightShift); 41227330f729Sjoerg llvm::Value *EmitNeonRShiftImm(llvm::Value *Vec, llvm::Value *Amt, 41237330f729Sjoerg llvm::Type *Ty, bool usgn, const char *name); 41247330f729Sjoerg llvm::Value *vectorWrapScalar16(llvm::Value *Op); 4125*e038c9c4Sjoerg /// SVEBuiltinMemEltTy - Returns the memory element type for this memory 4126*e038c9c4Sjoerg /// access builtin. Only required if it can't be inferred from the base 4127*e038c9c4Sjoerg /// pointer operand. 4128*e038c9c4Sjoerg llvm::Type *SVEBuiltinMemEltTy(SVETypeFlags TypeFlags); 4129*e038c9c4Sjoerg 4130*e038c9c4Sjoerg SmallVector<llvm::Type *, 2> getSVEOverloadTypes(SVETypeFlags TypeFlags, 4131*e038c9c4Sjoerg llvm::Type *ReturnType, 4132*e038c9c4Sjoerg ArrayRef<llvm::Value *> Ops); 4133*e038c9c4Sjoerg llvm::Type *getEltType(SVETypeFlags TypeFlags); 4134*e038c9c4Sjoerg llvm::ScalableVectorType *getSVEType(const SVETypeFlags &TypeFlags); 4135*e038c9c4Sjoerg llvm::ScalableVectorType *getSVEPredType(SVETypeFlags TypeFlags); 4136*e038c9c4Sjoerg llvm::Value *EmitSVEAllTruePred(SVETypeFlags TypeFlags); 4137*e038c9c4Sjoerg llvm::Value *EmitSVEDupX(llvm::Value *Scalar); 4138*e038c9c4Sjoerg llvm::Value *EmitSVEDupX(llvm::Value *Scalar, llvm::Type *Ty); 4139*e038c9c4Sjoerg llvm::Value *EmitSVEReinterpret(llvm::Value *Val, llvm::Type *Ty); 4140*e038c9c4Sjoerg llvm::Value *EmitSVEPMull(SVETypeFlags TypeFlags, 4141*e038c9c4Sjoerg llvm::SmallVectorImpl<llvm::Value *> &Ops, 4142*e038c9c4Sjoerg unsigned BuiltinID); 4143*e038c9c4Sjoerg llvm::Value *EmitSVEMovl(SVETypeFlags TypeFlags, 4144*e038c9c4Sjoerg llvm::ArrayRef<llvm::Value *> Ops, 4145*e038c9c4Sjoerg unsigned BuiltinID); 4146*e038c9c4Sjoerg llvm::Value *EmitSVEPredicateCast(llvm::Value *Pred, 4147*e038c9c4Sjoerg llvm::ScalableVectorType *VTy); 4148*e038c9c4Sjoerg llvm::Value *EmitSVEGatherLoad(SVETypeFlags TypeFlags, 4149*e038c9c4Sjoerg llvm::SmallVectorImpl<llvm::Value *> &Ops, 4150*e038c9c4Sjoerg unsigned IntID); 4151*e038c9c4Sjoerg llvm::Value *EmitSVEScatterStore(SVETypeFlags TypeFlags, 4152*e038c9c4Sjoerg llvm::SmallVectorImpl<llvm::Value *> &Ops, 4153*e038c9c4Sjoerg unsigned IntID); 4154*e038c9c4Sjoerg llvm::Value *EmitSVEMaskedLoad(const CallExpr *, llvm::Type *ReturnTy, 4155*e038c9c4Sjoerg SmallVectorImpl<llvm::Value *> &Ops, 4156*e038c9c4Sjoerg unsigned BuiltinID, bool IsZExtReturn); 4157*e038c9c4Sjoerg llvm::Value *EmitSVEMaskedStore(const CallExpr *, 4158*e038c9c4Sjoerg SmallVectorImpl<llvm::Value *> &Ops, 4159*e038c9c4Sjoerg unsigned BuiltinID); 4160*e038c9c4Sjoerg llvm::Value *EmitSVEPrefetchLoad(SVETypeFlags TypeFlags, 4161*e038c9c4Sjoerg SmallVectorImpl<llvm::Value *> &Ops, 4162*e038c9c4Sjoerg unsigned BuiltinID); 4163*e038c9c4Sjoerg llvm::Value *EmitSVEGatherPrefetch(SVETypeFlags TypeFlags, 4164*e038c9c4Sjoerg SmallVectorImpl<llvm::Value *> &Ops, 4165*e038c9c4Sjoerg unsigned IntID); 4166*e038c9c4Sjoerg llvm::Value *EmitSVEStructLoad(SVETypeFlags TypeFlags, 4167*e038c9c4Sjoerg SmallVectorImpl<llvm::Value *> &Ops, unsigned IntID); 4168*e038c9c4Sjoerg llvm::Value *EmitSVEStructStore(SVETypeFlags TypeFlags, 4169*e038c9c4Sjoerg SmallVectorImpl<llvm::Value *> &Ops, 4170*e038c9c4Sjoerg unsigned IntID); 4171*e038c9c4Sjoerg llvm::Value *EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 4172*e038c9c4Sjoerg 41737330f729Sjoerg llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, 41747330f729Sjoerg llvm::Triple::ArchType Arch); 41757330f729Sjoerg llvm::Value *EmitBPFBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 41767330f729Sjoerg 41777330f729Sjoerg llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops); 41787330f729Sjoerg llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E); 41797330f729Sjoerg llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 41807330f729Sjoerg llvm::Value *EmitAMDGPUBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 41817330f729Sjoerg llvm::Value *EmitSystemZBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 41827330f729Sjoerg llvm::Value *EmitNVPTXBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 41837330f729Sjoerg llvm::Value *EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, 41847330f729Sjoerg const CallExpr *E); 41857330f729Sjoerg llvm::Value *EmitHexagonBuiltinExpr(unsigned BuiltinID, const CallExpr *E); 4186*e038c9c4Sjoerg llvm::Value *EmitRISCVBuiltinExpr(unsigned BuiltinID, const CallExpr *E, 4187*e038c9c4Sjoerg ReturnValueSlot ReturnValue); 4188*e038c9c4Sjoerg bool ProcessOrderScopeAMDGCN(llvm::Value *Order, llvm::Value *Scope, 4189*e038c9c4Sjoerg llvm::AtomicOrdering &AO, 4190*e038c9c4Sjoerg llvm::SyncScope::ID &SSID); 41917330f729Sjoerg 41927330f729Sjoerg enum class MSVCIntrin; 41937330f729Sjoerg llvm::Value *EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E); 41947330f729Sjoerg 4195*e038c9c4Sjoerg llvm::Value *EmitBuiltinAvailable(const VersionTuple &Version); 41967330f729Sjoerg 41977330f729Sjoerg llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E); 41987330f729Sjoerg llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E); 41997330f729Sjoerg llvm::Value *EmitObjCBoxedExpr(const ObjCBoxedExpr *E); 42007330f729Sjoerg llvm::Value *EmitObjCArrayLiteral(const ObjCArrayLiteral *E); 42017330f729Sjoerg llvm::Value *EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E); 42027330f729Sjoerg llvm::Value *EmitObjCCollectionLiteral(const Expr *E, 42037330f729Sjoerg const ObjCMethodDecl *MethodWithObjects); 42047330f729Sjoerg llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E); 42057330f729Sjoerg RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, 42067330f729Sjoerg ReturnValueSlot Return = ReturnValueSlot()); 42077330f729Sjoerg 42087330f729Sjoerg /// Retrieves the default cleanup kind for an ARC cleanup. 42097330f729Sjoerg /// Except under -fobjc-arc-eh, ARC cleanups are normal-only. 42107330f729Sjoerg CleanupKind getARCCleanupKind() { 42117330f729Sjoerg return CGM.getCodeGenOpts().ObjCAutoRefCountExceptions 42127330f729Sjoerg ? NormalAndEHCleanup : NormalCleanup; 42137330f729Sjoerg } 42147330f729Sjoerg 42157330f729Sjoerg // ARC primitives. 42167330f729Sjoerg void EmitARCInitWeak(Address addr, llvm::Value *value); 42177330f729Sjoerg void EmitARCDestroyWeak(Address addr); 42187330f729Sjoerg llvm::Value *EmitARCLoadWeak(Address addr); 42197330f729Sjoerg llvm::Value *EmitARCLoadWeakRetained(Address addr); 42207330f729Sjoerg llvm::Value *EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored); 42217330f729Sjoerg void emitARCCopyAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr); 42227330f729Sjoerg void emitARCMoveAssignWeak(QualType Ty, Address DstAddr, Address SrcAddr); 42237330f729Sjoerg void EmitARCCopyWeak(Address dst, Address src); 42247330f729Sjoerg void EmitARCMoveWeak(Address dst, Address src); 42257330f729Sjoerg llvm::Value *EmitARCRetainAutorelease(QualType type, llvm::Value *value); 42267330f729Sjoerg llvm::Value *EmitARCRetainAutoreleaseNonBlock(llvm::Value *value); 42277330f729Sjoerg llvm::Value *EmitARCStoreStrong(LValue lvalue, llvm::Value *value, 42287330f729Sjoerg bool resultIgnored); 42297330f729Sjoerg llvm::Value *EmitARCStoreStrongCall(Address addr, llvm::Value *value, 42307330f729Sjoerg bool resultIgnored); 42317330f729Sjoerg llvm::Value *EmitARCRetain(QualType type, llvm::Value *value); 42327330f729Sjoerg llvm::Value *EmitARCRetainNonBlock(llvm::Value *value); 42337330f729Sjoerg llvm::Value *EmitARCRetainBlock(llvm::Value *value, bool mandatory); 42347330f729Sjoerg void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise); 42357330f729Sjoerg void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise); 42367330f729Sjoerg llvm::Value *EmitARCAutorelease(llvm::Value *value); 42377330f729Sjoerg llvm::Value *EmitARCAutoreleaseReturnValue(llvm::Value *value); 42387330f729Sjoerg llvm::Value *EmitARCRetainAutoreleaseReturnValue(llvm::Value *value); 42397330f729Sjoerg llvm::Value *EmitARCRetainAutoreleasedReturnValue(llvm::Value *value); 42407330f729Sjoerg llvm::Value *EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value); 42417330f729Sjoerg 42427330f729Sjoerg llvm::Value *EmitObjCAutorelease(llvm::Value *value, llvm::Type *returnType); 42437330f729Sjoerg llvm::Value *EmitObjCRetainNonBlock(llvm::Value *value, 42447330f729Sjoerg llvm::Type *returnType); 42457330f729Sjoerg void EmitObjCRelease(llvm::Value *value, ARCPreciseLifetime_t precise); 42467330f729Sjoerg 42477330f729Sjoerg std::pair<LValue,llvm::Value*> 42487330f729Sjoerg EmitARCStoreAutoreleasing(const BinaryOperator *e); 42497330f729Sjoerg std::pair<LValue,llvm::Value*> 42507330f729Sjoerg EmitARCStoreStrong(const BinaryOperator *e, bool ignored); 42517330f729Sjoerg std::pair<LValue,llvm::Value*> 42527330f729Sjoerg EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored); 42537330f729Sjoerg 42547330f729Sjoerg llvm::Value *EmitObjCAlloc(llvm::Value *value, 42557330f729Sjoerg llvm::Type *returnType); 42567330f729Sjoerg llvm::Value *EmitObjCAllocWithZone(llvm::Value *value, 42577330f729Sjoerg llvm::Type *returnType); 42587330f729Sjoerg llvm::Value *EmitObjCAllocInit(llvm::Value *value, llvm::Type *resultType); 42597330f729Sjoerg 42607330f729Sjoerg llvm::Value *EmitObjCThrowOperand(const Expr *expr); 42617330f729Sjoerg llvm::Value *EmitObjCConsumeObject(QualType T, llvm::Value *Ptr); 42627330f729Sjoerg llvm::Value *EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr); 42637330f729Sjoerg 42647330f729Sjoerg llvm::Value *EmitARCExtendBlockObject(const Expr *expr); 42657330f729Sjoerg llvm::Value *EmitARCReclaimReturnedObject(const Expr *e, 42667330f729Sjoerg bool allowUnsafeClaim); 42677330f729Sjoerg llvm::Value *EmitARCRetainScalarExpr(const Expr *expr); 42687330f729Sjoerg llvm::Value *EmitARCRetainAutoreleaseScalarExpr(const Expr *expr); 42697330f729Sjoerg llvm::Value *EmitARCUnsafeUnretainedScalarExpr(const Expr *expr); 42707330f729Sjoerg 42717330f729Sjoerg void EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values); 42727330f729Sjoerg 4273*e038c9c4Sjoerg void EmitARCNoopIntrinsicUse(ArrayRef<llvm::Value *> values); 4274*e038c9c4Sjoerg 42757330f729Sjoerg static Destroyer destroyARCStrongImprecise; 42767330f729Sjoerg static Destroyer destroyARCStrongPrecise; 42777330f729Sjoerg static Destroyer destroyARCWeak; 42787330f729Sjoerg static Destroyer emitARCIntrinsicUse; 42797330f729Sjoerg static Destroyer destroyNonTrivialCStruct; 42807330f729Sjoerg 42817330f729Sjoerg void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr); 42827330f729Sjoerg llvm::Value *EmitObjCAutoreleasePoolPush(); 42837330f729Sjoerg llvm::Value *EmitObjCMRRAutoreleasePoolPush(); 42847330f729Sjoerg void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr); 42857330f729Sjoerg void EmitObjCMRRAutoreleasePoolPop(llvm::Value *Ptr); 42867330f729Sjoerg 42877330f729Sjoerg /// Emits a reference binding to the passed in expression. 42887330f729Sjoerg RValue EmitReferenceBindingToExpr(const Expr *E); 42897330f729Sjoerg 42907330f729Sjoerg //===--------------------------------------------------------------------===// 42917330f729Sjoerg // Expression Emission 42927330f729Sjoerg //===--------------------------------------------------------------------===// 42937330f729Sjoerg 42947330f729Sjoerg // Expressions are broken into three classes: scalar, complex, aggregate. 42957330f729Sjoerg 42967330f729Sjoerg /// EmitScalarExpr - Emit the computation of the specified expression of LLVM 42977330f729Sjoerg /// scalar type, returning the result. 42987330f729Sjoerg llvm::Value *EmitScalarExpr(const Expr *E , bool IgnoreResultAssign = false); 42997330f729Sjoerg 43007330f729Sjoerg /// Emit a conversion from the specified type to the specified destination 43017330f729Sjoerg /// type, both of which are LLVM scalar types. 43027330f729Sjoerg llvm::Value *EmitScalarConversion(llvm::Value *Src, QualType SrcTy, 43037330f729Sjoerg QualType DstTy, SourceLocation Loc); 43047330f729Sjoerg 43057330f729Sjoerg /// Emit a conversion from the specified complex type to the specified 43067330f729Sjoerg /// destination type, where the destination type is an LLVM scalar type. 43077330f729Sjoerg llvm::Value *EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, 43087330f729Sjoerg QualType DstTy, 43097330f729Sjoerg SourceLocation Loc); 43107330f729Sjoerg 43117330f729Sjoerg /// EmitAggExpr - Emit the computation of the specified expression 43127330f729Sjoerg /// of aggregate type. The result is computed into the given slot, 43137330f729Sjoerg /// which may be null to indicate that the value is not needed. 43147330f729Sjoerg void EmitAggExpr(const Expr *E, AggValueSlot AS); 43157330f729Sjoerg 43167330f729Sjoerg /// EmitAggExprToLValue - Emit the computation of the specified expression of 43177330f729Sjoerg /// aggregate type into a temporary LValue. 43187330f729Sjoerg LValue EmitAggExprToLValue(const Expr *E); 43197330f729Sjoerg 4320*e038c9c4Sjoerg /// Build all the stores needed to initialize an aggregate at Dest with the 4321*e038c9c4Sjoerg /// value Val. 4322*e038c9c4Sjoerg void EmitAggregateStore(llvm::Value *Val, Address Dest, bool DestIsVolatile); 4323*e038c9c4Sjoerg 43247330f729Sjoerg /// EmitExtendGCLifetime - Given a pointer to an Objective-C object, 43257330f729Sjoerg /// make sure it survives garbage collection until this point. 43267330f729Sjoerg void EmitExtendGCLifetime(llvm::Value *object); 43277330f729Sjoerg 43287330f729Sjoerg /// EmitComplexExpr - Emit the computation of the specified expression of 43297330f729Sjoerg /// complex type, returning the result. 43307330f729Sjoerg ComplexPairTy EmitComplexExpr(const Expr *E, 43317330f729Sjoerg bool IgnoreReal = false, 43327330f729Sjoerg bool IgnoreImag = false); 43337330f729Sjoerg 43347330f729Sjoerg /// EmitComplexExprIntoLValue - Emit the given expression of complex 43357330f729Sjoerg /// type and place its result into the specified l-value. 43367330f729Sjoerg void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit); 43377330f729Sjoerg 43387330f729Sjoerg /// EmitStoreOfComplex - Store a complex number into the specified l-value. 43397330f729Sjoerg void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit); 43407330f729Sjoerg 43417330f729Sjoerg /// EmitLoadOfComplex - Load a complex number from the specified l-value. 43427330f729Sjoerg ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc); 43437330f729Sjoerg 43447330f729Sjoerg Address emitAddrOfRealComponent(Address complex, QualType complexType); 43457330f729Sjoerg Address emitAddrOfImagComponent(Address complex, QualType complexType); 43467330f729Sjoerg 43477330f729Sjoerg /// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the 43487330f729Sjoerg /// global variable that has already been created for it. If the initializer 43497330f729Sjoerg /// has a different type than GV does, this may free GV and return a different 43507330f729Sjoerg /// one. Otherwise it just returns GV. 43517330f729Sjoerg llvm::GlobalVariable * 43527330f729Sjoerg AddInitializerToStaticVarDecl(const VarDecl &D, 43537330f729Sjoerg llvm::GlobalVariable *GV); 43547330f729Sjoerg 43557330f729Sjoerg // Emit an @llvm.invariant.start call for the given memory region. 43567330f729Sjoerg void EmitInvariantStart(llvm::Constant *Addr, CharUnits Size); 43577330f729Sjoerg 43587330f729Sjoerg /// EmitCXXGlobalVarDeclInit - Create the initializer for a C++ 43597330f729Sjoerg /// variable with global storage. 43607330f729Sjoerg void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, 43617330f729Sjoerg bool PerformInit); 43627330f729Sjoerg 43637330f729Sjoerg llvm::Function *createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, 43647330f729Sjoerg llvm::Constant *Addr); 43657330f729Sjoerg 43667330f729Sjoerg /// Call atexit() with a function that passes the given argument to 43677330f729Sjoerg /// the given function. 43687330f729Sjoerg void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, 43697330f729Sjoerg llvm::Constant *addr); 43707330f729Sjoerg 43717330f729Sjoerg /// Call atexit() with function dtorStub. 43727330f729Sjoerg void registerGlobalDtorWithAtExit(llvm::Constant *dtorStub); 43737330f729Sjoerg 4374*e038c9c4Sjoerg /// Call unatexit() with function dtorStub. 4375*e038c9c4Sjoerg llvm::Value *unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub); 4376*e038c9c4Sjoerg 43777330f729Sjoerg /// Emit code in this function to perform a guarded variable 43787330f729Sjoerg /// initialization. Guarded initializations are used when it's not 43797330f729Sjoerg /// possible to prove that an initialization will be done exactly 43807330f729Sjoerg /// once, e.g. with a static local variable or a static data member 43817330f729Sjoerg /// of a class template. 43827330f729Sjoerg void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr, 43837330f729Sjoerg bool PerformInit); 43847330f729Sjoerg 43857330f729Sjoerg enum class GuardKind { VariableGuard, TlsGuard }; 43867330f729Sjoerg 43877330f729Sjoerg /// Emit a branch to select whether or not to perform guarded initialization. 43887330f729Sjoerg void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, 43897330f729Sjoerg llvm::BasicBlock *InitBlock, 43907330f729Sjoerg llvm::BasicBlock *NoInitBlock, 43917330f729Sjoerg GuardKind Kind, const VarDecl *D); 43927330f729Sjoerg 43937330f729Sjoerg /// GenerateCXXGlobalInitFunc - Generates code for initializing global 43947330f729Sjoerg /// variables. 43957330f729Sjoerg void 43967330f729Sjoerg GenerateCXXGlobalInitFunc(llvm::Function *Fn, 43977330f729Sjoerg ArrayRef<llvm::Function *> CXXThreadLocals, 43987330f729Sjoerg ConstantAddress Guard = ConstantAddress::invalid()); 43997330f729Sjoerg 4400*e038c9c4Sjoerg /// GenerateCXXGlobalCleanUpFunc - Generates code for cleaning up global 44017330f729Sjoerg /// variables. 4402*e038c9c4Sjoerg void GenerateCXXGlobalCleanUpFunc( 44037330f729Sjoerg llvm::Function *Fn, 4404*e038c9c4Sjoerg ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH, 4405*e038c9c4Sjoerg llvm::Constant *>> 4406*e038c9c4Sjoerg DtorsOrStermFinalizers); 44077330f729Sjoerg 44087330f729Sjoerg void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, 44097330f729Sjoerg const VarDecl *D, 44107330f729Sjoerg llvm::GlobalVariable *Addr, 44117330f729Sjoerg bool PerformInit); 44127330f729Sjoerg 44137330f729Sjoerg void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest); 44147330f729Sjoerg 44157330f729Sjoerg void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp); 44167330f729Sjoerg 44177330f729Sjoerg void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint = true); 44187330f729Sjoerg 44197330f729Sjoerg RValue EmitAtomicExpr(AtomicExpr *E); 44207330f729Sjoerg 44217330f729Sjoerg //===--------------------------------------------------------------------===// 44227330f729Sjoerg // Annotations Emission 44237330f729Sjoerg //===--------------------------------------------------------------------===// 44247330f729Sjoerg 44257330f729Sjoerg /// Emit an annotation call (intrinsic). 44267330f729Sjoerg llvm::Value *EmitAnnotationCall(llvm::Function *AnnotationFn, 44277330f729Sjoerg llvm::Value *AnnotatedVal, 44287330f729Sjoerg StringRef AnnotationStr, 4429*e038c9c4Sjoerg SourceLocation Location, 4430*e038c9c4Sjoerg const AnnotateAttr *Attr); 44317330f729Sjoerg 44327330f729Sjoerg /// Emit local annotations for the local variable V, declared by D. 44337330f729Sjoerg void EmitVarAnnotations(const VarDecl *D, llvm::Value *V); 44347330f729Sjoerg 44357330f729Sjoerg /// Emit field annotations for the given field & value. Returns the 44367330f729Sjoerg /// annotation result. 44377330f729Sjoerg Address EmitFieldAnnotations(const FieldDecl *D, Address V); 44387330f729Sjoerg 44397330f729Sjoerg //===--------------------------------------------------------------------===// 44407330f729Sjoerg // Internal Helpers 44417330f729Sjoerg //===--------------------------------------------------------------------===// 44427330f729Sjoerg 44437330f729Sjoerg /// ContainsLabel - Return true if the statement contains a label in it. If 44447330f729Sjoerg /// this statement is not executed normally, it not containing a label means 44457330f729Sjoerg /// that we can just remove the code. 44467330f729Sjoerg static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false); 44477330f729Sjoerg 44487330f729Sjoerg /// containsBreak - Return true if the statement contains a break out of it. 44497330f729Sjoerg /// If the statement (recursively) contains a switch or loop with a break 44507330f729Sjoerg /// inside of it, this is fine. 44517330f729Sjoerg static bool containsBreak(const Stmt *S); 44527330f729Sjoerg 44537330f729Sjoerg /// Determine if the given statement might introduce a declaration into the 44547330f729Sjoerg /// current scope, by being a (possibly-labelled) DeclStmt. 44557330f729Sjoerg static bool mightAddDeclToScope(const Stmt *S); 44567330f729Sjoerg 44577330f729Sjoerg /// ConstantFoldsToSimpleInteger - If the specified expression does not fold 44587330f729Sjoerg /// to a constant, or if it does but contains a label, return false. If it 44597330f729Sjoerg /// constant folds return true and set the boolean result in Result. 44607330f729Sjoerg bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, 44617330f729Sjoerg bool AllowLabels = false); 44627330f729Sjoerg 44637330f729Sjoerg /// ConstantFoldsToSimpleInteger - If the specified expression does not fold 44647330f729Sjoerg /// to a constant, or if it does but contains a label, return false. If it 44657330f729Sjoerg /// constant folds return true and set the folded value. 44667330f729Sjoerg bool ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APSInt &Result, 44677330f729Sjoerg bool AllowLabels = false); 44687330f729Sjoerg 4469*e038c9c4Sjoerg /// isInstrumentedCondition - Determine whether the given condition is an 4470*e038c9c4Sjoerg /// instrumentable condition (i.e. no "&&" or "||"). 4471*e038c9c4Sjoerg static bool isInstrumentedCondition(const Expr *C); 4472*e038c9c4Sjoerg 4473*e038c9c4Sjoerg /// EmitBranchToCounterBlock - Emit a conditional branch to a new block that 4474*e038c9c4Sjoerg /// increments a profile counter based on the semantics of the given logical 4475*e038c9c4Sjoerg /// operator opcode. This is used to instrument branch condition coverage 4476*e038c9c4Sjoerg /// for logical operators. 4477*e038c9c4Sjoerg void EmitBranchToCounterBlock(const Expr *Cond, BinaryOperator::Opcode LOp, 4478*e038c9c4Sjoerg llvm::BasicBlock *TrueBlock, 4479*e038c9c4Sjoerg llvm::BasicBlock *FalseBlock, 4480*e038c9c4Sjoerg uint64_t TrueCount = 0, 4481*e038c9c4Sjoerg Stmt::Likelihood LH = Stmt::LH_None, 4482*e038c9c4Sjoerg const Expr *CntrIdx = nullptr); 4483*e038c9c4Sjoerg 44847330f729Sjoerg /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an 44857330f729Sjoerg /// if statement) to the specified blocks. Based on the condition, this might 44867330f729Sjoerg /// try to simplify the codegen of the conditional based on the branch. 44877330f729Sjoerg /// TrueCount should be the number of times we expect the condition to 44887330f729Sjoerg /// evaluate to true based on PGO data. 44897330f729Sjoerg void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, 4490*e038c9c4Sjoerg llvm::BasicBlock *FalseBlock, uint64_t TrueCount, 4491*e038c9c4Sjoerg Stmt::Likelihood LH = Stmt::LH_None); 44927330f729Sjoerg 44937330f729Sjoerg /// Given an assignment `*LHS = RHS`, emit a test that checks if \p RHS is 44947330f729Sjoerg /// nonnull, if \p LHS is marked _Nonnull. 44957330f729Sjoerg void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc); 44967330f729Sjoerg 44977330f729Sjoerg /// An enumeration which makes it easier to specify whether or not an 44987330f729Sjoerg /// operation is a subtraction. 44997330f729Sjoerg enum { NotSubtraction = false, IsSubtraction = true }; 45007330f729Sjoerg 45017330f729Sjoerg /// Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to 45027330f729Sjoerg /// detect undefined behavior when the pointer overflow sanitizer is enabled. 45037330f729Sjoerg /// \p SignedIndices indicates whether any of the GEP indices are signed. 45047330f729Sjoerg /// \p IsSubtraction indicates whether the expression used to form the GEP 45057330f729Sjoerg /// is a subtraction. 45067330f729Sjoerg llvm::Value *EmitCheckedInBoundsGEP(llvm::Value *Ptr, 45077330f729Sjoerg ArrayRef<llvm::Value *> IdxList, 45087330f729Sjoerg bool SignedIndices, 45097330f729Sjoerg bool IsSubtraction, 45107330f729Sjoerg SourceLocation Loc, 45117330f729Sjoerg const Twine &Name = ""); 45127330f729Sjoerg 45137330f729Sjoerg /// Specifies which type of sanitizer check to apply when handling a 45147330f729Sjoerg /// particular builtin. 45157330f729Sjoerg enum BuiltinCheckKind { 45167330f729Sjoerg BCK_CTZPassedZero, 45177330f729Sjoerg BCK_CLZPassedZero, 45187330f729Sjoerg }; 45197330f729Sjoerg 45207330f729Sjoerg /// Emits an argument for a call to a builtin. If the builtin sanitizer is 45217330f729Sjoerg /// enabled, a runtime check specified by \p Kind is also emitted. 45227330f729Sjoerg llvm::Value *EmitCheckedArgForBuiltin(const Expr *E, BuiltinCheckKind Kind); 45237330f729Sjoerg 45247330f729Sjoerg /// Emit a description of a type in a format suitable for passing to 45257330f729Sjoerg /// a runtime sanitizer handler. 45267330f729Sjoerg llvm::Constant *EmitCheckTypeDescriptor(QualType T); 45277330f729Sjoerg 45287330f729Sjoerg /// Convert a value into a format suitable for passing to a runtime 45297330f729Sjoerg /// sanitizer handler. 45307330f729Sjoerg llvm::Value *EmitCheckValue(llvm::Value *V); 45317330f729Sjoerg 45327330f729Sjoerg /// Emit a description of a source location in a format suitable for 45337330f729Sjoerg /// passing to a runtime sanitizer handler. 45347330f729Sjoerg llvm::Constant *EmitCheckSourceLocation(SourceLocation Loc); 45357330f729Sjoerg 45367330f729Sjoerg /// Create a basic block that will either trap or call a handler function in 45377330f729Sjoerg /// the UBSan runtime with the provided arguments, and create a conditional 45387330f729Sjoerg /// branch to it. 45397330f729Sjoerg void EmitCheck(ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked, 45407330f729Sjoerg SanitizerHandler Check, ArrayRef<llvm::Constant *> StaticArgs, 45417330f729Sjoerg ArrayRef<llvm::Value *> DynamicArgs); 45427330f729Sjoerg 45437330f729Sjoerg /// Emit a slow path cross-DSO CFI check which calls __cfi_slowpath 45447330f729Sjoerg /// if Cond if false. 45457330f729Sjoerg void EmitCfiSlowPathCheck(SanitizerMask Kind, llvm::Value *Cond, 45467330f729Sjoerg llvm::ConstantInt *TypeId, llvm::Value *Ptr, 45477330f729Sjoerg ArrayRef<llvm::Constant *> StaticArgs); 45487330f729Sjoerg 45497330f729Sjoerg /// Emit a reached-unreachable diagnostic if \p Loc is valid and runtime 45507330f729Sjoerg /// checking is enabled. Otherwise, just emit an unreachable instruction. 45517330f729Sjoerg void EmitUnreachable(SourceLocation Loc); 45527330f729Sjoerg 45537330f729Sjoerg /// Create a basic block that will call the trap intrinsic, and emit a 45547330f729Sjoerg /// conditional branch to it, for the -ftrapv checks. 4555*e038c9c4Sjoerg void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID); 45567330f729Sjoerg 45577330f729Sjoerg /// Emit a call to trap or debugtrap and attach function attribute 45587330f729Sjoerg /// "trap-func-name" if specified. 45597330f729Sjoerg llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID); 45607330f729Sjoerg 45617330f729Sjoerg /// Emit a stub for the cross-DSO CFI check function. 45627330f729Sjoerg void EmitCfiCheckStub(); 45637330f729Sjoerg 45647330f729Sjoerg /// Emit a cross-DSO CFI failure handling function. 45657330f729Sjoerg void EmitCfiCheckFail(); 45667330f729Sjoerg 45677330f729Sjoerg /// Create a check for a function parameter that may potentially be 45687330f729Sjoerg /// declared as non-null. 45697330f729Sjoerg void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc, 45707330f729Sjoerg AbstractCallee AC, unsigned ParmNum); 45717330f729Sjoerg 45727330f729Sjoerg /// EmitCallArg - Emit a single call argument. 45737330f729Sjoerg void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType); 45747330f729Sjoerg 45757330f729Sjoerg /// EmitDelegateCallArg - We are performing a delegate call; that 45767330f729Sjoerg /// is, the current function is delegating to another one. Produce 45777330f729Sjoerg /// a r-value suitable for passing the given parameter. 45787330f729Sjoerg void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, 45797330f729Sjoerg SourceLocation loc); 45807330f729Sjoerg 45817330f729Sjoerg /// SetFPAccuracy - Set the minimum required accuracy of the given floating 45827330f729Sjoerg /// point operation, expressed as the maximum relative error in ulp. 45837330f729Sjoerg void SetFPAccuracy(llvm::Value *Val, float Accuracy); 45847330f729Sjoerg 4585*e038c9c4Sjoerg /// SetFPModel - Control floating point behavior via fp-model settings. 4586*e038c9c4Sjoerg void SetFPModel(); 4587*e038c9c4Sjoerg 4588*e038c9c4Sjoerg /// Set the codegen fast-math flags. 4589*e038c9c4Sjoerg void SetFastMathFlags(FPOptions FPFeatures); 4590*e038c9c4Sjoerg 45917330f729Sjoerg private: 45927330f729Sjoerg llvm::MDNode *getRangeForLoadFromType(QualType Ty); 45937330f729Sjoerg void EmitReturnOfRValue(RValue RV, QualType Ty); 45947330f729Sjoerg 45957330f729Sjoerg void deferPlaceholderReplacement(llvm::Instruction *Old, llvm::Value *New); 45967330f729Sjoerg 4597*e038c9c4Sjoerg llvm::SmallVector<std::pair<llvm::WeakTrackingVH, llvm::Value *>, 4> 45987330f729Sjoerg DeferredReplacements; 45997330f729Sjoerg 46007330f729Sjoerg /// Set the address of a local variable. 46017330f729Sjoerg void setAddrOfLocalVar(const VarDecl *VD, Address Addr) { 46027330f729Sjoerg assert(!LocalDeclMap.count(VD) && "Decl already exists in LocalDeclMap!"); 46037330f729Sjoerg LocalDeclMap.insert({VD, Addr}); 46047330f729Sjoerg } 46057330f729Sjoerg 46067330f729Sjoerg /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty 46077330f729Sjoerg /// from function arguments into \arg Dst. See ABIArgInfo::Expand. 46087330f729Sjoerg /// 46097330f729Sjoerg /// \param AI - The first function argument of the expansion. 46107330f729Sjoerg void ExpandTypeFromArgs(QualType Ty, LValue Dst, 4611*e038c9c4Sjoerg llvm::Function::arg_iterator &AI); 46127330f729Sjoerg 46137330f729Sjoerg /// ExpandTypeToArgs - Expand an CallArg \arg Arg, with the LLVM type for \arg 46147330f729Sjoerg /// Ty, into individual arguments on the provided vector \arg IRCallArgs, 46157330f729Sjoerg /// starting at index \arg IRCallArgPos. See ABIArgInfo::Expand. 46167330f729Sjoerg void ExpandTypeToArgs(QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy, 46177330f729Sjoerg SmallVectorImpl<llvm::Value *> &IRCallArgs, 46187330f729Sjoerg unsigned &IRCallArgPos); 46197330f729Sjoerg 46207330f729Sjoerg llvm::Value* EmitAsmInput(const TargetInfo::ConstraintInfo &Info, 46217330f729Sjoerg const Expr *InputExpr, std::string &ConstraintStr); 46227330f729Sjoerg 46237330f729Sjoerg llvm::Value* EmitAsmInputLValue(const TargetInfo::ConstraintInfo &Info, 46247330f729Sjoerg LValue InputValue, QualType InputType, 46257330f729Sjoerg std::string &ConstraintStr, 46267330f729Sjoerg SourceLocation Loc); 46277330f729Sjoerg 46287330f729Sjoerg /// Attempts to statically evaluate the object size of E. If that 46297330f729Sjoerg /// fails, emits code to figure the size of E out for us. This is 46307330f729Sjoerg /// pass_object_size aware. 46317330f729Sjoerg /// 46327330f729Sjoerg /// If EmittedExpr is non-null, this will use that instead of re-emitting E. 46337330f729Sjoerg llvm::Value *evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type, 46347330f729Sjoerg llvm::IntegerType *ResType, 46357330f729Sjoerg llvm::Value *EmittedE, 46367330f729Sjoerg bool IsDynamic); 46377330f729Sjoerg 46387330f729Sjoerg /// Emits the size of E, as required by __builtin_object_size. This 46397330f729Sjoerg /// function is aware of pass_object_size parameters, and will act accordingly 46407330f729Sjoerg /// if E is a parameter with the pass_object_size attribute. 46417330f729Sjoerg llvm::Value *emitBuiltinObjectSize(const Expr *E, unsigned Type, 46427330f729Sjoerg llvm::IntegerType *ResType, 46437330f729Sjoerg llvm::Value *EmittedE, 46447330f729Sjoerg bool IsDynamic); 46457330f729Sjoerg 46467330f729Sjoerg void emitZeroOrPatternForAutoVarInit(QualType type, const VarDecl &D, 46477330f729Sjoerg Address Loc); 46487330f729Sjoerg 46497330f729Sjoerg public: 46507330f729Sjoerg enum class EvaluationOrder { 46517330f729Sjoerg ///! No language constraints on evaluation order. 46527330f729Sjoerg Default, 46537330f729Sjoerg ///! Language semantics require left-to-right evaluation. 46547330f729Sjoerg ForceLeftToRight, 46557330f729Sjoerg ///! Language semantics require right-to-left evaluation. 46567330f729Sjoerg ForceRightToLeft 46577330f729Sjoerg }; 46587330f729Sjoerg 4659*e038c9c4Sjoerg // Wrapper for function prototype sources. Wraps either a FunctionProtoType or 4660*e038c9c4Sjoerg // an ObjCMethodDecl. 4661*e038c9c4Sjoerg struct PrototypeWrapper { 4662*e038c9c4Sjoerg llvm::PointerUnion<const FunctionProtoType *, const ObjCMethodDecl *> P; 46637330f729Sjoerg 4664*e038c9c4Sjoerg PrototypeWrapper(const FunctionProtoType *FT) : P(FT) {} 4665*e038c9c4Sjoerg PrototypeWrapper(const ObjCMethodDecl *MD) : P(MD) {} 4666*e038c9c4Sjoerg }; 46677330f729Sjoerg 4668*e038c9c4Sjoerg void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, 46697330f729Sjoerg llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange, 46707330f729Sjoerg AbstractCallee AC = AbstractCallee(), 46717330f729Sjoerg unsigned ParamsToSkip = 0, 46727330f729Sjoerg EvaluationOrder Order = EvaluationOrder::Default); 46737330f729Sjoerg 46747330f729Sjoerg /// EmitPointerWithAlignment - Given an expression with a pointer type, 46757330f729Sjoerg /// emit the value and compute our best estimate of the alignment of the 46767330f729Sjoerg /// pointee. 46777330f729Sjoerg /// 46787330f729Sjoerg /// \param BaseInfo - If non-null, this will be initialized with 46797330f729Sjoerg /// information about the source of the alignment and the may-alias 46807330f729Sjoerg /// attribute. Note that this function will conservatively fall back on 46817330f729Sjoerg /// the type when it doesn't recognize the expression and may-alias will 46827330f729Sjoerg /// be set to false. 46837330f729Sjoerg /// 46847330f729Sjoerg /// One reasonable way to use this information is when there's a language 46857330f729Sjoerg /// guarantee that the pointer must be aligned to some stricter value, and 46867330f729Sjoerg /// we're simply trying to ensure that sufficiently obvious uses of under- 46877330f729Sjoerg /// aligned objects don't get miscompiled; for example, a placement new 46887330f729Sjoerg /// into the address of a local variable. In such a case, it's quite 46897330f729Sjoerg /// reasonable to just ignore the returned alignment when it isn't from an 46907330f729Sjoerg /// explicit source. 46917330f729Sjoerg Address EmitPointerWithAlignment(const Expr *Addr, 46927330f729Sjoerg LValueBaseInfo *BaseInfo = nullptr, 46937330f729Sjoerg TBAAAccessInfo *TBAAInfo = nullptr); 46947330f729Sjoerg 46957330f729Sjoerg /// If \p E references a parameter with pass_object_size info or a constant 46967330f729Sjoerg /// array size modifier, emit the object size divided by the size of \p EltTy. 46977330f729Sjoerg /// Otherwise return null. 46987330f729Sjoerg llvm::Value *LoadPassedObjectSize(const Expr *E, QualType EltTy); 46997330f729Sjoerg 47007330f729Sjoerg void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK); 47017330f729Sjoerg 47027330f729Sjoerg struct MultiVersionResolverOption { 47037330f729Sjoerg llvm::Function *Function; 47047330f729Sjoerg struct Conds { 47057330f729Sjoerg StringRef Architecture; 47067330f729Sjoerg llvm::SmallVector<StringRef, 8> Features; 47077330f729Sjoerg 47087330f729Sjoerg Conds(StringRef Arch, ArrayRef<StringRef> Feats) 47097330f729Sjoerg : Architecture(Arch), Features(Feats.begin(), Feats.end()) {} 47107330f729Sjoerg } Conditions; 47117330f729Sjoerg 47127330f729Sjoerg MultiVersionResolverOption(llvm::Function *F, StringRef Arch, 47137330f729Sjoerg ArrayRef<StringRef> Feats) 47147330f729Sjoerg : Function(F), Conditions(Arch, Feats) {} 47157330f729Sjoerg }; 47167330f729Sjoerg 47177330f729Sjoerg // Emits the body of a multiversion function's resolver. Assumes that the 47187330f729Sjoerg // options are already sorted in the proper order, with the 'default' option 47197330f729Sjoerg // last (if it exists). 47207330f729Sjoerg void EmitMultiVersionResolver(llvm::Function *Resolver, 47217330f729Sjoerg ArrayRef<MultiVersionResolverOption> Options); 47227330f729Sjoerg 47237330f729Sjoerg static uint64_t GetX86CpuSupportsMask(ArrayRef<StringRef> FeatureStrs); 47247330f729Sjoerg 47257330f729Sjoerg private: 47267330f729Sjoerg QualType getVarArgType(const Expr *Arg); 47277330f729Sjoerg 47287330f729Sjoerg void EmitDeclMetadata(); 47297330f729Sjoerg 47307330f729Sjoerg BlockByrefHelpers *buildByrefHelpers(llvm::StructType &byrefType, 47317330f729Sjoerg const AutoVarEmission &emission); 47327330f729Sjoerg 47337330f729Sjoerg void AddObjCARCExceptionMetadata(llvm::Instruction *Inst); 47347330f729Sjoerg 47357330f729Sjoerg llvm::Value *GetValueForARMHint(unsigned BuiltinID); 47367330f729Sjoerg llvm::Value *EmitX86CpuIs(const CallExpr *E); 47377330f729Sjoerg llvm::Value *EmitX86CpuIs(StringRef CPUStr); 47387330f729Sjoerg llvm::Value *EmitX86CpuSupports(const CallExpr *E); 47397330f729Sjoerg llvm::Value *EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs); 47407330f729Sjoerg llvm::Value *EmitX86CpuSupports(uint64_t Mask); 47417330f729Sjoerg llvm::Value *EmitX86CpuInit(); 47427330f729Sjoerg llvm::Value *FormResolverCondition(const MultiVersionResolverOption &RO); 47437330f729Sjoerg }; 47447330f729Sjoerg 4745*e038c9c4Sjoerg /// TargetFeatures - This class is used to check whether the builtin function 4746*e038c9c4Sjoerg /// has the required tagert specific features. It is able to support the 4747*e038c9c4Sjoerg /// combination of ','(and), '|'(or), and '()'. By default, the priority of 4748*e038c9c4Sjoerg /// ',' is higher than that of '|' . 4749*e038c9c4Sjoerg /// E.g: 4750*e038c9c4Sjoerg /// A,B|C means the builtin function requires both A and B, or C. 4751*e038c9c4Sjoerg /// If we want the builtin function requires both A and B, or both A and C, 4752*e038c9c4Sjoerg /// there are two ways: A,B|A,C or A,(B|C). 4753*e038c9c4Sjoerg /// The FeaturesList should not contain spaces, and brackets must appear in 4754*e038c9c4Sjoerg /// pairs. 4755*e038c9c4Sjoerg class TargetFeatures { 4756*e038c9c4Sjoerg struct FeatureListStatus { 4757*e038c9c4Sjoerg bool HasFeatures; 4758*e038c9c4Sjoerg StringRef CurFeaturesList; 4759*e038c9c4Sjoerg }; 4760*e038c9c4Sjoerg 4761*e038c9c4Sjoerg const llvm::StringMap<bool> &CallerFeatureMap; 4762*e038c9c4Sjoerg 4763*e038c9c4Sjoerg FeatureListStatus getAndFeatures(StringRef FeatureList) { 4764*e038c9c4Sjoerg int InParentheses = 0; 4765*e038c9c4Sjoerg bool HasFeatures = true; 4766*e038c9c4Sjoerg size_t SubexpressionStart = 0; 4767*e038c9c4Sjoerg for (size_t i = 0, e = FeatureList.size(); i < e; ++i) { 4768*e038c9c4Sjoerg char CurrentToken = FeatureList[i]; 4769*e038c9c4Sjoerg switch (CurrentToken) { 4770*e038c9c4Sjoerg default: 4771*e038c9c4Sjoerg break; 4772*e038c9c4Sjoerg case '(': 4773*e038c9c4Sjoerg if (InParentheses == 0) 4774*e038c9c4Sjoerg SubexpressionStart = i + 1; 4775*e038c9c4Sjoerg ++InParentheses; 4776*e038c9c4Sjoerg break; 4777*e038c9c4Sjoerg case ')': 4778*e038c9c4Sjoerg --InParentheses; 4779*e038c9c4Sjoerg assert(InParentheses >= 0 && "Parentheses are not in pair"); 4780*e038c9c4Sjoerg LLVM_FALLTHROUGH; 4781*e038c9c4Sjoerg case '|': 4782*e038c9c4Sjoerg case ',': 4783*e038c9c4Sjoerg if (InParentheses == 0) { 4784*e038c9c4Sjoerg if (HasFeatures && i != SubexpressionStart) { 4785*e038c9c4Sjoerg StringRef F = FeatureList.slice(SubexpressionStart, i); 4786*e038c9c4Sjoerg HasFeatures = CurrentToken == ')' ? hasRequiredFeatures(F) 4787*e038c9c4Sjoerg : CallerFeatureMap.lookup(F); 4788*e038c9c4Sjoerg } 4789*e038c9c4Sjoerg SubexpressionStart = i + 1; 4790*e038c9c4Sjoerg if (CurrentToken == '|') { 4791*e038c9c4Sjoerg return {HasFeatures, FeatureList.substr(SubexpressionStart)}; 4792*e038c9c4Sjoerg } 4793*e038c9c4Sjoerg } 4794*e038c9c4Sjoerg break; 4795*e038c9c4Sjoerg } 4796*e038c9c4Sjoerg } 4797*e038c9c4Sjoerg assert(InParentheses == 0 && "Parentheses are not in pair"); 4798*e038c9c4Sjoerg if (HasFeatures && SubexpressionStart != FeatureList.size()) 4799*e038c9c4Sjoerg HasFeatures = 4800*e038c9c4Sjoerg CallerFeatureMap.lookup(FeatureList.substr(SubexpressionStart)); 4801*e038c9c4Sjoerg return {HasFeatures, StringRef()}; 4802*e038c9c4Sjoerg } 4803*e038c9c4Sjoerg 4804*e038c9c4Sjoerg public: 4805*e038c9c4Sjoerg bool hasRequiredFeatures(StringRef FeatureList) { 4806*e038c9c4Sjoerg FeatureListStatus FS = {false, FeatureList}; 4807*e038c9c4Sjoerg while (!FS.HasFeatures && !FS.CurFeaturesList.empty()) 4808*e038c9c4Sjoerg FS = getAndFeatures(FS.CurFeaturesList); 4809*e038c9c4Sjoerg return FS.HasFeatures; 4810*e038c9c4Sjoerg } 4811*e038c9c4Sjoerg 4812*e038c9c4Sjoerg TargetFeatures(const llvm::StringMap<bool> &CallerFeatureMap) 4813*e038c9c4Sjoerg : CallerFeatureMap(CallerFeatureMap) {} 4814*e038c9c4Sjoerg }; 4815*e038c9c4Sjoerg 48167330f729Sjoerg inline DominatingLLVMValue::saved_type 48177330f729Sjoerg DominatingLLVMValue::save(CodeGenFunction &CGF, llvm::Value *value) { 48187330f729Sjoerg if (!needsSaving(value)) return saved_type(value, false); 48197330f729Sjoerg 48207330f729Sjoerg // Otherwise, we need an alloca. 48217330f729Sjoerg auto align = CharUnits::fromQuantity( 48227330f729Sjoerg CGF.CGM.getDataLayout().getPrefTypeAlignment(value->getType())); 48237330f729Sjoerg Address alloca = 48247330f729Sjoerg CGF.CreateTempAlloca(value->getType(), align, "cond-cleanup.save"); 48257330f729Sjoerg CGF.Builder.CreateStore(value, alloca); 48267330f729Sjoerg 48277330f729Sjoerg return saved_type(alloca.getPointer(), true); 48287330f729Sjoerg } 48297330f729Sjoerg 48307330f729Sjoerg inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF, 48317330f729Sjoerg saved_type value) { 48327330f729Sjoerg // If the value says it wasn't saved, trust that it's still dominating. 48337330f729Sjoerg if (!value.getInt()) return value.getPointer(); 48347330f729Sjoerg 48357330f729Sjoerg // Otherwise, it should be an alloca instruction, as set up in save(). 48367330f729Sjoerg auto alloca = cast<llvm::AllocaInst>(value.getPointer()); 4837*e038c9c4Sjoerg return CGF.Builder.CreateAlignedLoad(alloca->getAllocatedType(), alloca, 4838*e038c9c4Sjoerg alloca->getAlign()); 48397330f729Sjoerg } 48407330f729Sjoerg 48417330f729Sjoerg } // end namespace CodeGen 4842*e038c9c4Sjoerg 4843*e038c9c4Sjoerg // Map the LangOption for floating point exception behavior into 4844*e038c9c4Sjoerg // the corresponding enum in the IR. 4845*e038c9c4Sjoerg llvm::fp::ExceptionBehavior 4846*e038c9c4Sjoerg ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind); 48477330f729Sjoerg } // end namespace clang 48487330f729Sjoerg 48497330f729Sjoerg #endif 4850