// locations of subexpressions in the initialization.
EmitExprAsInit(&l2r, &blockFieldPseudoVar,
MakeAddrLValue(blockField, type, align),
- /*captured by init*/ false, SourceLocation());
+ /*captured by init*/ false);
}
// Activate the cleanup if layout pushed one.
Alloca->setAlignment(Align);
// Set the DebugLocation to empty, so the store is recognized as a
// frame setup instruction by llvm::DwarfDebug::beginFunction().
- NoLocation NL(*this, Builder);
+ ApplyDebugLocation NL(*this);
Builder.CreateAlignedStore(BlockPointer, Alloca, Align);
BlockPointerDbgLoc = Alloca;
}
false,
false);
// Create a scope with an artificial location for the body of this function.
- ArtificialLocation AL(*this, Builder);
+ ApplyDebugLocation NL(*this);
StartFunction(FD, C.VoidTy, Fn, FI, args);
- AL.Emit();
+ ArtificialLocation AL(*this);
llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();
nullptr, SC_Static,
false, false);
// Create a scope with an artificial location for the body of this function.
- ArtificialLocation AL(*this, Builder);
+ ApplyDebugLocation NL(*this);
StartFunction(FD, C.VoidTy, Fn, FI, args);
- AL.Emit();
+ ArtificialLocation AL(*this);
llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();
CXXCtorInitializer *MemberInit,
const CXXConstructorDecl *Constructor,
FunctionArgList &Args) {
+ ApplyDebugLocation Loc(CGF, MemberInit->getMemberLocation());
assert(MemberInit->isAnyMemberInitializer() &&
"Must have member initializer!");
assert(MemberInit->getInit() && "Must have initializer!");
ArrayRef<VarDecl *> ArrayIndexes;
if (MemberInit->getNumArrayIndices())
ArrayIndexes = MemberInit->getArrayIndexes();
- CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit(), ArrayIndexes,
- MemberInit->getMemberLocation());
+ ApplyDebugLocation DL(CGF, MemberInit->getMemberLocation());
+ CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit(), ArrayIndexes);
}
-void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS,
- Expr *Init,
- ArrayRef<VarDecl *> ArrayIndexes,
- SourceLocation DbgLoc) {
+void CodeGenFunction::EmitInitializerForField(
+ FieldDecl *Field, LValue LHS, Expr *Init,
+ ArrayRef<VarDecl *> ArrayIndexes) {
QualType FieldType = Field->getType();
switch (getEvaluationKind(FieldType)) {
case TEK_Scalar:
if (LHS.isSimple()) {
- EmitExprAsInit(Init, Field, LHS, false, DbgLoc);
+ EmitExprAsInit(Init, Field, LHS, false);
} else {
RValue RHS = RValue::get(EmitScalarExpr(Init));
EmitStoreThroughLValue(RHS, LHS);
}
break;
case TEK_Complex:
- EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true, DbgLoc);
+ EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true);
break;
case TEK_Aggregate: {
llvm::Value *ArrayIndexVar = nullptr;
// delegation optimization.
if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor) &&
CGM.getTarget().getCXXABI().hasConstructorVariants()) {
- if (CGDebugInfo *DI = getDebugInfo())
- DI->EmitLocation(Builder, Ctor->getLocEnd());
EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args, Ctor->getLocEnd());
return;
}
// Emit the EH cleanup if required.
if (RequiresEHCleanup) {
- CGDebugInfo *DI = getDebugInfo();
- SaveAndRestoreLocation AutoRestoreLocation(*this, Builder);
- if (DI)
- DI->EmitLocation(Builder, CurEHLocation);
+ ApplyDebugLocation AutoRestoreLocation(*this, CurEHLocation);
CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
"Region stack mismatch, stack not empty!");
}
-SaveAndRestoreLocation::SaveAndRestoreLocation(CodeGenFunction &CGF,
- CGBuilderTy &B)
- : DI(CGF.getDebugInfo()), Builder(B) {
- if (DI) {
- SavedLoc = DI->getLocation();
- DI->CurLoc = SourceLocation();
- }
-}
-
-SaveAndRestoreLocation::~SaveAndRestoreLocation() {
- if (DI)
- DI->EmitLocation(Builder, SavedLoc);
-}
-
-NoLocation::NoLocation(CodeGenFunction &CGF, CGBuilderTy &B)
- : SaveAndRestoreLocation(CGF, B) {
- if (DI)
- Builder.SetCurrentDebugLocation(llvm::DebugLoc());
-}
-
-NoLocation::~NoLocation() {
- if (DI)
- assert(Builder.getCurrentDebugLocation().isUnknown());
-}
-
-ArtificialLocation::ArtificialLocation(CodeGenFunction &CGF, CGBuilderTy &B)
- : SaveAndRestoreLocation(CGF, B) {
- if (DI)
- Builder.SetCurrentDebugLocation(llvm::DebugLoc());
-}
-
-void ArtificialLocation::Emit() {
- if (DI) {
- // Sync the Builder.
- DI->EmitLocation(Builder, SavedLoc);
- DI->CurLoc = SourceLocation();
+ArtificialLocation::ArtificialLocation(CodeGenFunction &CGF)
+ : ApplyDebugLocation(CGF) {
+ if (auto *DI = CGF.getDebugInfo()) {
// Construct a location that has a valid scope, but no line info.
assert(!DI->LexicalBlockStack.empty());
llvm::DIDescriptor Scope(DI->LexicalBlockStack.back());
- Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(0, 0, Scope));
+ CGF.Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(0, 0, Scope));
+ }
+}
+
+ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF,
+ SourceLocation TemporaryLocation,
+ bool ForceColumnInfo)
+ : CGF(CGF) {
+ if (auto *DI = CGF.getDebugInfo()) {
+ OriginalLocation = CGF.Builder.getCurrentDebugLocation();
+ if (TemporaryLocation.isInvalid())
+ CGF.Builder.SetCurrentDebugLocation(llvm::DebugLoc());
+ else
+ DI->EmitLocation(CGF.Builder, TemporaryLocation, ForceColumnInfo);
}
}
-ArtificialLocation::~ArtificialLocation() {
- if (DI)
- assert(Builder.getCurrentDebugLocation().getLine() == 0);
+ApplyDebugLocation::~ApplyDebugLocation() {
+ CGF.Builder.SetCurrentDebugLocation(OriginalLocation);
}
+/// ArtificialLocation - An RAII object that temporarily switches to
+/// an artificial debug location that has a valid scope, but no line
void CGDebugInfo::setLocation(SourceLocation Loc) {
// If the new location isn't valid return.
if (Loc.isInvalid())
}
};
-/// SaveAndRestoreLocation - An RAII object saves the current location
-/// and automatically restores it to the original value.
-class SaveAndRestoreLocation {
+class ApplyDebugLocation {
protected:
- SourceLocation SavedLoc;
- CGDebugInfo *DI;
- CGBuilderTy &Builder;
-public:
- SaveAndRestoreLocation(CodeGenFunction &CGF, CGBuilderTy &B);
- /// Autorestore everything back to normal.
- ~SaveAndRestoreLocation();
-};
+ llvm::DebugLoc OriginalLocation;
+ CodeGenFunction &CGF;
-/// NoLocation - An RAII object that temporarily disables debug
-/// locations. This is useful for emitting instructions that should be
-/// counted towards the function prologue.
-class NoLocation : public SaveAndRestoreLocation {
public:
- NoLocation(CodeGenFunction &CGF, CGBuilderTy &B);
- /// Autorestore everything back to normal.
- ~NoLocation();
+ ApplyDebugLocation(CodeGenFunction &CGF,
+ SourceLocation TemporaryLocation = SourceLocation(),
+ bool ForceColumnInfo = false);
+ ~ApplyDebugLocation();
};
/// ArtificialLocation - An RAII object that temporarily switches to
/// This is necessary because passing an empty SourceLocation to
/// CGDebugInfo::setLocation() will result in the last valid location
/// being reused.
-class ArtificialLocation : public SaveAndRestoreLocation {
+class ArtificialLocation : public ApplyDebugLocation {
public:
- ArtificialLocation(CodeGenFunction &CGF, CGBuilderTy &B);
-
- /// Set the current location to line 0, but within the current scope
- /// (= the top of the LexicalBlockStack).
- void Emit();
-
- /// Autorestore everything back to normal.
- ~ArtificialLocation();
+ ArtificialLocation(CodeGenFunction &CGF);
};
}
void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
- LValue lvalue, bool capturedByInit,
- SourceLocation DbgLoc) {
+ LValue lvalue, bool capturedByInit) {
Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime();
if (!lifetime) {
llvm::Value *value = EmitScalarExpr(init);
if (capturedByInit)
drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
- EmitStoreThroughLValue(RValue::get(value), lvalue, true, DbgLoc);
+ EmitStoreThroughLValue(RValue::get(value), lvalue, true);
return;
}
if (emission.wasEmittedAsGlobal()) return;
const VarDecl &D = *emission.Variable;
+ ApplyDebugLocation DL(*this, D.getLocation());
QualType type = D.getType();
// If this local has an initializer, emit it now.
if (!constant) {
LValue lv = MakeAddrLValue(Loc, type, alignment);
lv.setNonGC(true);
- return EmitExprAsInit(Init, &D, lv, capturedByInit, D.getLocation());
+ return EmitExprAsInit(Init, &D, lv, capturedByInit);
}
if (!emission.IsConstantAggregate) {
/// \param capturedByInit true if the variable is a __block variable
/// whose address is potentially changed by the initializer
void CodeGenFunction::EmitExprAsInit(const Expr *init, const ValueDecl *D,
- LValue lvalue, bool capturedByInit,
- SourceLocation DbgLoc) {
+ LValue lvalue, bool capturedByInit) {
QualType type = D->getType();
if (type->isReferenceType()) {
RValue rvalue = EmitReferenceBindingToExpr(init);
if (capturedByInit)
drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
- EmitStoreThroughLValue(rvalue, lvalue, true, DbgLoc);
+ EmitStoreThroughLValue(rvalue, lvalue, true);
return;
}
switch (getEvaluationKind(type)) {
case TEK_Scalar:
- EmitScalarInit(init, D, lvalue, capturedByInit, DbgLoc);
+ EmitScalarInit(init, D, lvalue, capturedByInit);
return;
case TEK_Complex: {
ComplexPairTy complex = EmitComplexExpr(init);
if (capturedByInit)
drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
- EmitStoreOfComplex(complex, lvalue, /*init*/ true, DbgLoc);
+ EmitStoreOfComplex(complex, lvalue, /*init*/ true);
return;
}
case TEK_Aggregate:
ArrayRef<llvm::Function *> Decls,
llvm::GlobalVariable *Guard) {
{
- ArtificialLocation AL(*this, Builder);
+ ApplyDebugLocation NL(*this);
StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
getTypes().arrangeNullaryFunction(), FunctionArgList());
// Emit an artificial location for this function.
- AL.Emit();
+ ArtificialLocation AL(*this);
llvm::BasicBlock *ExitBlock = nullptr;
if (Guard) {
const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> >
&DtorsAndObjects) {
{
- ArtificialLocation AL(*this, Builder);
+ ApplyDebugLocation NL(*this);
StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
getTypes().arrangeNullaryFunction(), FunctionArgList());
// Emit an artificial location for this function.
- AL.Emit();
+ ArtificialLocation AL(*this);
// Emit the dtors, in reverse order from construction.
for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
// Save the current IR generation state.
CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();
- SaveAndRestoreLocation AutoRestoreLocation(*this, Builder);
- if (CGDebugInfo *DI = getDebugInfo())
- DI->EmitLocation(Builder, CurEHLocation);
+ ApplyDebugLocation AutoRestoreLocation(*this, CurEHLocation);
const EHPersonality &personality = EHPersonality::get(CGM);
/// lvalue, where both are guaranteed to the have the same type, and that type
/// is 'Ty'.
void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
- bool isInit,
- SourceLocation DbgLoc) {
- if (auto *DI = getDebugInfo())
- DI->EmitLocation(Builder, DbgLoc);
-
+ bool isInit) {
if (!Dst.isSimple()) {
if (Dst.isVectorElt()) {
// Read/modify/write the vector, inserting the new element.
// The element count here is the total number of non-VLA elements.
llvm::Value *numElements = getVLASize(vla).first;
- if (auto *DI = getDebugInfo())
- DI->EmitLocation(Builder, E->getLocStart());
-
// Effectively, the multiply by the VLA size is part of the GEP.
// GEP indexes are signed, and scaling an index isn't permitted to
// signed-overflow, so we use the same semantics for our explicit
// Propagate the alignment from the array itself to the result.
ArrayAlignment = ArrayLV.getAlignment();
- if (auto *DI = getDebugInfo())
- DI->EmitLocation(Builder, E->getLocStart());
-
if (getLangOpts().isSignedOverflowDefined())
Address = Builder.CreateGEP(ArrayPtr, Args, "arrayidx");
else
} else {
// The base must be a pointer, which is not an aggregate. Emit it.
llvm::Value *Base = EmitScalarExpr(E->getBase());
- if (auto *DI = getDebugInfo())
- DI->EmitLocation(Builder, E->getLocStart());
if (getLangOpts().isSignedOverflowDefined())
Address = Builder.CreateGEP(Base, Idx, "arrayidx");
else
RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,
ReturnValueSlot ReturnValue) {
- if (CGDebugInfo *DI = getDebugInfo()) {
- SourceLocation Loc = E->getLocStart();
- // Force column info to be generated so we can differentiate
- // multiple call sites on the same line in the debug info.
- // FIXME: This is insufficient. Two calls coming from the same macro
- // expansion will still get the same line/column and break debug info. It's
- // possible that LLVM can be fixed to not rely on this uniqueness, at which
- // point this workaround can be removed.
- const FunctionDecl* Callee = E->getDirectCallee();
- bool ForceColumnInfo = Callee && Callee->isInlineSpecified();
- DI->EmitLocation(Builder, Loc, ForceColumnInfo);
- }
+ // Force column info to be generated so we can differentiate
+ // multiple call sites on the same line in the debug info.
+ // FIXME: This is insufficient. Two calls coming from the same macro
+ // expansion will still get the same line/column and break debug info. It's
+ // possible that LLVM can be fixed to not rely on this uniqueness, at which
+ // point this workaround can be removed.
+ ApplyDebugLocation DL(*this, E->getLocStart(),
+ E->getDirectCallee() &&
+ E->getDirectCallee()->isInlineSpecified());
// Builtins never have block type.
if (E->getCallee()->getType()->isBlockPointerType())
RValue RV = EmitAnyExpr(E->getRHS());
LValue LV = EmitCheckedLValue(E->getLHS(), TCK_Store);
- if (CGDebugInfo *DI = getDebugInfo())
- DI->EmitLocation(Builder, E->getLocStart());
EmitStoreThroughLValue(RV, LV);
return LV;
}
unsigned ArgsToSkip = isa<CXXOperatorCallExpr>(CE) ? 1 : 0;
llvm::Value *RHS =
EmitLValue(*(CE->arg_begin() + ArgsToSkip)).getAddress();
- if (auto *DI = getDebugInfo())
- DI->EmitLocation(Builder, CE->getLocStart());
EmitAggregateAssign(This, RHS, CE->getType());
return RValue::get(This);
}
}
static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init,
- QualType AllocType, llvm::Value *NewPtr,
- SourceLocation DbgLoc = SourceLocation()) {
+ QualType AllocType, llvm::Value *NewPtr) {
// FIXME: Refactor with EmitExprAsInit.
CharUnits Alignment = CGF.getContext().getTypeAlignInChars(AllocType);
switch (CGF.getEvaluationKind(AllocType)) {
case TEK_Scalar:
CGF.EmitScalarInit(Init, nullptr,
- CGF.MakeAddrLValue(NewPtr, AllocType, Alignment), false,
- DbgLoc);
+ CGF.MakeAddrLValue(NewPtr, AllocType, Alignment), false);
return;
case TEK_Complex:
CGF.EmitComplexExprIntoLValue(Init, CGF.MakeAddrLValue(NewPtr, AllocType,
llvm::Value *NewPtr,
llvm::Value *NumElements,
llvm::Value *AllocSizeWithoutCookie) {
+ ApplyDebugLocation DL(CGF, E->getStartLoc());
if (E->isArray())
CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements,
AllocSizeWithoutCookie);
else if (const Expr *Init = E->getInitializer())
- StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr,
- E->getStartLoc());
+ StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr);
}
/// Emit a call to an operator new or operator delete function, as implicitly
E->placement_arg_end(), /* CalleeDecl */ nullptr,
/*ParamsToSkip*/ 1);
- if (auto *DI = getDebugInfo())
- DI->EmitLocation(Builder, E->getLocStart());
-
// Emit the allocation call. If the allocator is a global placement
// operator, just "inline" it directly.
RValue RV;
/// EmitStoreOfComplex - Store the specified real/imag parts into the
/// specified value pointer.
- void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit,
- SourceLocation DbgLoc);
+ void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit);
/// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType.
ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
/// EmitStoreOfComplex - Store the specified real/imag parts into the
/// specified value pointer.
void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, LValue lvalue,
- bool isInit,
- SourceLocation DbgLoc) {
- if (auto *DI = CGF.getDebugInfo())
- DI->EmitLocation(CGF.Builder, DbgLoc);
-
+ bool isInit) {
if (lvalue.getType()->isAtomicType())
return CGF.EmitAtomicStore(RValue::getComplex(Val), lvalue, isInit);
// Truncate the result and store it into the LHS lvalue.
if (LHSTy->isAnyComplexType()) {
ComplexPairTy ResVal = EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy);
- EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false, E->getLocStart());
+ EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false);
Val = RValue::getComplex(ResVal);
} else {
llvm::Value *ResVal =
LValue LHS = CGF.EmitLValue(E->getLHS());
// Store the result value into the LHS lvalue.
- EmitStoreOfComplex(Val, LHS, /*isInit*/ false, E->getLocStart());
+ EmitStoreOfComplex(Val, LHS, /*isInit*/ false);
return LHS;
}
}
void CodeGenFunction::EmitComplexExprIntoLValue(const Expr *E, LValue dest,
- bool isInit,
- SourceLocation DbgLoc) {
+ bool isInit) {
assert(E && getComplexType(E->getType()) &&
"Invalid complex expression to emit");
ComplexExprEmitter Emitter(*this);
ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E));
- Emitter.EmitStoreOfComplex(Val, dest, isInit, DbgLoc);
+ Emitter.EmitStoreOfComplex(Val, dest, isInit);
}
/// EmitStoreOfComplex - Store a complex number into the specified l-value.
void CodeGenFunction::EmitStoreOfComplex(ComplexPairTy V, LValue dest,
- bool isInit, SourceLocation DbgLoc) {
- ComplexExprEmitter(*this).EmitStoreOfComplex(V, dest, isInit, DbgLoc);
+ bool isInit) {
+ ComplexExprEmitter(*this).EmitStoreOfComplex(V, dest, isInit);
}
/// EmitLoadOfComplex - Load a complex number from the specified address.
//===--------------------------------------------------------------------===//
Value *Visit(Expr *E) {
+ ApplyDebugLocation DL(CGF, E->getLocStart());
return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
}
// Emit an unconditional branch from this block to ContBlock.
{
// There is no need to emit line number for unconditional branch.
- SuppressDebugLocation S(Builder);
+ ApplyDebugLocation DL(CGF);
CGF.EmitBlock(ContBlock);
}
// Insert an entry into the phi node for the edge with the value of RHSCond.
if (const Stmt *Else = S.getElse()) {
{
// There is no need to emit line number for unconditional branch.
- SuppressDebugLocation S(Builder);
+ ApplyDebugLocation DL(*this);
EmitBlock(ElseBlock);
}
{
}
{
// There is no need to emit line number for unconditional branch.
- SuppressDebugLocation S(Builder);
+ ApplyDebugLocation DL(*this);
EmitBranch(ContBlock);
}
}
// Emit the 'else' code if present.
{
// There is no need to emit line number for unconditional branch.
- SuppressDebugLocation SDL(CGF.Builder);
+ ApplyDebugLocation DL(CGF);
CGF.EmitBlock(ElseBlock);
}
CodeGen(/*ThenBlock*/ false);
{
// There is no need to emit line number for unconditional branch.
- SuppressDebugLocation SDL(CGF.Builder);
+ ApplyDebugLocation DL(CGF);
CGF.EmitBranch(ContBlock);
}
// Emit the continuation block for code after the if.
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 {
FunctionArgList &Args);
void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init,
- ArrayRef<VarDecl *> ArrayIndexes,
- SourceLocation DbgLoc = SourceLocation());
+ ArrayRef<VarDecl *> ArrayIndexes);
/// InitializeVTablePointer - Initialize the vtable pointer of the given
/// subobject.
/// 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, SourceLocation DbgLoc);
+ bool capturedByInit);
/// hasVolatileMember - returns true if aggregate type has a volatile
/// member.
void EmitVarDecl(const VarDecl &D);
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue,
- bool capturedByInit,
- SourceLocation DbgLoc = SourceLocation());
+ bool capturedByInit);
void EmitScalarInit(llvm::Value *init, LValue lvalue);
typedef void SpecialInitFn(CodeGenFunction &Init, const VarDecl &D,
/// 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,
- SourceLocation DbgLoc = SourceLocation());
+ void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit = false);
void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst);
void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst);
/// EmitComplexExprIntoLValue - Emit the given expression of complex
/// type and place its result into the specified l-value.
- void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit,
- SourceLocation DbgLoc = SourceLocation());
+ void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit);
/// EmitStoreOfComplex - Store a complex number into the specified l-value.
- void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit,
- SourceLocation DbgLoc = SourceLocation());
+ void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit);
/// EmitLoadOfComplex - Load a complex number from the specified l-value.
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc);
-// RUN: %clang_cc1 -triple %itanium_abi_triple -g -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -g -mllvm -no-discriminators -emit-llvm %s -o - | FileCheck %s
struct C {
~C();
// CHECK: call {{.*}}, !dbg [[DTOR_CALL2_LOC:![0-9]*]]
// CHECK: [[FUN1:.*]] = {{.*}}; [ DW_TAG_subprogram ] {{.*}} [def] [fun1]
// CHECK: [[FUN2:.*]] = {{.*}}; [ DW_TAG_subprogram ] {{.*}} [def] [fun2]
-// CHECK: [[DTOR_CALL1_LOC]] = !{i32 [[@LINE+2]], i32 0, [[FUN1_BLOCK:.*]], null}
-// CHECK: [[FUN1_BLOCK]] = !{!"0xb{{[^,]*}}", {{[^,]*}}, [[FUN1]]}
+// CHECK: [[DTOR_CALL1_LOC]] = !{i32 [[@LINE+1]], i32 0, [[FUN1]], null}
void fun1() { b && (C(), 1); }
-// CHECK: [[DTOR_CALL2_LOC]] = !{i32 [[@LINE+2]], i32 0, [[FUN2_BLOCK1:.*]], null}
-// CHECK: [[FUN2_BLOCK1]] = !{!"0xb{{[^,]*}}", {{[^,]*}}, [[FUN2]]}
+// CHECK: [[DTOR_CALL2_LOC]] = !{i32 [[@LINE+1]], i32 0, [[FUN2]], null}
bool fun2() { return (C(), b) && 0; }
// RUN: %clang_cc1 -g -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-linux-gnu -g -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
int &src();
int *sink();
new (void_src()) int(src()));
}
+__complex double f11() {
+ __complex double f;
+ // CHECK: store {{.*}} !dbg [[DBG_F11:!.*]]
+#line 1200
+ return f;
+}
+
// CHECK: [[DBG_F1]] = !{i32 100,
// CHECK: [[DBG_FOO_VALUE]] = !{i32 200,
// CHECK: [[DBG_FOO_REF]] = !{i32 202,
// CHECK: [[DBG_F9]] = !{i32 1000,
// CHECK: [[DBG_F10_ICMP]] = !{i32 1100,
// CHECK: [[DBG_F10_STORE]] = !{i32 1100,
+// CHECK: [[DBG_F11]] = !{i32 1200,
// CHECK: = !{!"0x100\00{{.*}}", [[FOR:![0-9]*]], {{.*}} ; [ DW_TAG_auto_variable ] [i] [line [[@LINE+2]]]
// CHECK: [[FOR]] = !{!"0xb\00[[@LINE+1]]\00{{.*}}", !{{.*}}} ; [ DW_TAG_lexical_block ]
for (int i = 0; i != 10; ++i) {
- // FIXME: Do not include scopes that have only other scopes (and no variables
- // or using declarations) as direct children, they just waste
- // space/relocations/etc.
- // CHECK: = !{!"0x100\00{{.*}}", [[FOR_COMPOUND:![0-9]*]], {{.*}} ; [ DW_TAG_auto_variable ] [b] [line [[@LINE+3]]]
- // CHECK: [[FOR_COMPOUND]] = !{!"0xb\00[[@LINE-5]]\00{{.*}}", !{{[0-9]+}}, [[FOR_BODY:![0-9]+]]} ; [ DW_TAG_lexical_block ]
- // CHECK: [[FOR_BODY]] = !{!"0xb\00[[@LINE-6]]\00{{.*}}", !{{[0-9]+}}, [[FOR]]} ; [ DW_TAG_lexical_block ]
+ // FIXME: Do not include scopes that have only other scopes (and no variables
+ // or using declarations) as direct children, they just waste
+ // space/relocations/etc.
+ // CHECK: [[FOR_LOOP_INCLUDING_COND:!.*]] = !{!"0xb\00[[@LINE-4]]\00{{.*}}", !{{[0-9]+}}, [[FOR]]} ; [ DW_TAG_lexical_block ]
+ // CHECK: = !{!"0x100\00{{.*}}", [[FOR_COMPOUND:![0-9]*]], {{.*}} ; [ DW_TAG_auto_variable ] [b] [line [[@LINE+2]]]
+ // CHECK: [[FOR_COMPOUND]] = !{!"0xb\00[[@LINE-6]]\00{{.*}}", !{{[0-9]+}}, [[FOR_LOOP_INCLUDING_COND]]} ; [ DW_TAG_lexical_block ]
bool b = i % 2;
}