In c++ coroutine, clang will emit different debug info variables for parameters and move-parameters.
The first one is the real parameters of the coroutine function, the other one just for copying parameters to the coroutine frame.
Considering the following c++ code:
struct coro { ... }; coro foo(struct test & t) { ... co_await suspend_always(); ... co_await suspend_always(); ... co_await suspend_always(); } int main(int argc, char *argv[]) { auto c = foo(...); c.handle.resume(); ... }
Function foo is the standard coroutine function, and it has only one parameter named t (ignoring this at first),
when we use the llvm code to compile this function, we can get the following ir:
!2921 = distinct !DISubprogram(name: "foo", linkageName: "_ZN6Object3fooE4test", scope: !2211, file: !45, li\ ne: 48, type: !2329, scopeLine: 48, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefi\ nition | DISPFlagOptimized, unit: !44, declaration: !2328, retainedNodes: !2922) !2924 = !DILocalVariable(name: "t", arg: 2, scope: !2921, file: !45, line: 48, type: !838) ... !2926 = !DILocalVariable(name: "t", scope: !2921, type: !838, flags: DIFlagArtificial)
We can find there are two the same DIVariable named t in the same dwarf scope for foo.resume.
And when we try to use llvm-dwarfdump to dump the dwarf info of this elf, we get the following output:
0x00006684: DW_TAG_subprogram DW_AT_low_pc (0x00000000004013a0) DW_AT_high_pc (0x00000000004013a8) DW_AT_frame_base (DW_OP_reg7 RSP) DW_AT_object_pointer (0x0000669c) DW_AT_GNU_all_call_sites (true) DW_AT_specification (0x00005b5c "_ZN6Object3fooE4test") 0x000066a5: DW_TAG_formal_parameter DW_AT_name ("t") DW_AT_decl_file ("/disk1/yifeng.dongyifeng/my_code/llvm/build/bin/coro-debug-1.cpp") DW_AT_decl_line (48) DW_AT_type (0x00004146 "test") 0x000066ba: DW_TAG_variable DW_AT_name ("t") DW_AT_type (0x00004146 "test") DW_AT_artificial (true)
The elf also has two 't' in the same scope.
But unluckily, it might let the debugger confused. And failed to print parameters for O0 or above.
This patch will make coroutine parameters and move parameters use the same DIVar and try to fix the problems that I mentioned before.
Test Plan:
check-clang
Nit: Per LLVM Coding style this should be formatted as:
// Create mapping between parameters and copy-params for coroutine function.