Skip to content

[clang][DebugInfo] Revert to printing canonical typenames for template aliases #110767

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 2, 2024

Conversation

Michael137
Copy link
Member

@Michael137 Michael137 commented Oct 1, 2024

This was originally added in https://reviews.llvm.org/D142268 to have LLDB display variable typenames that benefit from suppressing defaulted template arguments.

We currently represent template aliases as DW_AT_typedefs instead of DW_TAG_template_alias. This means for types like:

template <class _Tp>
using __remove_cv_t = __remove_cv(_Tp);

template <class _Tp>
using remove_cv_t = __remove_cv_t<_Tp>;

template<typename T>
class optional {
  using value_type = T;
  remove_cv_t<value_type> __val_;
}

we would generate DWARF like:

0x0000274f:       DW_TAG_typedef
                    DW_AT_type  (0x0000000000002758 "__remove_cv_t<value_type>")
                    DW_AT_name  ("remove_cv_t<value_type>")

This is an actual libc++ type layout introduced in #110355, and uncovered a shortcoming of LLDB's data-formatter infrastructure, where we cache formatters on the contents of DW_AT_name (which currently wouldn't be a fully resolved typename for template specializations).

To unblock the libc++ change, I think we can revert this without much fallout.

Then we have two options for follow-up (or do both):

  1. reland this but adjust the LLDB formatter cache so it doesn't cache formatters for template specializations
  2. implement support for DW_TAG_template_alias in LLDB (and make Clang generate them by default).

…e aliases

This was originally added in https://reviews.llvm.org/D142268
have LLDB display variable typenames that benefit from suppressing
defaulted template arguments.

We currently represent template aliases as `DW_AT_typedef`s
instead of `DW_TAG_template_alias`. This means for types like:
```
template <class _Tp>
using __remove_cv_t = __remove_cv(_Tp);

template <class _Tp>
using remove_cv_t = __remove_cv_t<_Tp>;

template<typename T>
class optional {
  using value_type = T;
  remove_cv_t<value_type> __val_;
}
```
we would generate DWARF like:
```
0x0000274f:       DW_TAG_typedef
                    DW_AT_type  (0x0000000000002758 "__remove_cv_t<value_type>")
                    DW_AT_name  ("remove_cv_t<value_type>")

```

This is an actual libc++ type layout introduced in llvm#110355,
which uncovered a shortcoming of LLDB's data-formatter infrastructure,
which caches formatters on the contents of `DW_AT_name`.

To unblock the libc++ change, we can revert this without much fallout.

Then we have two options:
1. reland this but adjust the LLDB formatter cache so it doesn't
   cache formatters for template specializations
2. implement support for `DW_TAG_template_alias` in LLDB (and
   make Clang generate them by default).
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. debuginfo labels Oct 1, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 1, 2024

@llvm/pr-subscribers-debuginfo

@llvm/pr-subscribers-clang

Author: Michael Buch (Michael137)

Changes

This was originally added in https://reviews.llvm.org/D142268 have LLDB display variable typenames that benefit from suppressing defaulted template arguments.

We currently represent template aliases as DW_AT_typedefs instead of DW_TAG_template_alias. This means for types like:

template &lt;class _Tp&gt;
using __remove_cv_t = __remove_cv(_Tp);

template &lt;class _Tp&gt;
using remove_cv_t = __remove_cv_t&lt;_Tp&gt;;

template&lt;typename T&gt;
class optional {
  using value_type = T;
  remove_cv_t&lt;value_type&gt; __val_;
}

we would generate DWARF like:

0x0000274f:       DW_TAG_typedef
                    DW_AT_type  (0x0000000000002758 "__remove_cv_t&lt;value_type&gt;")
                    DW_AT_name  ("remove_cv_t&lt;value_type&gt;")

This is an actual libc++ type layout introduced in #110355, which uncovered a shortcoming of LLDB's data-formatter infrastructure, which caches formatters on the contents of DW_AT_name.

To unblock the libc++ change, I think we can revert this without much fallout.

Then we have two options for follow-up (or do both):

  1. reland this but adjust the LLDB formatter cache so it doesn't cache formatters for template specializations
  2. implement support for DW_TAG_template_alias in LLDB (and make Clang generate them by default).

Full diff: https://github.com/llvm/llvm-project/pull/110767.diff

2 Files Affected:

  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (-9)
  • (modified) clang/test/CodeGenCXX/debug-info-alias.cpp (+1-1)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 8887c4de7c4c81..609957b75d6e7e 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1472,15 +1472,6 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty,
     return AliasTy;
   }
 
-  // Disable PrintCanonicalTypes here because we want
-  // the DW_AT_name to benefit from the TypePrinter's ability
-  // to skip defaulted template arguments.
-  //
-  // FIXME: Once -gsimple-template-names is enabled by default
-  // and we attach template parameters to alias template DIEs
-  // we don't need to worry about customizing the PrintingPolicy
-  // here anymore.
-  PP.PrintCanonicalTypes = false;
   printTemplateArgumentList(OS, Ty->template_arguments(), PP,
                             TD->getTemplateParameters());
   return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(Loc),
diff --git a/clang/test/CodeGenCXX/debug-info-alias.cpp b/clang/test/CodeGenCXX/debug-info-alias.cpp
index bf2dbee4659592..3cd1446d25270e 100644
--- a/clang/test/CodeGenCXX/debug-info-alias.cpp
+++ b/clang/test/CodeGenCXX/debug-info-alias.cpp
@@ -24,7 +24,7 @@ x::bar<int> bi;
 // CHECK: [[BFLOAT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<float>"
 x::bar<float> bf;
 // CHECK: !DIGlobalVariable(name: "bz",{{.*}} type: [[BBAZ:![0-9]+]]
-// CHECK: [[BBAZ]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<baz<int> >"
+// CHECK: [[BBAZ]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<baz<int, int> >"
 x::bar<baz<int>> bz;
 
 using

@llvmbot
Copy link
Member

llvmbot commented Oct 1, 2024

@llvm/pr-subscribers-clang-codegen

Author: Michael Buch (Michael137)

Changes

This was originally added in https://reviews.llvm.org/D142268 have LLDB display variable typenames that benefit from suppressing defaulted template arguments.

We currently represent template aliases as DW_AT_typedefs instead of DW_TAG_template_alias. This means for types like:

template &lt;class _Tp&gt;
using __remove_cv_t = __remove_cv(_Tp);

template &lt;class _Tp&gt;
using remove_cv_t = __remove_cv_t&lt;_Tp&gt;;

template&lt;typename T&gt;
class optional {
  using value_type = T;
  remove_cv_t&lt;value_type&gt; __val_;
}

we would generate DWARF like:

0x0000274f:       DW_TAG_typedef
                    DW_AT_type  (0x0000000000002758 "__remove_cv_t&lt;value_type&gt;")
                    DW_AT_name  ("remove_cv_t&lt;value_type&gt;")

This is an actual libc++ type layout introduced in #110355, which uncovered a shortcoming of LLDB's data-formatter infrastructure, which caches formatters on the contents of DW_AT_name.

To unblock the libc++ change, I think we can revert this without much fallout.

Then we have two options for follow-up (or do both):

  1. reland this but adjust the LLDB formatter cache so it doesn't cache formatters for template specializations
  2. implement support for DW_TAG_template_alias in LLDB (and make Clang generate them by default).

Full diff: https://github.com/llvm/llvm-project/pull/110767.diff

2 Files Affected:

  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (-9)
  • (modified) clang/test/CodeGenCXX/debug-info-alias.cpp (+1-1)
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 8887c4de7c4c81..609957b75d6e7e 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1472,15 +1472,6 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty,
     return AliasTy;
   }
 
-  // Disable PrintCanonicalTypes here because we want
-  // the DW_AT_name to benefit from the TypePrinter's ability
-  // to skip defaulted template arguments.
-  //
-  // FIXME: Once -gsimple-template-names is enabled by default
-  // and we attach template parameters to alias template DIEs
-  // we don't need to worry about customizing the PrintingPolicy
-  // here anymore.
-  PP.PrintCanonicalTypes = false;
   printTemplateArgumentList(OS, Ty->template_arguments(), PP,
                             TD->getTemplateParameters());
   return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(Loc),
diff --git a/clang/test/CodeGenCXX/debug-info-alias.cpp b/clang/test/CodeGenCXX/debug-info-alias.cpp
index bf2dbee4659592..3cd1446d25270e 100644
--- a/clang/test/CodeGenCXX/debug-info-alias.cpp
+++ b/clang/test/CodeGenCXX/debug-info-alias.cpp
@@ -24,7 +24,7 @@ x::bar<int> bi;
 // CHECK: [[BFLOAT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<float>"
 x::bar<float> bf;
 // CHECK: !DIGlobalVariable(name: "bz",{{.*}} type: [[BBAZ:![0-9]+]]
-// CHECK: [[BBAZ]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<baz<int> >"
+// CHECK: [[BBAZ]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<baz<int, int> >"
 x::bar<baz<int>> bz;
 
 using

@Michael137
Copy link
Member Author

Test failures in Sema/aarch64-sve-vector-trig-ops.c unrelated

Copy link
Collaborator

@adrian-prantl adrian-prantl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds unfortunate, but if you think that's the best choice for unblocking libc++, let's do that.

@dwblaikie
Copy link
Collaborator

Not quite sure how we get to caching and template specializations and pretty printers.

If we're still producing the typedef-style DWARF for these alias template specializations - perhaps lldb could not cache pretty printers for typedefs? (I guess the pretty printers shouldn't be typedef-specific, right, since typedefs are transparent anyway - but I guess maybe pretty printers can be typedef-specific because typedefs can be intended to communicate what kind of a thing is and possibly how to render it?) - it'll cache teh pretty printer for the underlying type anyway, yeah?

@Michael137
Copy link
Member Author

If we're still producing the typedef-style DWARF for these alias template specializations - perhaps lldb could not cache pretty printers for typedefs? (I guess the pretty printers shouldn't be typedef-specific, right, since typedefs are transparent anyway - but I guess maybe pretty printers can be typedef-specific because typedefs can be intended to communicate what kind of a thing is and possibly how to render it?) - it'll cache teh pretty printer for the underlying type anyway, yeah?

Basically what was happening is that LLDB saw the new std::removecv_ref_t<value_type> member of std::optional, which resolved to std::string. Then formatted it as std::string. And then cached the DW_AT_name, i.e., std::removecv_ref_t<value_type>, to point to the std::string formatter. But that meant that the next time we saw a std::removecv_ref_t<value_type> (even if it didn't resolve to std::string) would use the cached formatter. The reason this patch works around that situation is that now the DW_AT_name will have the canonical type in DW_AT_name, not the unresolved std::removecv_ref_t<value_type>.

@jimingham will be able to speak more confidently about LLDB's intention here but I think caching typedefs is intentionally supported. Jim and I came to the conclusion yesterday that we probably don't want to cache template specializations.

I think we can (and should) fix the caching behaviour, but that would be a longer undertaking and I wanted to unblock the libc++ patch (#110355) as soon as possible.

It's on my list of follow-ups to reland this and fix the cache (and also investigate what it would take to support DW_TAG_template_alias in LLDB, so we can enable those by default).

@jimingham
Copy link
Collaborator

jimingham commented Oct 2, 2024 via email

@dwblaikie
Copy link
Collaborator

Thanks @jimingham - yeah, that makes sense. My original argument for being OK with the de-canonicalization of typedefs was that they aren't load bearing anyway. But if lldb puts load on them, that assumption doesn't hold.

Yeah, could check for angles or template parameter DIEs and cache typedef->prettyprinter only if none of those features appear.

@Michael137
Copy link
Member Author

Test failure unrelated. Will merge to unblock libc++ and investigate a path forward as a follow-up

@Michael137 Michael137 merged commit 52a9ba7 into llvm:main Oct 2, 2024
5 of 7 checks passed
@Michael137 Michael137 deleted the clang/template-alias-printing branch October 2, 2024 18:38
Sterling-Augustine pushed a commit to Sterling-Augustine/llvm-project that referenced this pull request Oct 3, 2024
…e aliases (llvm#110767)

This was originally added in https://reviews.llvm.org/D142268 to have
LLDB display variable typenames that benefit from suppressing defaulted
template arguments.

We currently represent template aliases as `DW_AT_typedef`s instead of
`DW_TAG_template_alias`. This means for types like:
```
template <class _Tp>
using __remove_cv_t = __remove_cv(_Tp);

template <class _Tp>
using remove_cv_t = __remove_cv_t<_Tp>;

template<typename T>
class optional {
  using value_type = T;
  remove_cv_t<value_type> __val_;
}
```
we would generate DWARF like:
```
0x0000274f:       DW_TAG_typedef
                    DW_AT_type  (0x0000000000002758 "__remove_cv_t<value_type>")
                    DW_AT_name  ("remove_cv_t<value_type>")

```

This is an actual libc++ type layout introduced in
llvm#110355, and uncovered a
shortcoming of LLDB's data-formatter infrastructure, where we cache
formatters on the contents of `DW_AT_name` (which currently wouldn't be
a fully resolved typename for template specializations).

To unblock the libc++ change, I think we can revert this without much
fallout.

Then we have two options for follow-up (or do both):
1. reland this but adjust the LLDB formatter cache so it doesn't cache
formatters for template specializations
2. implement support for `DW_TAG_template_alias` in LLDB (and make Clang
generate them by default).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category debuginfo
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants