From bab175ec4b075c8076ba14c762900392533f6ee4 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Mon, 2 Jan 2017 19:18:08 +0000 Subject: Vendor import of clang trunk r290819: https://llvm.org/svn/llvm-project/cfe/trunk@290819 --- lib/CodeGen/CodeGenFunction.h | 177 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 152 insertions(+), 25 deletions(-) (limited to 'lib/CodeGen/CodeGenFunction.h') diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index fb19a2657c9c..222d0e97968a 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -21,6 +21,7 @@ #include "CodeGenModule.h" #include "CodeGenPGO.h" #include "EHScopeStack.h" +#include "VarBypassDetector.h" #include "clang/AST/CharUnits.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" @@ -77,6 +78,7 @@ class ObjCAutoreleasePoolStmt; namespace CodeGen { class CodeGenTypes; +class CGCallee; class CGFunctionInfo; class CGRecordLayout; class CGBlockInfo; @@ -88,6 +90,7 @@ class BlockFieldFlags; class RegionCodeGenTy; class TargetCodeGenInfo; struct OMPTaskDataTy; +struct CGCoroData; /// The kind of evaluation to perform on values of a particular /// type. Basically, is the code in CGExprScalar, CGExprComplex, or @@ -100,6 +103,32 @@ enum TypeEvaluationKind { TEK_Aggregate }; +#define LIST_SANITIZER_CHECKS \ + SANITIZER_CHECK(AddOverflow, add_overflow, 0) \ + SANITIZER_CHECK(BuiltinUnreachable, builtin_unreachable, 0) \ + SANITIZER_CHECK(CFICheckFail, cfi_check_fail, 0) \ + SANITIZER_CHECK(DivremOverflow, divrem_overflow, 0) \ + SANITIZER_CHECK(DynamicTypeCacheMiss, dynamic_type_cache_miss, 0) \ + SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0) \ + SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 0) \ + SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0) \ + SANITIZER_CHECK(MissingReturn, missing_return, 0) \ + SANITIZER_CHECK(MulOverflow, mul_overflow, 0) \ + SANITIZER_CHECK(NegateOverflow, negate_overflow, 0) \ + SANITIZER_CHECK(NonnullArg, nonnull_arg, 0) \ + SANITIZER_CHECK(NonnullReturn, nonnull_return, 0) \ + SANITIZER_CHECK(OutOfBounds, out_of_bounds, 0) \ + SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0) \ + SANITIZER_CHECK(SubOverflow, sub_overflow, 0) \ + SANITIZER_CHECK(TypeMismatch, type_mismatch, 0) \ + SANITIZER_CHECK(VLABoundNotPositive, vla_bound_not_positive, 0) + +enum SanitizerHandler { +#define SANITIZER_CHECK(Enum, Name, Version) Enum, + LIST_SANITIZER_CHECKS +#undef SANITIZER_CHECK +}; + /// CodeGenFunction - This class organizes the per-function state that is used /// while generating LLVM code. class CodeGenFunction : public CodeGenTypeCache { @@ -140,6 +169,10 @@ public: LoopInfoStack LoopStack; CGBuilderTy Builder; + // Stores variables for which we can't generate correct lifetime markers + // because of jumps. + VarBypassDetector Bypasses; + /// \brief CGBuilder insert helper. This function is called after an /// instruction is created using Builder. void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, @@ -155,6 +188,16 @@ public: QualType FnRetTy; llvm::Function *CurFn; + // Holds coroutine data if the current function is a coroutine. We use a + // wrapper to manage its lifetime, so that we don't have to define CGCoroData + // in this header. + struct CGCoroInfo { + std::unique_ptr Data; + CGCoroInfo(); + ~CGCoroInfo(); + }; + CGCoroInfo CurCoro; + /// CurGD - The GlobalDecl for the current function being compiled. GlobalDecl CurGD; @@ -430,7 +473,7 @@ public: LifetimeExtendedCleanupStack.resize( LifetimeExtendedCleanupStack.size() + sizeof(Header) + Header.Size); - static_assert(sizeof(Header) % llvm::AlignOf::Alignment == 0, + static_assert(sizeof(Header) % alignof(T) == 0, "Cleanup will be allocated on misaligned address"); char *Buffer = &LifetimeExtendedCleanupStack[OldSize]; new (Buffer) LifetimeExtendedCleanupHeader(Header); @@ -901,6 +944,17 @@ public: e->getCommon()); } + /// Build the opaque value mapping for an OpaqueValueExpr whose source + /// expression is set to the expression the OVE represents. + OpaqueValueMapping(CodeGenFunction &CGF, const OpaqueValueExpr *OV) + : CGF(CGF) { + if (OV) { + assert(OV->getSourceExpr() && "wrong form of OpaqueValueMapping used " + "for OVE with no source expression"); + Data = OpaqueValueMappingData::bind(CGF, OV, OV->getSourceExpr()); + } + } + OpaqueValueMapping(CodeGenFunction &CGF, const OpaqueValueExpr *opaqueValue, LValue lvalue) @@ -1166,6 +1220,23 @@ public: CharUnits OldCXXThisAlignment; }; + /// The scope of an ArrayInitLoopExpr. Within this scope, the value of the + /// current loop index is overridden. + class ArrayInitLoopExprScope { + public: + ArrayInitLoopExprScope(CodeGenFunction &CGF, llvm::Value *Index) + : CGF(CGF), OldArrayInitIndex(CGF.ArrayInitIndex) { + CGF.ArrayInitIndex = Index; + } + ~ArrayInitLoopExprScope() { + CGF.ArrayInitIndex = OldArrayInitIndex; + } + + private: + CodeGenFunction &CGF; + llvm::Value *OldArrayInitIndex; + }; + class InlinedInheritingConstructorScope { public: InlinedInheritingConstructorScope(CodeGenFunction &CGF, GlobalDecl GD) @@ -1234,6 +1305,10 @@ private: /// this expression. Address CXXDefaultInitExprThis = Address::invalid(); + /// The current array initialization index when evaluating an + /// ArrayInitIndexExpr within an ArrayInitLoopExpr. + llvm::Value *ArrayInitIndex = nullptr; + /// The values of function arguments to use when evaluating /// CXXInheritedCtorInitExprs within this context. CallArgList CXXInheritedCtorInitExprArgs; @@ -1263,6 +1338,9 @@ private: llvm::BasicBlock *TerminateHandler; llvm::BasicBlock *TrapBB; + /// True if we need emit the life-time markers. + const bool ShouldEmitLifetimeMarkers; + /// Add a kernel metadata node to the named metadata node 'opencl.kernels'. /// In the kernel metadata node, reference the kernel function and metadata /// nodes for its optional attribute qualifiers (OpenCL 1.1 6.7.2): @@ -1421,7 +1499,6 @@ public: //===--------------------------------------------------------------------===// llvm::Value *EmitBlockLiteral(const BlockExpr *); - llvm::Value *EmitBlockLiteral(const CGBlockInfo &Info); static void destroyBlockInfos(CGBlockInfo *info); llvm::Function *GenerateBlockFunction(GlobalDecl GD, @@ -1503,7 +1580,8 @@ public: void StartThunk(llvm::Function *Fn, GlobalDecl GD, const CGFunctionInfo &FnInfo); - void EmitCallAndReturnForThunk(llvm::Value *Callee, const ThunkInfo *Thunk); + void EmitCallAndReturnForThunk(llvm::Constant *Callee, + const ThunkInfo *Thunk); void FinishThunk(); @@ -1522,8 +1600,7 @@ public: void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type, FunctionArgList &Args); - void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init, - ArrayRef ArrayIndexes); + void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init); /// Struct with all informations about dynamic [sub]class needed to set vptr. struct VPtr { @@ -1932,6 +2009,9 @@ public: return it->second; } + /// Get the index of the current ArrayInitLoopExpr, if any. + llvm::Value *getArrayInitIndex() { return ArrayInitIndex; } + /// getAccessedFieldNo - Given an encoded value and a result number, return /// the input field number being accessed. static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts); @@ -2110,7 +2190,8 @@ public: void EmitCXXDeleteExpr(const CXXDeleteExpr *E); void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, - QualType DeleteTy); + QualType DeleteTy, llvm::Value *NumElements = nullptr, + CharUnits CookieSize = CharUnits()); RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type, const Expr *Arg, bool IsDelete); @@ -2179,6 +2260,10 @@ public: OffsetValue); } + /// Converts Location to a DebugLoc, if debug information is enabled. + llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location); + + //===--------------------------------------------------------------------===// // Declaration Emission //===--------------------------------------------------------------------===// @@ -2195,7 +2280,6 @@ public: void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit); - void EmitScalarInit(llvm::Value *init, LValue lvalue); typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D, llvm::Value *Address); @@ -2378,6 +2462,9 @@ public: void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S); void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S); + void EmitCoroutineBody(const CoroutineBodyStmt &S); + RValue EmitCoroutineIntrinsic(const CallExpr *E, unsigned int IID); + void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false); void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false); @@ -2480,6 +2567,9 @@ public: OMPPrivateScope &PrivateScope); void EmitOMPPrivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope); + void EmitOMPUseDevicePtrClause( + const OMPClause &C, OMPPrivateScope &PrivateScope, + const llvm::DenseMap &CaptureDeviceAddrMap); /// \brief Emit code for copyin clause in \a D directive. The next code is /// generated at the start of outlined functions for directives: /// \code @@ -2596,6 +2686,19 @@ public: void EmitOMPDistributeSimdDirective(const OMPDistributeSimdDirective &S); void EmitOMPTargetParallelForSimdDirective( const OMPTargetParallelForSimdDirective &S); + void EmitOMPTargetSimdDirective(const OMPTargetSimdDirective &S); + void EmitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective &S); + void + EmitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective &S); + void EmitOMPTeamsDistributeParallelForSimdDirective( + const OMPTeamsDistributeParallelForSimdDirective &S); + void EmitOMPTeamsDistributeParallelForDirective( + const OMPTeamsDistributeParallelForDirective &S); + void EmitOMPTargetTeamsDirective(const OMPTargetTeamsDirective &S); + void EmitOMPTargetTeamsDistributeDirective( + const OMPTargetTeamsDistributeDirective &S); + void EmitOMPTargetTeamsDistributeParallelForDirective( + const OMPTargetTeamsDistributeParallelForDirective &S); /// Emit outlined function for the target directive. static std::pair args); - llvm::Value *BuildAppleKextVirtualCall(const CXXMethodDecl *MD, - NestedNameSpecifier *Qual, - llvm::Type *Ty); + CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD, + NestedNameSpecifier *Qual, + llvm::Type *Ty); - llvm::Value *BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, - CXXDtorType Type, - const CXXRecordDecl *RD); + CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, + CXXDtorType Type, + const CXXRecordDecl *RD); RValue - EmitCXXMemberOrOperatorCall(const CXXMethodDecl *MD, llvm::Value *Callee, + EmitCXXMemberOrOperatorCall(const CXXMethodDecl *Method, + const CGCallee &Callee, ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, - QualType ImplicitParamTy, const CallExpr *E); - RValue EmitCXXDestructorCall(const CXXDestructorDecl *DD, llvm::Value *Callee, + QualType ImplicitParamTy, const CallExpr *E, + CallArgList *RtlArgs); + RValue EmitCXXDestructorCall(const CXXDestructorDecl *DD, + const CGCallee &Callee, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *E, StructorType Type); @@ -2974,6 +3083,7 @@ public: RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue); + RValue EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E); RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E, ReturnValueSlot ReturnValue); @@ -3029,6 +3139,12 @@ public: llvm::Value *EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, const CallExpr *E); +private: + enum class MSVCIntrin; + +public: + llvm::Value *EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E); + llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E); llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E); llvm::Value *EmitObjCBoxedExpr(const ObjCBoxedExpr *E); @@ -3292,7 +3408,7 @@ public: /// sanitizer runtime with the provided arguments, and create a conditional /// branch to it. void EmitCheck(ArrayRef> Checked, - StringRef CheckName, ArrayRef StaticArgs, + SanitizerHandler Check, ArrayRef StaticArgs, ArrayRef DynamicArgs); /// \brief Emit a slow path cross-DSO CFI check which calls __cfi_slowpath @@ -3400,12 +3516,22 @@ public: static bool isObjCMethodWithTypeParams(const T *) { return false; } #endif + enum class EvaluationOrder { + ///! No language constraints on evaluation order. + Default, + ///! Language semantics require left-to-right evaluation. + ForceLeftToRight, + ///! Language semantics require right-to-left evaluation. + ForceRightToLeft + }; + /// EmitCallArgs - Emit call arguments for a function. template void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, llvm::iterator_range ArgRange, const FunctionDecl *CalleeDecl = nullptr, - unsigned ParamsToSkip = 0) { + unsigned ParamsToSkip = 0, + EvaluationOrder Order = EvaluationOrder::Default) { SmallVector ArgTypes; CallExpr::const_arg_iterator Arg = ArgRange.begin(); @@ -3445,13 +3571,14 @@ public: for (auto *A : llvm::make_range(Arg, ArgRange.end())) ArgTypes.push_back(getVarArgType(A)); - EmitCallArgs(Args, ArgTypes, ArgRange, CalleeDecl, ParamsToSkip); + EmitCallArgs(Args, ArgTypes, ArgRange, CalleeDecl, ParamsToSkip, Order); } void EmitCallArgs(CallArgList &Args, ArrayRef ArgTypes, llvm::iterator_range ArgRange, const FunctionDecl *CalleeDecl = nullptr, - unsigned ParamsToSkip = 0); + unsigned ParamsToSkip = 0, + EvaluationOrder Order = EvaluationOrder::Default); /// EmitPointerWithAlignment - Given an expression with a pointer /// type, emit the value and compute our best estimate of the -- cgit v1.2.3