No location info for artificial arguments: cannot step into class methods

Hi David,

I got a problem related to the change made in r188651 - not including file/line info for artificial arguments like “this” and “self”.
Would you be able to take a look at it, please?

I am compiling the code for ARM linux with fast ISel disabled: -mllvm -fast-isel=0. The problem is that it’s not possible to step into the constructor, destructor or a method of a class while debugging. Clang generates correct .loc in function prologues, but then, due to r188651, inserts a debug info location with zeroed line number (.loc 1 0 0) for “this”, which misleads the debugger.

Could you explain the reasoning behind this change, please?

This hasn’t been noticed before due to the fast ISel omitting location info for arguments, so the correct location from the prologue is used. It is probably yet another problem to handle.

Thanks in advance for any help.
Kind regards,
Oleg

Hi David,

I got a problem related to the change made in r188651 - not including
file/line info for artificial arguments like "this" and "self".
Would you be able to take a look at it, please?

Could you provide a simple test case? (& ideally: does this reproduce on
X86, a platform I've easy access to (& if it doesn't, I'd be curious to
understand why not...))

I am compiling the code for ARM linux with fast ISel disabled: -mllvm
-fast-isel=0. The problem is that it's not possible to step into the
constructor, destructor or a method of a class while debugging. Clang
generates correct .loc in function prologues, but then, due to r188651,
inserts a debug info location with zeroed line number (.loc 1 0 0) for
"this", which misleads the debugger.

Could you explain the reasoning behind this change, please?

The reason for the change, if I recall correctly (perhaps I mentioned in
the commit message, I'm not sure) was to reduce debug info size for the
debug_info section - I don't believe the intent was to have any impact on
the line table.

(artificial variables, like "this" don't have a location they are declared
on, so there was/is no need to have a DW_AT_decl_file/line in the
debug_info describing their declaration location)

Sure. It’s enough to have a simple class with a constructor and create its instance.
Compile it w/o fast ISel, e.g.: clang -g -O0 main.cpp --target=armv7l-unknown-linux-gnueabihf -mllvm -fast-isel=0

class MyClass
{
public:
MyClass()
{
}
};
int main()
{
MyClass obj; // ← can’t step into MyClass::MyClass() here
return 0;
}

It didn’t reproduce on X86_64 though. I will try to find out why.

I see, thanks.
The r188651 patch leads to inserting “.loc 1 0 0” into the constructor’s code. Here is a part of the assembly I get for the MyClass constructor:

_ZN7MyClassC2Ev: @ @_ZN7MyClassC2Ev
.Lfunc_begin1:
.loc 1 7 0 @ main.cpp:7:0
.fnstart
.cfi_startproc
@ BB#0: @ %entry
.loc 1 0 0 @ main.cpp:0:0 <-------------- loc with line == 0 confuses the debugger
.pad #4
sub sp, sp, #4

Fast ISel removes this “.loc 1 0 0”, so the debugger successfully steps into the constructor due to the previous “.loc 1 7 0”.

Hi David,

It doesn’t reproduce on X86 due to the differences in emitPrologue for ARM and X86. While ARMFrameLowering::emitPrologue initializes debug location:
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
X86FrameLowering::emitPrologue leaves its default value:
DebugLoc DL;
ARMFrameLowering::emitPushInst has the same problem.
Leaving it unitialized looks like a hack.

Taking this into account, could you review if the r188651 patch is fully correct, please?

Thanks.