summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenFunction.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.h')
-rw-r--r--lib/CodeGen/CodeGenFunction.h179
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