Michael137 added a comment.

In D131335#3712243 <https://reviews.llvm.org/D131335#3712243>, @labath wrote:

> In D131335#3710236 <https://reviews.llvm.org/D131335#3710236>, @Michael137 
> wrote:
>
>> In D131335#3709788 <https://reviews.llvm.org/D131335#3709788>, @labath wrote:
>>
>>> I haven't been able to keep up with all the lldb happenings lately, so it's 
>>> possible I have missed something, but can you give a summary (or point me 
>>> to one) of what is the problem with abi tags in lldb. For example, why 
>>> isn't the DW_AT_linkage_name string sufficient to find the correct function?
>>>
>>> I am somewhat sceptical that this is the best way to fix this problem. As 
>>> you've said yourself, the "alternate name" machinery is a last resort, and 
>>> the things that it's doing are wrong on several levels (and quite slow). To 
>>> tell the truth, I've been hoping that we could get rid of it completely one 
>>> day. Relying on this mechanism for "core" functionality would preclude that 
>>> from happening...
>>
>> Unqualified lookup of template functions currently always resorts this 
>> "fall-back" mechanism. I investigated this mainly with `import-std-module` 
>> enabled since those were the tests that failed due to D127444 
>> <https://reviews.llvm.org/D127444>. There are two parts to it:
>>
>> 1. During unqualified lookup `clang::Sema` asks LLDB for the decl 
>> corresponding to the template in question. `DWARFASTParserClang` adds two 
>> decls to the AST, one non-template `FunctionDecl` marked `extern` and 
>> another `TemplateFunctionDecl`. Because of unqualified lookup rules in C++ 
>> `clang::Sema` picks the extern FunctionDecl. This is why the generated IR 
>> has an unresolved symbol that we then try to find in the object files.
>>
>> 2. When resolving this external symbol we try to match mangled function 
>> names using the hand-rolled `CPlusPlusNameParser` which doesn't support ABI 
>> tags and we fail to find a suitable symbol.
>>
>> We can fish out the ABI tag from the `DW_AT_linkage_name` when parsing DWARF 
>> but we would still fail at (2). The plan was to address both. First reduce 
>> the reliance on `CPlusPlusNameParser` since that fixes the unqualified 
>> lookup issue trivially and is more robust to C++ syntax changes/attribute 
>> additions/etc. And then address the unqualified template lookup which has 
>> had numerous workarounds added to it over the years 
>> (https://reviews.llvm.org/D33025, 
>>  https://reviews.llvm.org/D61044, https://reviews.llvm.org/D75761, etc.)
>
> Thanks for the explanation. I have to admit I am surprised that this is 
> motivated by the `import-std-module` feature. That's the last place I would 
> expect, as my understanding was that this is basically about providing a 
> fully faithful AST representation (of the module) -- by having clang compile 
> itself rather than us trying to roundtrip it through dwarf.
>
> From your description, it sounds to me like things go wrong right at the 
> start -- with the two AST Decls. Do you understand why is that happening? I 
> pretty sure I am missing something, but I can't escape the feeling that this 
> could be solved by generating a "better" AST. I know that isn't always 
> possible, but it's not clear to me why it is not be possible **in this case**.
>
> The way I understand it, for regular (non-templated) functions we are 
> generating an AST roughly corresponding to `extern void foo(int) 
> asm("mangled_name");`. That means we tell clang precisely the mangled name it 
> should use (the one we get from dwarf), and nobody will care whether it 
> contains an abi tag or anything else. Could we do the same for templated 
> functions as well? `extern template void foo<int>() asm("whatever");` doesn't 
> appear to be entirely valid syntax (gcc rejects it outright, while clang just 
> ignores <https://godbolt.org/z/zKcE5vfEP> the `asm` part, but maybe it 
> wouldn't be too hard to change that (we wouldn't actually need to accept that 
> source code, just a way to express something similar in the AST)?
>
> Would something like that help here? Or am I just completely in the dark?
>
> (BTW, I really like the ability to do AST-based processing (comparisons) of 
> mangled names. That seems like it could be very useful in some situations -- 
> it's just not clear to me why this is one of them.)

Thanks for taking a closer look. I'm revisiting the AST construction for 
template functions again and seeing some discrepancies in the structure of the 
AST generated by Clang's `-ast-dump` vs LLDB. We're not only dropping the ABI 
tags from the mangled name but also the template arguments. That's because the 
decl that `clang::Sema` finds during lookup looks like the following:

  // main.cpp
  
  namespace A {
  struct B {};
  template <typename T> [[gnu::abi_tag("vTest")]] bool tagged(T t) { return 
true; }
  
  int main() { bool res = tagged(A::B{}); }



  ...
  FunctionDecl 0x11910ffd0 <<invalid sloc>> <invalid sloc> used tagged 'bool 
(A::B)' extern
  |-ParmVarDecl 0x11910ff68 <<invalid sloc>> <invalid sloc> t 'A::B'

It seems like the `FunctionTemplateDecl` we create in `DWARFASTParserClang` 
doesn't actually get attached to the AST properly. E.g., we never call 
`addDecl` on it. I'm not sure if that's by design, but that is one of the 
discrepancies; it has pretty much stayed this way since support for template 
functions was first introduced in 3c2e3ae49093a4f5e0660c96932d83f6d81bd798.

This lack of a `FunctionTemplateDecl` is reflected again when emitting the 
`$__lldb_result_expr` IR via `CodeGen::EmitDirectCall` (which is the component 
that emits the "incorrectly" mangled function call).

- `-ast-dump` yields the following

  ...
      |         |-ImplicitCastExpr 0x13311c548 <col:28> 'bool (*)(A::B)' 
<FunctionToPointerDecay>                                                        
                               
      |         | `-DeclRefExpr 0x13311c4c0 <col:28> 'bool (A::B)' lvalue 
Function 0x13311a130 'tagged' 'bool (A::B)' (FunctionTemplate 0x1331166c8 
'tagged')      
  ...



- while LLDB's AST looks like:

  ...
      |-ImplicitCastExpr 0x119110208 '_Bool (*)(struct A::B)' 
<FunctionToPointerDecay>
      | `-DeclRefExpr 0x1191101c0 '_Bool (struct A::B)' lvalue Function 
0x11910ffd0 'tagged' '_Bool (struct A::B)'
  ...

Note how the `DeclRefExpr` node doesn't have a `FunctionTemplate` attached to 
it in LLDB's AST.

I'll have to see if there's something wrong with how 
`TypeSystemClang::CreateFunctionTemplateDecl` is used


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131335/new/

https://reviews.llvm.org/D131335

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to