diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h | 346 |
1 files changed, 318 insertions, 28 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h index 4803b13..fb19a26 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenFunction.h @@ -36,6 +36,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Support/Debug.h" +#include "llvm/Transforms/Utils/SanitizerStats.h" namespace llvm { class BasicBlock; @@ -67,7 +68,6 @@ class ObjCMethodDecl; class ObjCImplementationDecl; class ObjCPropertyImplDecl; class TargetInfo; -class TargetCodeGenInfo; class VarDecl; class ObjCForCollectionStmt; class ObjCAtTryStmt; @@ -85,6 +85,9 @@ class BlockByrefHelpers; class BlockByrefInfo; class BlockFlags; class BlockFieldFlags; +class RegionCodeGenTy; +class TargetCodeGenInfo; +struct OMPTaskDataTy; /// The kind of evaluation to perform on values of a particular /// type. Basically, is the code in CGExprScalar, CGExprComplex, or @@ -188,6 +191,8 @@ public: CXXThisFieldDecl = *Field; else if (I->capturesVariable()) CaptureFields[I->getCapturedVar()] = *Field; + else if (I->capturesVariableByCopy()) + CaptureFields[I->getCapturedVar()] = *Field; } } @@ -275,6 +280,8 @@ public: /// potentially set the return value. bool SawAsmBlock; + const FunctionDecl *CurSEHParent = nullptr; + /// True if the current function is an outlined SEH helper. This can be a /// finally block or filter expression. bool IsOutlinedSEHHelper; @@ -295,6 +302,19 @@ public: llvm::Instruction *CurrentFuncletPad = nullptr; + class CallLifetimeEnd final : public EHScopeStack::Cleanup { + llvm::Value *Addr; + llvm::Value *Size; + + public: + CallLifetimeEnd(Address addr, llvm::Value *size) + : Addr(addr.getPointer()), Size(size) {} + + void Emit(CodeGenFunction &CGF, Flags flags) override { + CGF.EmitLifetimeEnd(Size, Addr); + } + }; + /// Header for data within LifetimeExtendedCleanupStack. struct LifetimeExtendedCleanupHeader { /// The size of the following cleanup object. @@ -637,6 +657,11 @@ public: ForceCleanup(); } + /// Checks if the global variable is captured in current function. + bool isGlobalVarCaptured(const VarDecl *VD) const { + return !VD->isLocalVarDeclOrParm() && CGF.LocalDeclMap.count(VD) > 0; + } + private: /// Copy all the entries in the source map over the corresponding /// entries in the destination, which must exist. @@ -940,6 +965,94 @@ private: }; SmallVector<BreakContinue, 8> BreakContinueStack; + /// Handles cancellation exit points in OpenMP-related constructs. + class OpenMPCancelExitStack { + /// Tracks cancellation exit point and join point for cancel-related exit + /// and normal exit. + struct CancelExit { + CancelExit() = default; + CancelExit(OpenMPDirectiveKind Kind, JumpDest ExitBlock, + JumpDest ContBlock) + : Kind(Kind), ExitBlock(ExitBlock), ContBlock(ContBlock) {} + OpenMPDirectiveKind Kind = OMPD_unknown; + /// true if the exit block has been emitted already by the special + /// emitExit() call, false if the default codegen is used. + bool HasBeenEmitted = false; + JumpDest ExitBlock; + JumpDest ContBlock; + }; + + SmallVector<CancelExit, 8> Stack; + + public: + OpenMPCancelExitStack() : Stack(1) {} + ~OpenMPCancelExitStack() = default; + /// Fetches the exit block for the current OpenMP construct. + JumpDest getExitBlock() const { return Stack.back().ExitBlock; } + /// Emits exit block with special codegen procedure specific for the related + /// OpenMP construct + emits code for normal construct cleanup. + void emitExit(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, + const llvm::function_ref<void(CodeGenFunction &)> &CodeGen) { + if (Stack.back().Kind == Kind && getExitBlock().isValid()) { + assert(CGF.getOMPCancelDestination(Kind).isValid()); + assert(CGF.HaveInsertPoint()); + assert(!Stack.back().HasBeenEmitted); + auto IP = CGF.Builder.saveAndClearIP(); + CGF.EmitBlock(Stack.back().ExitBlock.getBlock()); + CodeGen(CGF); + CGF.EmitBranchThroughCleanup(Stack.back().ContBlock); + CGF.Builder.restoreIP(IP); + Stack.back().HasBeenEmitted = true; + } + CodeGen(CGF); + } + /// Enter the cancel supporting \a Kind construct. + /// \param Kind OpenMP directive that supports cancel constructs. + /// \param HasCancel true, if the construct has inner cancel directive, + /// false otherwise. + void enter(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, bool HasCancel) { + Stack.push_back({Kind, + HasCancel ? CGF.getJumpDestInCurrentScope("cancel.exit") + : JumpDest(), + HasCancel ? CGF.getJumpDestInCurrentScope("cancel.cont") + : JumpDest()}); + } + /// Emits default exit point for the cancel construct (if the special one + /// has not be used) + join point for cancel/normal exits. + void exit(CodeGenFunction &CGF) { + if (getExitBlock().isValid()) { + assert(CGF.getOMPCancelDestination(Stack.back().Kind).isValid()); + bool HaveIP = CGF.HaveInsertPoint(); + if (!Stack.back().HasBeenEmitted) { + if (HaveIP) + CGF.EmitBranchThroughCleanup(Stack.back().ContBlock); + CGF.EmitBlock(Stack.back().ExitBlock.getBlock()); + CGF.EmitBranchThroughCleanup(Stack.back().ContBlock); + } + CGF.EmitBlock(Stack.back().ContBlock.getBlock()); + if (!HaveIP) { + CGF.Builder.CreateUnreachable(); + CGF.Builder.ClearInsertionPoint(); + } + } + Stack.pop_back(); + } + }; + OpenMPCancelExitStack OMPCancelStack; + + /// Controls insertion of cancellation exit blocks in worksharing constructs. + class OMPCancelStackRAII { + CodeGenFunction &CGF; + + public: + OMPCancelStackRAII(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, + bool HasCancel) + : CGF(CGF) { + CGF.OMPCancelStack.enter(CGF, Kind, HasCancel); + } + ~OMPCancelStackRAII() { CGF.OMPCancelStack.exit(CGF); } + }; + CodeGenPGO PGO; /// Calculate branch weights appropriate for PGO data @@ -951,7 +1064,7 @@ private: public: /// Increment the profiler's counter for the given statement. void incrementProfileCounter(const Stmt *S) { - if (CGM.getCodeGenOpts().ProfileInstrGenerate) + if (CGM.getCodeGenOpts().hasProfileClangInstr()) PGO.emitCounterIncrement(Builder, S); PGO.setCurrentStmt(S); } @@ -1053,6 +1166,61 @@ public: CharUnits OldCXXThisAlignment; }; + class InlinedInheritingConstructorScope { + public: + InlinedInheritingConstructorScope(CodeGenFunction &CGF, GlobalDecl GD) + : CGF(CGF), OldCurGD(CGF.CurGD), OldCurFuncDecl(CGF.CurFuncDecl), + OldCurCodeDecl(CGF.CurCodeDecl), + OldCXXABIThisDecl(CGF.CXXABIThisDecl), + OldCXXABIThisValue(CGF.CXXABIThisValue), + OldCXXThisValue(CGF.CXXThisValue), + OldCXXABIThisAlignment(CGF.CXXABIThisAlignment), + OldCXXThisAlignment(CGF.CXXThisAlignment), + OldReturnValue(CGF.ReturnValue), OldFnRetTy(CGF.FnRetTy), + OldCXXInheritedCtorInitExprArgs( + std::move(CGF.CXXInheritedCtorInitExprArgs)) { + CGF.CurGD = GD; + CGF.CurFuncDecl = CGF.CurCodeDecl = + cast<CXXConstructorDecl>(GD.getDecl()); + CGF.CXXABIThisDecl = nullptr; + CGF.CXXABIThisValue = nullptr; + CGF.CXXThisValue = nullptr; + CGF.CXXABIThisAlignment = CharUnits(); + CGF.CXXThisAlignment = CharUnits(); + CGF.ReturnValue = Address::invalid(); + CGF.FnRetTy = QualType(); + CGF.CXXInheritedCtorInitExprArgs.clear(); + } + ~InlinedInheritingConstructorScope() { + CGF.CurGD = OldCurGD; + CGF.CurFuncDecl = OldCurFuncDecl; + CGF.CurCodeDecl = OldCurCodeDecl; + CGF.CXXABIThisDecl = OldCXXABIThisDecl; + CGF.CXXABIThisValue = OldCXXABIThisValue; + CGF.CXXThisValue = OldCXXThisValue; + CGF.CXXABIThisAlignment = OldCXXABIThisAlignment; + CGF.CXXThisAlignment = OldCXXThisAlignment; + CGF.ReturnValue = OldReturnValue; + CGF.FnRetTy = OldFnRetTy; + CGF.CXXInheritedCtorInitExprArgs = + std::move(OldCXXInheritedCtorInitExprArgs); + } + + private: + CodeGenFunction &CGF; + GlobalDecl OldCurGD; + const Decl *OldCurFuncDecl; + const Decl *OldCurCodeDecl; + ImplicitParamDecl *OldCXXABIThisDecl; + llvm::Value *OldCXXABIThisValue; + llvm::Value *OldCXXThisValue; + CharUnits OldCXXABIThisAlignment; + CharUnits OldCXXThisAlignment; + Address OldReturnValue; + QualType OldFnRetTy; + CallArgList OldCXXInheritedCtorInitExprArgs; + }; + private: /// CXXThisDecl - When generating code for a C++ member function, /// this will hold the implicit 'this' declaration. @@ -1066,6 +1234,10 @@ private: /// this expression. Address CXXDefaultInitExprThis = Address::invalid(); + /// The values of function arguments to use when evaluating + /// CXXInheritedCtorInitExprs within this context. + CallArgList CXXInheritedCtorInitExprArgs; + /// CXXStructorImplicitParamDecl - When generating code for a constructor or /// destructor, this will hold the implicit argument (e.g. VTT). ImplicitParamDecl *CXXStructorImplicitParamDecl; @@ -1149,10 +1321,7 @@ public: return getInvokeDestImpl(); } - bool currentFunctionUsesSEHTry() const { - const auto *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl); - return FD && FD->usesSEHTry(); - } + bool currentFunctionUsesSEHTry() const { return CurSEHParent != nullptr; } const TargetInfo &getTarget() const { return Target; } llvm::LLVMContext &getLLVMContext() { return CGM.getLLVMContext(); } @@ -1292,6 +1461,8 @@ public: const BlockByrefInfo &getBlockByrefInfo(const VarDecl *var); + QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args); + void GenerateCode(GlobalDecl GD, llvm::Function *Fn, const CGFunctionInfo &FnInfo); /// \brief Emit code for the start of a function. @@ -1388,6 +1559,7 @@ public: CFITCK_NVCall, CFITCK_DerivedCast, CFITCK_UnrelatedCast, + CFITCK_ICall, }; /// \brief Derived is the presumed address of an object of type T after a @@ -1399,14 +1571,29 @@ public: /// EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable. /// If vptr CFI is enabled, emit a check that VTable is valid. - void EmitVTablePtrCheckForCall(const CXXMethodDecl *MD, llvm::Value *VTable, + void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc); /// EmitVTablePtrCheck - Emit a check that VTable is a valid virtual table for - /// RD using llvm.bitset.test. + /// RD using llvm.type.test. void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc); + /// If whole-program virtual table optimization is enabled, emit an assumption + /// that VTable is a member of RD's type identifier. Or, if vptr CFI is + /// enabled, emit a check that VTable is a member of RD's type identifier. + void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, + llvm::Value *VTable, SourceLocation Loc); + + /// Returns whether we should perform a type checked load when loading a + /// virtual function for virtual calls to members of RD. This is generally + /// true when both vcall CFI and whole-program-vtables are enabled. + bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD); + + /// Emit a type checked load from the given vtable. + llvm::Value *EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, + uint64_t VTableByteOffset); + /// CanDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given /// expr can be devirtualized. bool CanDevirtualizeMemberFunctionCall(const Expr *Base, @@ -1422,6 +1609,10 @@ public: /// instrumented with __cyg_profile_func_* calls bool ShouldInstrumentFunction(); + /// ShouldXRayInstrument - Return true if the current function should be + /// instrumented with XRay nop sleds. + bool ShouldXRayInstrumentFunction() const; + /// EmitFunctionInstrumentation - Emit LLVM code to call the specified /// instrumentation function with the current function and the call site, if /// function instrumentation is enabled. @@ -1572,6 +1763,10 @@ public: AlignmentSource *Source = nullptr); LValue EmitLoadOfReferenceLValue(Address Ref, const ReferenceType *RefTy); + Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, + AlignmentSource *Source = nullptr); + LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy); + /// CreateTempAlloca - This creates a alloca and inserts it into the entry /// block. The caller is responsible for setting an appropriate alignment on /// the alloca. @@ -1845,10 +2040,32 @@ public: void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, const FunctionArgList &Args); + /// Emit a call to an inheriting constructor (that is, one that invokes a + /// constructor inherited from a base class) by inlining its definition. This + /// is necessary if the ABI does not support forwarding the arguments to the + /// base class constructor (because they're variadic or similar). + void EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor, + CXXCtorType CtorType, + bool ForVirtualBase, + bool Delegating, + CallArgList &Args); + + /// Emit a call to a constructor inherited from a base class, passing the + /// current constructor's arguments along unmodified (without even making + /// a copy). + void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D, + bool ForVirtualBase, Address This, + bool InheritedFromVBase, + const CXXInheritedCtorInitExpr *E); + void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, Address This, const CXXConstructExpr *E); + void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, + bool ForVirtualBase, bool Delegating, + Address This, CallArgList &Args); + /// Emit assumption load for all bases. Requires to be be called only on /// most-derived class and not under construction of the object. void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This); @@ -1861,7 +2078,7 @@ public: const CXXConstructExpr *E); void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, - const ConstantArrayType *ArrayTy, + const ArrayType *ArrayTy, Address ArrayPtr, const CXXConstructExpr *E, bool ZeroInitialization = false); @@ -2204,6 +2421,8 @@ public: void EmitCXXForRangeStmt(const CXXForRangeStmt &S, ArrayRef<const Attr *> Attrs = None); + /// Returns calculated size of the specified type. + llvm::Value *getTypeSize(QualType Ty); LValue InitCapturedStruct(const CapturedStmt &S); llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K); llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S); @@ -2294,7 +2513,17 @@ public: /// it is the last iteration of the loop code in associated directive, or to /// 'i1 false' otherwise. If this item is nullptr, no final check is required. void EmitOMPLastprivateClauseFinal(const OMPExecutableDirective &D, + bool NoFinals, llvm::Value *IsLastIterCond = nullptr); + /// Emit initial code for linear clauses. + void EmitOMPLinearClause(const OMPLoopDirective &D, + CodeGenFunction::OMPPrivateScope &PrivateScope); + /// Emit final code for linear clauses. + /// \param CondGen Optional conditional code for final part of codegen for + /// linear clause. + void EmitOMPLinearClauseFinal( + const OMPLoopDirective &D, + const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen); /// \brief Emit initial code for reduction variables. Creates reduction copies /// and initializes them with the values according to OpenMP standard. /// @@ -2315,6 +2544,14 @@ public: /// \param D Directive (possibly) with the 'linear' clause. void EmitOMPLinearClauseInit(const OMPLoopDirective &D); + typedef const llvm::function_ref<void(CodeGenFunction & /*CGF*/, + llvm::Value * /*OutlinedFn*/, + const OMPTaskDataTy & /*Data*/)> + TaskGenTy; + void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S, + const RegionCodeGenTy &BodyGen, + const TaskGenTy &TaskGen, OMPTaskDataTy &Data); + void EmitOMPParallelDirective(const OMPParallelDirective &S); void EmitOMPSimdDirective(const OMPSimdDirective &S); void EmitOMPForDirective(const OMPForDirective &S); @@ -2337,14 +2574,36 @@ public: void EmitOMPAtomicDirective(const OMPAtomicDirective &S); void EmitOMPTargetDirective(const OMPTargetDirective &S); void EmitOMPTargetDataDirective(const OMPTargetDataDirective &S); + void EmitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective &S); + void EmitOMPTargetExitDataDirective(const OMPTargetExitDataDirective &S); + void EmitOMPTargetUpdateDirective(const OMPTargetUpdateDirective &S); + void EmitOMPTargetParallelDirective(const OMPTargetParallelDirective &S); + void + EmitOMPTargetParallelForDirective(const OMPTargetParallelForDirective &S); void EmitOMPTeamsDirective(const OMPTeamsDirective &S); void EmitOMPCancellationPointDirective(const OMPCancellationPointDirective &S); void EmitOMPCancelDirective(const OMPCancelDirective &S); + void EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S); void EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S); void EmitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective &S); void EmitOMPDistributeDirective(const OMPDistributeDirective &S); - + void EmitOMPDistributeLoop(const OMPDistributeDirective &S); + void EmitOMPDistributeParallelForDirective( + const OMPDistributeParallelForDirective &S); + void EmitOMPDistributeParallelForSimdDirective( + const OMPDistributeParallelForSimdDirective &S); + void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S); + void EmitOMPTargetParallelForSimdDirective( + const OMPTargetParallelForSimdDirective &S); + + /// Emit outlined function for the target directive. + static std::pair<llvm::Function * /*OutlinedFn*/, + llvm::Constant * /*OutlinedFnID*/> + EmitOMPTargetDirectiveOutlinedFunction(CodeGenModule &CGM, + const OMPTargetDirective &S, + StringRef ParentName, + bool IsOffloadEntry); /// \brief Emit inner loop of the worksharing/simd construct. /// /// \param S Directive, for which the inner loop must be emitted. @@ -2362,24 +2621,35 @@ public: const llvm::function_ref<void(CodeGenFunction &)> &PostIncGen); JumpDest getOMPCancelDestination(OpenMPDirectiveKind Kind); + /// Emit initial code for loop counters of loop-based directives. + void EmitOMPPrivateLoopCounters(const OMPLoopDirective &S, + OMPPrivateScope &LoopScope); private: - /// Helpers for the OpenMP loop directives. void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit); void EmitOMPSimdInit(const OMPLoopDirective &D, bool IsMonotonic = false); - void EmitOMPSimdFinal(const OMPLoopDirective &D); + void EmitOMPSimdFinal( + const OMPLoopDirective &D, + const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen); /// \brief Emit code for the worksharing loop-based directive. /// \return true, if this construct has any lastprivate clause, false - /// otherwise. bool EmitOMPWorksharingLoop(const OMPLoopDirective &S); - void EmitOMPForOuterLoop(OpenMPScheduleClauseKind ScheduleKind, + void EmitOMPOuterLoop(bool IsMonotonic, bool DynamicOrOrdered, + const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered, + Address LB, Address UB, Address ST, Address IL, llvm::Value *Chunk); + void EmitOMPForOuterLoop(const OpenMPScheduleTy &ScheduleKind, bool IsMonotonic, const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered, Address LB, Address UB, Address ST, Address IL, llvm::Value *Chunk); + void EmitOMPDistributeOuterLoop( + OpenMPDistScheduleClauseKind ScheduleKind, + const OMPDistributeDirective &S, OMPPrivateScope &LoopScope, + Address LB, Address UB, Address ST, Address IL, llvm::Value *Chunk); /// \brief Emit code for sections directive. - OpenMPDirectiveKind EmitSections(const OMPExecutableDirective &S); + void EmitSections(const OMPExecutableDirective &S); public: @@ -2430,7 +2700,6 @@ public: void EmitAtomicInit(Expr *E, LValue lvalue); bool LValueIsSuitableForInlineAtomic(LValue Src); - bool typeIsSuitableForInlineAtomic(QualType Ty, bool IsVolatile) const; RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot = AggValueSlot::ignored()); @@ -2446,8 +2715,10 @@ public: std::pair<RValue, llvm::Value *> EmitAtomicCompareExchange( LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, - llvm::AtomicOrdering Success = llvm::SequentiallyConsistent, - llvm::AtomicOrdering Failure = llvm::SequentiallyConsistent, + llvm::AtomicOrdering Success = + llvm::AtomicOrdering::SequentiallyConsistent, + llvm::AtomicOrdering Failure = + llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak = false, AggValueSlot Slot = AggValueSlot::ignored()); void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO, @@ -2680,11 +2951,10 @@ public: ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *E); - RValue EmitCXXStructorCall(const CXXMethodDecl *MD, llvm::Value *Callee, - ReturnValueSlot ReturnValue, llvm::Value *This, - llvm::Value *ImplicitParam, - QualType ImplicitParamTy, const CallExpr *E, - StructorType Type); + RValue EmitCXXDestructorCall(const CXXDestructorDecl *DD, llvm::Value *Callee, + llvm::Value *This, llvm::Value *ImplicitParam, + QualType ImplicitParamTy, const CallExpr *E, + StructorType Type); RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue); RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE, @@ -2708,6 +2978,8 @@ public: RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E, ReturnValueSlot ReturnValue); + RValue EmitCUDADevicePrintfCallExpr(const CallExpr *E, + ReturnValueSlot ReturnValue); RValue EmitBuiltinExpr(const FunctionDecl *FD, unsigned BuiltinID, const CallExpr *E, @@ -2798,19 +3070,25 @@ public: llvm::Value *EmitARCAutoreleaseReturnValue(llvm::Value *value); llvm::Value *EmitARCRetainAutoreleaseReturnValue(llvm::Value *value); llvm::Value *EmitARCRetainAutoreleasedReturnValue(llvm::Value *value); + llvm::Value *EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value); std::pair<LValue,llvm::Value*> EmitARCStoreAutoreleasing(const BinaryOperator *e); std::pair<LValue,llvm::Value*> EmitARCStoreStrong(const BinaryOperator *e, bool ignored); + std::pair<LValue,llvm::Value*> + EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored); llvm::Value *EmitObjCThrowOperand(const Expr *expr); llvm::Value *EmitObjCConsumeObject(QualType T, llvm::Value *Ptr); llvm::Value *EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr); llvm::Value *EmitARCExtendBlockObject(const Expr *expr); + llvm::Value *EmitARCReclaimReturnedObject(const Expr *e, + bool allowUnsafeClaim); llvm::Value *EmitARCRetainScalarExpr(const Expr *expr); llvm::Value *EmitARCRetainAutoreleaseScalarExpr(const Expr *expr); + llvm::Value *EmitARCUnsafeUnretainedScalarExpr(const Expr *expr); void EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values); @@ -2973,17 +3251,23 @@ public: /// If the statement (recursively) contains a switch or loop with a break /// inside of it, this is fine. static bool containsBreak(const Stmt *S); + + /// Determine if the given statement might introduce a declaration into the + /// current scope, by being a (possibly-labelled) DeclStmt. + static bool mightAddDeclToScope(const Stmt *S); /// ConstantFoldsToSimpleInteger - If the specified expression does not fold /// to a constant, or if it does but contains a label, return false. If it /// constant folds return true and set the boolean result in Result. - bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result); + bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, + bool AllowLabels = false); /// ConstantFoldsToSimpleInteger - If the specified expression does not fold /// to a constant, or if it does but contains a label, return false. If it /// constant folds return true and set the folded value. - bool ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APSInt &Result); - + bool ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APSInt &Result, + bool AllowLabels = false); + /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an /// if statement) to the specified blocks. Based on the condition, this might /// try to simplify the codegen of the conditional based on the branch. @@ -3013,8 +3297,9 @@ public: /// \brief Emit a slow path cross-DSO CFI check which calls __cfi_slowpath /// if Cond if false. - void EmitCfiSlowPathCheck(llvm::Value *Cond, llvm::ConstantInt *TypeId, - llvm::Value *Ptr); + void EmitCfiSlowPathCheck(SanitizerMask Kind, llvm::Value *Cond, + llvm::ConstantInt *TypeId, llvm::Value *Ptr, + ArrayRef<llvm::Constant *> StaticArgs); /// \brief Create a basic block that will call the trap intrinsic, and emit a /// conditional branch to it, for the -ftrapv checks. @@ -3024,6 +3309,9 @@ public: /// "trap-func-name" if specified. llvm::CallInst *EmitTrapCall(llvm::Intrinsic::ID IntrID); + /// \brief Emit a cross-DSO CFI failure handling function. + void EmitCfiCheckFail(); + /// \brief Create a check for a function parameter that may potentially be /// declared as non-null. void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc, @@ -3062,7 +3350,7 @@ private: /// /// \param AI - The first function argument of the expansion. void ExpandTypeFromArgs(QualType Ty, LValue Dst, - SmallVectorImpl<llvm::Argument *>::iterator &AI); + SmallVectorImpl<llvm::Value *>::iterator &AI); /// ExpandTypeToArgs - Expand an RValue \arg RV, with the LLVM type for \arg /// Ty, into individual arguments on the provided vector \arg IRCallArgs, @@ -3189,6 +3477,8 @@ public: Address EmitPointerWithAlignment(const Expr *Addr, AlignmentSource *Source = nullptr); + void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK); + private: QualType getVarArgType(const Expr *Arg); |