diff options
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 179 |
1 files changed, 107 insertions, 72 deletions
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index f9e2842329720..89cb850ab1b10 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -29,9 +29,9 @@ #include "clang/AST/Type.h" #include "clang/Basic/ABI.h" #include "clang/Basic/CapturedStmt.h" +#include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/TargetInfo.h" -#include "clang/Frontend/CodeGenOptions.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/MapVector.h" @@ -131,6 +131,7 @@ enum TypeEvaluationKind { SANITIZER_CHECK(ShiftOutOfBounds, shift_out_of_bounds, 0) \ SANITIZER_CHECK(SubOverflow, sub_overflow, 0) \ SANITIZER_CHECK(TypeMismatch, type_mismatch, 1) \ + SANITIZER_CHECK(AlignmentAssumption, alignment_assumption, 0) \ SANITIZER_CHECK(VLABoundNotPositive, vla_bound_not_positive, 0) enum SanitizerHandler { @@ -470,7 +471,7 @@ public: /// potentially set the return value. bool SawAsmBlock = false; - const FunctionDecl *CurSEHParent = nullptr; + const NamedDecl *CurSEHParent = nullptr; /// True if the current function is an outlined SEH helper. This can be a /// finally block or filter expression. @@ -1197,6 +1198,8 @@ public: private: CGDebugInfo *DebugInfo; + /// Used to create unique names for artificial VLA size debug info variables. + unsigned VLAExprCounter = 0; bool DisableDebugInfo = false; /// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid @@ -1746,6 +1749,9 @@ public: bool IsLambdaConversionToBlock, bool BuildGlobalBlock); + /// Check if \p T is a C++ class that has a destructor that can throw. + static bool cxxDestructorCanThrow(QualType T); + llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo); llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo); llvm::Constant *GenerateObjCAtomicSetterCopyHelperFunction( @@ -1754,7 +1760,8 @@ public: const ObjCPropertyImplDecl *PID); llvm::Value *EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty); - void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags); + void BuildBlockRelease(llvm::Value *DeclPtr, BlockFieldFlags flags, + bool CanThrow); class AutoVarEmission; @@ -1777,13 +1784,13 @@ public: /// \param LoadBlockVarAddr Indicates whether we need to emit a load from /// \p Addr to get the address of the __block structure. void enterByrefCleanup(CleanupKind Kind, Address Addr, BlockFieldFlags Flags, - bool LoadBlockVarAddr); + bool LoadBlockVarAddr, bool CanThrow); void setBlockContextParameter(const ImplicitParamDecl *D, unsigned argNum, llvm::Value *ptr); Address LoadBlockStruct(); - Address GetAddrOfBlockDecl(const VarDecl *var, bool ByRef); + Address GetAddrOfBlockDecl(const VarDecl *var); /// BuildBlockByrefAddress - Computes the location of the /// data in a variable which is declared as __block. @@ -1800,6 +1807,11 @@ public: void GenerateCode(GlobalDecl GD, llvm::Function *Fn, const CGFunctionInfo &FnInfo); + + /// Annotate the function with an attribute that disables TSan checking at + /// runtime. + void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn); + /// Emit code for the start of a function. /// \param Loc The location to be associated with the function. /// \param StartLoc The location of the function body. @@ -1816,7 +1828,7 @@ public: void EmitConstructorBody(FunctionArgList &Args); void EmitDestructorBody(FunctionArgList &Args); void emitImplicitAssignmentOperatorBody(FunctionArgList &Args); - void EmitFunctionBody(FunctionArgList &Args, const Stmt *Body); + void EmitFunctionBody(const Stmt *Body); void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S); void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator, @@ -1845,7 +1857,7 @@ public: void FinishThunk(); /// Emit a musttail call for a thunk with a potentially adjusted this pointer. - void EmitMustTailThunk(const CXXMethodDecl *MD, llvm::Value *AdjustedThisPtr, + void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, llvm::Value *Callee); /// Generate a thunk for the given method. @@ -2622,12 +2634,6 @@ public: ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre); - void EmitAlignmentAssumption(llvm::Value *PtrValue, unsigned Alignment, - llvm::Value *OffsetValue = nullptr) { - Builder.CreateAlignmentAssumption(CGM.getDataLayout(), PtrValue, Alignment, - OffsetValue); - } - /// Converts Location to a DebugLoc, if debug information is enabled. llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location); @@ -2674,8 +2680,9 @@ public: llvm::Value *NRVOFlag; - /// True if the variable is a __block variable. - bool IsByRef; + /// True if the variable is a __block variable that is captured by an + /// escaping block. + bool IsEscapingByRef; /// True if the variable is of aggregate type and has a constant /// initializer. @@ -2695,7 +2702,7 @@ public: AutoVarEmission(const VarDecl &variable) : Variable(&variable), Addr(Address::invalid()), NRVOFlag(nullptr), - IsByRef(false), IsConstantAggregate(false), + IsEscapingByRef(false), IsConstantAggregate(false), SizeForLifetimeMarkers(nullptr), AllocaAddr(Address::invalid()) {} bool wasEmittedAsGlobal() const { return !Addr.isValid(); } @@ -2725,7 +2732,7 @@ public: /// Note that this does not chase the forwarding pointer for /// __block decls. Address getObjectAddress(CodeGenFunction &CGF) const { - if (!IsByRef) return Addr; + if (!IsEscapingByRef) return Addr; return CGF.emitBlockByrefAddress(Addr, Variable, /*forward*/ false); } @@ -2790,11 +2797,27 @@ public: PeepholeProtection protectFromPeepholes(RValue rvalue); void unprotectFromPeepholes(PeepholeProtection protection); - void EmitAlignmentAssumption(llvm::Value *PtrValue, llvm::Value *Alignment, - llvm::Value *OffsetValue = nullptr) { - Builder.CreateAlignmentAssumption(CGM.getDataLayout(), PtrValue, Alignment, - OffsetValue); - } + void EmitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType Ty, + SourceLocation Loc, + SourceLocation AssumptionLoc, + llvm::Value *Alignment, + llvm::Value *OffsetValue, + llvm::Value *TheCheck, + llvm::Instruction *Assumption); + + void EmitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, + SourceLocation Loc, SourceLocation AssumptionLoc, + llvm::Value *Alignment, + llvm::Value *OffsetValue = nullptr); + + void EmitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, + SourceLocation Loc, SourceLocation AssumptionLoc, + unsigned Alignment, + llvm::Value *OffsetValue = nullptr); + + void EmitAlignmentAssumption(llvm::Value *PtrValue, const Expr *E, + SourceLocation AssumptionLoc, unsigned Alignment, + llvm::Value *OffsetValue = nullptr); //===--------------------------------------------------------------------===// // Statement Emission @@ -2878,6 +2901,8 @@ public: void EnterSEHTryStmt(const SEHTryStmt &S); void ExitSEHTryStmt(const SEHTryStmt &S); + void pushSEHCleanup(CleanupKind kind, + llvm::Function *FinallyFunc); void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, const Stmt *OutlinedStmt); @@ -3512,6 +3537,7 @@ public: ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr); ConstantEmission tryEmitAsConstant(const MemberExpr *ME); + llvm::Value *emitScalarConstant(const ConstantEmission &Constant, Expr *E); RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot = AggValueSlot::ignored()); @@ -3603,6 +3629,19 @@ public: CXXDtorType Type, const CXXRecordDecl *RD); + // Return the copy constructor name with the prefix "__copy_constructor_" + // removed. + static std::string getNonTrivialCopyConstructorStr(QualType QT, + CharUnits Alignment, + bool IsVolatile, + ASTContext &Ctx); + + // Return the destructor name with the prefix "__destructor_" removed. + static std::string getNonTrivialDestructorStr(QualType QT, + CharUnits Alignment, + bool IsVolatile, + ASTContext &Ctx); + // These functions emit calls to the special functions of non-trivial C // structs. void defaultInitNonTrivialCStructVar(LValue Dst); @@ -3653,9 +3692,10 @@ public: RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue); - RValue EmitBuiltinExpr(const FunctionDecl *FD, - unsigned BuiltinID, const CallExpr *E, - ReturnValueSlot ReturnValue); + RValue EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, + const CallExpr *E, ReturnValueSlot ReturnValue); + + RValue emitRotate(const CallExpr *E, bool IsRotateRight); /// Emit IR for __builtin_os_log_format. RValue emitBuiltinOSLogFormat(const CallExpr &E); @@ -3769,6 +3809,11 @@ public: llvm::Value *EmitARCRetainAutoreleasedReturnValue(llvm::Value *value); llvm::Value *EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value); + llvm::Value *EmitObjCAutorelease(llvm::Value *value, llvm::Type *returnType); + llvm::Value *EmitObjCRetainNonBlock(llvm::Value *value, + llvm::Type *returnType); + void EmitObjCRelease(llvm::Value *value, ARCPreciseLifetime_t precise); + std::pair<LValue,llvm::Value*> EmitARCStoreAutoreleasing(const BinaryOperator *e); std::pair<LValue,llvm::Value*> @@ -3776,6 +3821,10 @@ public: std::pair<LValue,llvm::Value*> EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored); + llvm::Value *EmitObjCAlloc(llvm::Value *value, + llvm::Type *returnType); + llvm::Value *EmitObjCAllocWithZone(llvm::Value *value, + llvm::Type *returnType); llvm::Value *EmitObjCThrowOperand(const Expr *expr); llvm::Value *EmitObjCConsumeObject(QualType T, llvm::Value *Ptr); llvm::Value *EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr); @@ -3865,6 +3914,8 @@ public: AddInitializerToStaticVarDecl(const VarDecl &D, llvm::GlobalVariable *GV); + // Emit an @llvm.invariant.start call for the given memory region. + void EmitInvariantStart(llvm::Constant *Addr, CharUnits Size); /// EmitCXXGlobalVarDeclInit - Create the initializer for a C++ /// variable with global storage. @@ -3900,9 +3951,10 @@ public: /// GenerateCXXGlobalInitFunc - Generates code for initializing global /// variables. - void GenerateCXXGlobalInitFunc(llvm::Function *Fn, - ArrayRef<llvm::Function *> CXXThreadLocals, - Address Guard = Address::invalid()); + void + GenerateCXXGlobalInitFunc(llvm::Function *Fn, + ArrayRef<llvm::Function *> CXXThreadLocals, + ConstantAddress Guard = ConstantAddress::invalid()); /// GenerateCXXGlobalDtorsFunc - Generates code for destroying global /// variables. @@ -3920,11 +3972,13 @@ public: void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp); - void enterFullExpression(const ExprWithCleanups *E) { - if (E->getNumObjects() == 0) return; + void enterFullExpression(const FullExpr *E) { + if (const auto *EWC = dyn_cast<ExprWithCleanups>(E)) + if (EWC->getNumObjects() == 0) + return; enterNonTrivialFullExpression(E); } - void enterNonTrivialFullExpression(const ExprWithCleanups *E); + void enterNonTrivialFullExpression(const FullExpr *E); void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint = true); @@ -4245,47 +4299,29 @@ public: void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK); - struct TargetMultiVersionResolverOption { + struct MultiVersionResolverOption { llvm::Function *Function; - TargetAttr::ParsedTargetAttr ParsedAttribute; - unsigned Priority; - TargetMultiVersionResolverOption( - const TargetInfo &TargInfo, llvm::Function *F, - const clang::TargetAttr::ParsedTargetAttr &PT) - : Function(F), ParsedAttribute(PT), Priority(0u) { - for (StringRef Feat : PT.Features) - Priority = std::max(Priority, - TargInfo.multiVersionSortPriority(Feat.substr(1))); - - if (!PT.Architecture.empty()) - Priority = std::max(Priority, - TargInfo.multiVersionSortPriority(PT.Architecture)); - } - - bool operator>(const TargetMultiVersionResolverOption &Other) const { - return Priority > Other.Priority; - } + FunctionDecl *FD; + struct Conds { + StringRef Architecture; + llvm::SmallVector<StringRef, 8> Features; + + Conds(StringRef Arch, ArrayRef<StringRef> Feats) + : Architecture(Arch), Features(Feats.begin(), Feats.end()) {} + } Conditions; + + MultiVersionResolverOption(llvm::Function *F, StringRef Arch, + ArrayRef<StringRef> Feats) + : Function(F), Conditions(Arch, Feats) {} }; - void EmitTargetMultiVersionResolver( - llvm::Function *Resolver, - ArrayRef<TargetMultiVersionResolverOption> Options); - struct CPUDispatchMultiVersionResolverOption { - llvm::Function *Function; - // Note: EmitX86CPUSupports only has 32 bits available, so we store the mask - // as 32 bits here. When 64-bit support is added to __builtin_cpu_supports, - // this can be extended to 64 bits. - uint32_t FeatureMask; - CPUDispatchMultiVersionResolverOption(llvm::Function *F, uint64_t Mask) - : Function(F), FeatureMask(static_cast<uint32_t>(Mask)) {} - bool operator>(const CPUDispatchMultiVersionResolverOption &Other) const { - return FeatureMask > Other.FeatureMask; - } - }; - void EmitCPUDispatchMultiVersionResolver( - llvm::Function *Resolver, - ArrayRef<CPUDispatchMultiVersionResolverOption> Options); - static uint32_t GetX86CpuSupportsMask(ArrayRef<StringRef> FeatureStrs); + // Emits the body of a multiversion function's resolver. Assumes that the + // options are already sorted in the proper order, with the 'default' option + // last (if it exists). + void EmitMultiVersionResolver(llvm::Function *Resolver, + ArrayRef<MultiVersionResolverOption> Options); + + static uint64_t GetX86CpuSupportsMask(ArrayRef<StringRef> FeatureStrs); private: QualType getVarArgType(const Expr *Arg); @@ -4302,10 +4338,9 @@ private: llvm::Value *EmitX86CpuIs(StringRef CPUStr); llvm::Value *EmitX86CpuSupports(const CallExpr *E); llvm::Value *EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs); - llvm::Value *EmitX86CpuSupports(uint32_t Mask); + llvm::Value *EmitX86CpuSupports(uint64_t Mask); llvm::Value *EmitX86CpuInit(); - llvm::Value * - FormResolverCondition(const TargetMultiVersionResolverOption &RO); + llvm::Value *FormResolverCondition(const MultiVersionResolverOption &RO); }; inline DominatingLLVMValue::saved_type |