Update aosp/master clang for rebase to r230699.
Change-Id: I6a546ab3d4ae37119eebb735e102cca4f80ab520
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 4575e31..c0368aa 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -27,6 +27,7 @@
#include "clang/AST/Type.h"
#include "clang/Basic/ABI.h"
#include "clang/Basic/CapturedStmt.h"
+#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/ADT/ArrayRef.h"
@@ -93,24 +94,11 @@
TEK_Aggregate
};
-class SuppressDebugLocation {
- llvm::DebugLoc CurLoc;
- llvm::IRBuilderBase &Builder;
-public:
- SuppressDebugLocation(llvm::IRBuilderBase &Builder)
- : CurLoc(Builder.getCurrentDebugLocation()), Builder(Builder) {
- Builder.SetCurrentDebugLocation(llvm::DebugLoc());
- }
- ~SuppressDebugLocation() {
- Builder.SetCurrentDebugLocation(CurLoc);
- }
-};
-
/// CodeGenFunction - This class organizes the per-function state that is used
/// while generating LLVM code.
class CodeGenFunction : public CodeGenTypeCache {
- CodeGenFunction(const CodeGenFunction &) LLVM_DELETED_FUNCTION;
- void operator=(const CodeGenFunction &) LLVM_DELETED_FUNCTION;
+ CodeGenFunction(const CodeGenFunction &) = delete;
+ void operator=(const CodeGenFunction &) = delete;
friend class CGCXXABI;
public:
@@ -182,6 +170,8 @@
/// \brief API for captured statement code generation.
class CGCapturedStmtInfo {
public:
+ explicit CGCapturedStmtInfo(CapturedRegionKind K = CR_Default)
+ : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {}
explicit CGCapturedStmtInfo(const CapturedStmt &S,
CapturedRegionKind K = CR_Default)
: Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {
@@ -204,22 +194,22 @@
void setContextValue(llvm::Value *V) { ThisValue = V; }
// \brief Retrieve the value of the context parameter.
- llvm::Value *getContextValue() const { return ThisValue; }
+ virtual llvm::Value *getContextValue() const { return ThisValue; }
/// \brief Lookup the captured field decl for a variable.
- const FieldDecl *lookup(const VarDecl *VD) const {
+ virtual const FieldDecl *lookup(const VarDecl *VD) const {
return CaptureFields.lookup(VD);
}
- bool isCXXThisExprCaptured() const { return CXXThisFieldDecl != nullptr; }
- FieldDecl *getThisFieldDecl() const { return CXXThisFieldDecl; }
+ bool isCXXThisExprCaptured() const { return getThisFieldDecl() != nullptr; }
+ virtual FieldDecl *getThisFieldDecl() const { return CXXThisFieldDecl; }
static bool classof(const CGCapturedStmtInfo *) {
return true;
}
/// \brief Emit the captured statement body.
- virtual void EmitBody(CodeGenFunction &CGF, Stmt *S) {
+ virtual void EmitBody(CodeGenFunction &CGF, const Stmt *S) {
RegionCounter Cnt = CGF.getPGORegionCounter(S);
Cnt.beginRegion(CGF.Builder);
CGF.EmitStmt(S);
@@ -285,6 +275,7 @@
EHScopeStack EHStack;
llvm::SmallVector<char, 256> LifetimeExtendedCleanupStack;
+ llvm::SmallVector<const JumpDest *, 2> SEHTryEpilogueStack;
/// Header for data within LifetimeExtendedCleanupStack.
struct LifetimeExtendedCleanupHeader {
@@ -316,6 +307,12 @@
/// write the current selector value into this alloca.
llvm::AllocaInst *EHSelectorSlot;
+ llvm::AllocaInst *AbnormalTerminationSlot;
+
+ /// The implicit parameter to SEH filter functions of type
+ /// 'EXCEPTION_POINTERS*'.
+ ImplicitParamDecl *SEHPointersDecl;
+
/// Emits a landing pad for the current EH stack.
llvm::BasicBlock *EmitLandingPad();
@@ -354,6 +351,20 @@
void exit(CodeGenFunction &CGF);
};
+ /// Cleanups can be emitted for two reasons: normal control leaving a region
+ /// exceptional control flow leaving a region.
+ struct SEHFinallyInfo {
+ SEHFinallyInfo()
+ : FinallyBB(nullptr), ContBB(nullptr), ResumeBB(nullptr) {}
+
+ llvm::BasicBlock *FinallyBB;
+ llvm::BasicBlock *ContBB;
+ llvm::BasicBlock *ResumeBB;
+ };
+
+ /// Returns true inside SEH __try blocks.
+ bool isSEHTryScope() const { return !SEHTryEpilogueStack.empty(); }
+
/// pushFullExprCleanup - Push a cleanup to be run at the end of the
/// current full-expression. Safe against the possibility that
/// we're currently inside a conditionally-evaluated expression.
@@ -499,8 +510,8 @@
bool PerformCleanup;
private:
- RunCleanupsScope(const RunCleanupsScope &) LLVM_DELETED_FUNCTION;
- void operator=(const RunCleanupsScope &) LLVM_DELETED_FUNCTION;
+ RunCleanupsScope(const RunCleanupsScope &) = delete;
+ void operator=(const RunCleanupsScope &) = delete;
protected:
CodeGenFunction& CGF;
@@ -548,8 +559,8 @@
SmallVector<const LabelDecl*, 4> Labels;
LexicalScope *ParentScope;
- LexicalScope(const LexicalScope &) LLVM_DELETED_FUNCTION;
- void operator=(const LexicalScope &) LLVM_DELETED_FUNCTION;
+ LexicalScope(const LexicalScope &) = delete;
+ void operator=(const LexicalScope &) = delete;
public:
/// \brief Enter a new cleanup scope.
@@ -573,7 +584,10 @@
// If we should perform a cleanup, force them now. Note that
// this ends the cleanup scope before rescoping any labels.
- if (PerformCleanup) ForceCleanup();
+ if (PerformCleanup) {
+ ApplyDebugLocation DL(CGF, Range.getEnd());
+ ForceCleanup();
+ }
}
/// \brief Force the emission of cleanups now, instead of waiting
@@ -598,8 +612,8 @@
VarDeclMapTy SavedPrivates;
private:
- OMPPrivateScope(const OMPPrivateScope &) LLVM_DELETED_FUNCTION;
- void operator=(const OMPPrivateScope &) LLVM_DELETED_FUNCTION;
+ OMPPrivateScope(const OMPPrivateScope &) = delete;
+ void operator=(const OMPPrivateScope &) = delete;
public:
/// \brief Enter a new OpenMP private scope.
@@ -614,7 +628,6 @@
addPrivate(const VarDecl *LocalVD,
const std::function<llvm::Value *()> &PrivateGen) {
assert(PerformCleanup && "adding private to dead scope");
- assert(LocalVD->isLocalVarDecl() && "privatizing non-local variable");
if (SavedLocals.count(LocalVD) > 0) return false;
SavedLocals[LocalVD] = CGF.LocalDeclMap.lookup(LocalVD);
CGF.LocalDeclMap.erase(LocalVD);
@@ -1089,6 +1102,10 @@
llvm::Value *getExceptionSlot();
llvm::Value *getEHSelectorSlot();
+ /// Stack slot that contains whether a __finally block is being executed as an
+ /// EH cleanup or as a normal cleanup.
+ llvm::Value *getAbnormalTerminationSlot();
+
/// Returns the contents of the function's exception object and selector
/// slots.
llvm::Value *getExceptionFromSlot();
@@ -1109,6 +1126,11 @@
return getInvokeDestImpl();
}
+ bool currentFunctionUsesSEHTry() const {
+ const auto *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl);
+ return FD && FD->usesSEHTry();
+ }
+
const TargetInfo &getTarget() const { return Target; }
llvm::LLVMContext &getLLVMContext() { return CGM.getLLVMContext(); }
@@ -1178,9 +1200,7 @@
void GenerateObjCMethod(const ObjCMethodDecl *OMD);
- void StartObjCMethod(const ObjCMethodDecl *MD,
- const ObjCContainerDecl *CD,
- SourceLocation StartLoc);
+ void StartObjCMethod(const ObjCMethodDecl *MD, const ObjCContainerDecl *CD);
/// GenerateObjCGetter - Synthesize an Objective-C property getter function.
void GenerateObjCGetter(ObjCImplementationDecl *IMP,
@@ -1272,15 +1292,18 @@
void EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD);
void EmitAsanPrologueOrEpilogue(bool Prologue);
- /// EmitReturnBlock - Emit the unified return block, trying to avoid its
- /// emission when possible.
- void EmitReturnBlock();
+ /// \brief Emit the unified return block, trying to avoid its emission when
+ /// possible.
+ /// \return The debug location of the user written return statement if the
+ /// return block is is avoided.
+ llvm::DebugLoc EmitReturnBlock();
/// FinishFunction - Complete IR generation of the current function. It is
/// legal to call this function even if there is no current insertion point.
void FinishFunction(SourceLocation EndLoc=SourceLocation());
- void StartThunk(llvm::Function *Fn, GlobalDecl GD, const CGFunctionInfo &FnInfo);
+ void StartThunk(llvm::Function *Fn, GlobalDecl GD,
+ const CGFunctionInfo &FnInfo);
void EmitCallAndReturnForThunk(llvm::Value *Callee, const ThunkInfo *Thunk);
@@ -1323,6 +1346,9 @@
/// to by This.
llvm::Value *GetVTablePtr(llvm::Value *This, llvm::Type *Ty);
+ /// 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);
/// CanDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given
/// expr can be devirtualized.
@@ -1543,8 +1569,8 @@
/// EmitExprAsInit - Emits the code necessary to initialize a
/// location in memory with the given initializer.
- void EmitExprAsInit(const Expr *init, const ValueDecl *D,
- LValue lvalue, bool capturedByInit);
+ void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue,
+ bool capturedByInit);
/// hasVolatileMember - returns true if aggregate type has a volatile
/// member.
@@ -1566,6 +1592,15 @@
true);
}
+ void EmitAggregateCopyCtor(llvm::Value *DestPtr, llvm::Value *SrcPtr,
+ QualType DestTy, QualType SrcTy) {
+ CharUnits DestTypeAlign = getContext().getTypeAlignInChars(DestTy);
+ CharUnits SrcTypeAlign = getContext().getTypeAlignInChars(SrcTy);
+ EmitAggregateCopy(DestPtr, SrcPtr, SrcTy, /*IsVolatile=*/false,
+ std::min(DestTypeAlign, SrcTypeAlign),
+ /*IsAssignment=*/false);
+ }
+
/// EmitAggregateCopy - Emit an aggregate copy.
///
/// \param isVolatile - True iff either the source or the destination is
@@ -1830,8 +1865,8 @@
/// This function can be called with a null (unreachable) insert point.
void EmitVarDecl(const VarDecl &D);
- void EmitScalarInit(const Expr *init, const ValueDecl *D,
- LValue lvalue, bool capturedByInit);
+ 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,
@@ -2002,6 +2037,17 @@
void EmitCXXTryStmt(const CXXTryStmt &S);
void EmitSEHTryStmt(const SEHTryStmt &S);
void EmitSEHLeaveStmt(const SEHLeaveStmt &S);
+ void EnterSEHTryStmt(const SEHTryStmt &S, SEHFinallyInfo &FI);
+ void ExitSEHTryStmt(const SEHTryStmt &S, SEHFinallyInfo &FI);
+
+ llvm::Function *GenerateSEHFilterFunction(CodeGenFunction &ParentCGF,
+ const SEHExceptStmt &Except);
+
+ void EmitSEHExceptionCodeSave();
+ llvm::Value *EmitSEHExceptionCode();
+ llvm::Value *EmitSEHExceptionInfo();
+ llvm::Value *EmitSEHAbnormalTermination();
+
void EmitCXXForRangeStmt(const CXXForRangeStmt &S,
ArrayRef<const Attr *> Attrs = None);
@@ -2041,12 +2087,22 @@
void EmitOMPTargetDirective(const OMPTargetDirective &S);
void EmitOMPTeamsDirective(const OMPTeamsDirective &S);
- /// Helpers for 'omp simd' directive.
+private:
+
+ /// Helpers for the OpenMP loop directives.
void EmitOMPLoopBody(const OMPLoopDirective &Directive,
bool SeparateIter = false);
void EmitOMPInnerLoop(const OMPLoopDirective &S, OMPPrivateScope &LoopScope,
bool SeparateIter = false);
void EmitOMPSimdFinal(const OMPLoopDirective &S);
+ void EmitOMPWorksharingLoop(const OMPLoopDirective &S);
+ void EmitOMPForOuterLoop(OpenMPScheduleClauseKind ScheduleKind,
+ const OMPLoopDirective &S,
+ OMPPrivateScope &LoopScope, llvm::Value *LB,
+ llvm::Value *UB, llvm::Value *ST, llvm::Value *IL,
+ llvm::Value *Chunk);
+
+public:
//===--------------------------------------------------------------------===//
// LValue Expression Emission
@@ -2094,11 +2150,27 @@
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());
+
RValue EmitAtomicLoad(LValue lvalue, SourceLocation loc,
+ llvm::AtomicOrdering AO, bool IsVolatile = false,
AggValueSlot slot = AggValueSlot::ignored());
void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit);
+ void EmitAtomicStore(RValue rvalue, LValue lvalue, llvm::AtomicOrdering AO,
+ bool IsVolatile, bool isInit);
+
+ std::pair<RValue, RValue> EmitAtomicCompareExchange(
+ LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc,
+ llvm::AtomicOrdering Success = llvm::SequentiallyConsistent,
+ llvm::AtomicOrdering Failure = llvm::SequentiallyConsistent,
+ bool IsWeak = false, AggValueSlot Slot = AggValueSlot::ignored());
+
/// EmitToMemory - Change a scalar value from its value
/// representation to its in-memory representation.
llvm::Value *EmitToMemory(llvm::Value *Value, QualType Ty);
@@ -2150,7 +2222,7 @@
/// EmitStoreThroughLValue - Store the specified rvalue into the specified
/// lvalue, where both are guaranteed to the have the same type, and that type
/// is 'Ty'.
- void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false);
+ void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit = false);
void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst);
void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst);
@@ -2166,8 +2238,8 @@
/// Emit an l-value for an assignment (simple or compound) of complex type.
LValue EmitComplexAssignmentLValue(const BinaryOperator *E);
LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E);
- LValue EmitScalarCompooundAssignWithComplex(const CompoundAssignOperator *E,
- llvm::Value *&Result);
+ LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E,
+ llvm::Value *&Result);
// Note: only available for agg return types
LValue EmitBinaryOperatorLValue(const BinaryOperator *E);
@@ -2211,7 +2283,7 @@
return ConstantEmission(C, false);
}
- LLVM_EXPLICIT operator bool() const {
+ explicit operator bool() const {
return ValueAndIsReference.getOpaqueValue() != nullptr;
}
@@ -2281,7 +2353,8 @@
RValue EmitCall(QualType FnType, llvm::Value *Callee, const CallExpr *E,
ReturnValueSlot ReturnValue,
- const Decl *TargetDecl = nullptr);
+ const Decl *TargetDecl = nullptr,
+ llvm::Value *Chain = nullptr);
RValue EmitCallExpr(const CallExpr *E,
ReturnValueSlot ReturnValue = ReturnValueSlot());
@@ -2329,12 +2402,16 @@
StructorType Type);
RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E,
ReturnValueSlot ReturnValue);
+ RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE,
+ const CXXMethodDecl *MD,
+ ReturnValueSlot ReturnValue,
+ bool HasQualifier,
+ NestedNameSpecifier *Qualifier,
+ bool IsArrow, const Expr *Base);
+ // Compute the object pointer.
RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
ReturnValueSlot ReturnValue);
- llvm::Value *EmitCXXOperatorMemberCallee(const CXXOperatorCallExpr *E,
- const CXXMethodDecl *MD,
- llvm::Value *This);
RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
const CXXMethodDecl *MD,
ReturnValueSlot ReturnValue);
@@ -2344,7 +2421,8 @@
RValue EmitBuiltinExpr(const FunctionDecl *FD,
- unsigned BuiltinID, const CallExpr *E);
+ unsigned BuiltinID, const CallExpr *E,
+ ReturnValueSlot ReturnValue);
RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue);
@@ -2711,7 +2789,7 @@
CallExpr::const_arg_iterator ArgBeg,
CallExpr::const_arg_iterator ArgEnd,
const FunctionDecl *CalleeDecl = nullptr,
- unsigned ParamsToSkip = 0, bool ForceColumnInfo = false) {
+ unsigned ParamsToSkip = 0) {
SmallVector<QualType, 16> ArgTypes;
CallExpr::const_arg_iterator Arg = ArgBeg;
@@ -2723,28 +2801,13 @@
E = CallArgTypeInfo->param_type_end();
I != E; ++I, ++Arg) {
assert(Arg != ArgEnd && "Running over edge of argument list!");
-#ifndef NDEBUG
- QualType ArgType = *I;
- QualType ActualArgType = Arg->getType();
- if (ArgType->isPointerType() && ActualArgType->isPointerType()) {
- QualType ActualBaseType =
- ActualArgType->getAs<PointerType>()->getPointeeType();
- QualType ArgBaseType =
- ArgType->getAs<PointerType>()->getPointeeType();
- if (ArgBaseType->isVariableArrayType()) {
- if (const VariableArrayType *VAT =
- getContext().getAsVariableArrayType(ActualBaseType)) {
- if (!VAT->getSizeExpr())
- ActualArgType = ArgType;
- }
- }
- }
- assert(getContext()
- .getCanonicalType(ArgType.getNonReferenceType())
- .getTypePtr() ==
- getContext().getCanonicalType(ActualArgType).getTypePtr() &&
- "type mismatch in call argument!");
-#endif
+ assert(
+ ((*I)->isVariablyModifiedType() ||
+ getContext()
+ .getCanonicalType((*I).getNonReferenceType())
+ .getTypePtr() ==
+ getContext().getCanonicalType(Arg->getType()).getTypePtr()) &&
+ "type mismatch in call argument!");
ArgTypes.push_back(*I);
}
}
@@ -2759,15 +2822,14 @@
for (; Arg != ArgEnd; ++Arg)
ArgTypes.push_back(getVarArgType(*Arg));
- EmitCallArgs(Args, ArgTypes, ArgBeg, ArgEnd, CalleeDecl, ParamsToSkip,
- ForceColumnInfo);
+ EmitCallArgs(Args, ArgTypes, ArgBeg, ArgEnd, CalleeDecl, ParamsToSkip);
}
void EmitCallArgs(CallArgList &Args, ArrayRef<QualType> ArgTypes,
CallExpr::const_arg_iterator ArgBeg,
CallExpr::const_arg_iterator ArgEnd,
const FunctionDecl *CalleeDecl = nullptr,
- unsigned ParamsToSkip = 0, bool ForceColumnInfo = false);
+ unsigned ParamsToSkip = 0);
private:
QualType getVarArgType(const Expr *Arg);
@@ -2787,6 +2849,8 @@
/// GetPointeeAlignment - Given an expression with a pointer type, emit the
/// value and compute our best estimate of the alignment of the pointee.
std::pair<llvm::Value*, unsigned> EmitPointerWithAlignment(const Expr *Addr);
+
+ llvm::Value *GetValueForARMHint(unsigned BuiltinID);
};
/// Helper class with most of the code for saving a value for a