Debug Info / EmitCallArgs: arguments may modify the debug location.

Restore it after each argument is emitted. This fixes the scope info for
inlined subroutines inside of function argument expressions. (E.g.,
anything STL).

rdar://problem/12592135

llvm-svn: 187240
This commit is contained in:
Adrian Prantl 2013-07-26 20:42:57 +00:00
parent 39b1a26aeb
commit ca64c3e136
3 changed files with 49 additions and 4 deletions

View File

@ -3096,8 +3096,15 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
const FunctionType *FnType
= cast<FunctionType>(cast<PointerType>(CalleeType)->getPointeeType());
// Force column info to differentiate multiple inlined call sites on
// the same line, analoguous to EmitCallExpr.
bool ForceColumnInfo = false;
if (const FunctionDecl* FD = dyn_cast_or_null<const FunctionDecl>(TargetDecl))
ForceColumnInfo = FD->isInlineSpecified();
CallArgList Args;
EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd);
EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd,
ForceColumnInfo);
const CGFunctionInfo &FnInfo =
CGM.getTypes().arrangeFreeFunctionCall(Args, FnType);

View File

@ -2483,8 +2483,13 @@ private:
template<typename T>
void EmitCallArgs(CallArgList& Args, const T* CallArgTypeInfo,
CallExpr::const_arg_iterator ArgBeg,
CallExpr::const_arg_iterator ArgEnd) {
CallExpr::const_arg_iterator Arg = ArgBeg;
CallExpr::const_arg_iterator ArgEnd,
bool ForceColumnInfo = false) {
CGDebugInfo *DI = getDebugInfo();
SourceLocation CallLoc;
if (DI) CallLoc = DI->getLocation();
CallExpr::const_arg_iterator Arg = ArgBeg;
// First, use the argument types that the type info knows about
if (CallArgTypeInfo) {
@ -2513,6 +2518,10 @@ private:
"type mismatch in call argument!");
#endif
EmitCallArg(Args, *Arg, ArgType);
// Each argument expression could modify the debug
// location. Restore it.
if (DI) DI->EmitLocation(Builder, CallLoc, ForceColumnInfo);
}
// Either we've emitted all the call args, or we have a call to a
@ -2523,8 +2532,12 @@ private:
}
// If we still have any arguments, emit them using the type of the argument.
for (; Arg != ArgEnd; ++Arg)
for (; Arg != ArgEnd; ++Arg) {
EmitCallArg(Args, *Arg, Arg->getType());
// Restore the debug location.
if (DI) DI->EmitLocation(Builder, CallLoc, ForceColumnInfo);
}
}
const TargetCodeGenInfo &getTargetHooks() const {

View File

@ -83,6 +83,21 @@ main(int argc, char const *argv[])
// result
// CHECK: call void @llvm.dbg.declare
// We want to see a distinct !dbg node.
// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg ![[A_DI]]
// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg !{{.*}}
// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg ![[B_DI]]
// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg !{{.*}}
// result
// CHECK: call void @llvm.dbg.declare
// Again: we want to see a distinct !dbg node.
// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[X_MD:[0-9]+]]), !dbg ![[X_DI:[0-9]+]]
// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[Y_MD:[0-9]+]]), !dbg ![[Y_DI:[0-9]+]]
// result
// CHECK: call void @llvm.dbg.declare
// CHECK: define {{.*}} @main
// CHECK: call {{.*}} @_Z3fooii
// CHECK: call {{.*}} @_Z3fooii
@ -96,3 +111,13 @@ main(int argc, char const *argv[])
// CHECK: load {{.*}} !dbg ![[DBG]]
// CHECK: call {{.*}} @_Z11strange_maxii(i32 {{.*}}, i32 {{.*}}), !dbg ![[DBG]]
// CHECK: call {{.*}} @_Z11strange_maxii(i32 {{.*}}, i32 {{.*}}), !dbg ![[DBG]]
// Verify that product() has its own inlined_at location at column 15.
// CHECK-DAG: ![[A_MD]] = metadata{{.*}}[ DW_TAG_arg_variable ] [a]
// CHECK-DAG: ![[B_MD]] = metadata{{.*}}[ DW_TAG_arg_variable ] [b]
// CHECK-DAG: ![[X_MD]] = metadata{{.*}}[ DW_TAG_arg_variable ] [x]
// CHECK-DAG: ![[Y_MD]] = metadata{{.*}}[ DW_TAG_arg_variable ] [y]
// CHECK-DAG: ![[X_DI]] = metadata !{i32 {{[0-9]+}}, i32 {{[0-9]+}}, metadata !{{[0-9]+}}, metadata ![[PRODUCT:[0-9]+]]}
// CHECK-DAG: [[PRODUCT]] = metadata !{i32 {{.*}}, i32 16, metadata !{{.*}}, null}
// CHECK-DAG: ![[Y_DI]] = metadata !{i32 {{[0-9]+}}, i32 {{[0-9]+}}, metadata !{{[0-9]+}}, metadata ![[PRODUCT]]}