[clang] [llvm] [Clang] Emit DW_TAG_template_alias for template aliases (PR #87623)

Orlando Cazalet-Hyams via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 17 06:20:08 PDT 2024


================
@@ -1332,6 +1332,54 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty,
   auto PP = getPrintingPolicy();
   Ty->getTemplateName().print(OS, PP, TemplateName::Qualified::None);
 
+  SourceLocation Loc = AliasDecl->getLocation();
+
+  if (CGM.getCodeGenOpts().DebugTemplateAlias) {
+    // TemplateSpecializationType doesn't know if its template args are
+    // being substituted into a parameter pack. We can find out if that's
+    // the case now by inspecting the TypeAliasTemplateDecl template
+    // parameters. Insert Ty's template args into SpecArgs, bundling args
+    // passed to a parameter pack into a TemplateArgument::Pack.
+    SmallVector<TemplateArgument> SpecArgs;
+    {
+      ArrayRef SubstArgs = Ty->template_arguments();
+      for (const NamedDecl *P : TD->getTemplateParameters()->asArray()) {
+        if (P->isParameterPack()) {
+          SpecArgs.push_back(TemplateArgument(SubstArgs));
+          break;
+        }
+        // Skip defaulted args.
+        if (SubstArgs.empty()) {
+          // If SubstArgs is now empty (we're taking from it each iteration) and
+          // this template parameter isn't a pack, then that should mean we're
+          // using default values for the remaining template parameters.
+          break;
----------------
OCHyams wrote:

> Does this mean we won't be emitting the defaulted template arguments as part of the DW_TAG_template_alias?

Yes. At the moment (without this patch, with typedefs) the names get constructed without the default values which is different behaviour to structs:
```
template<typename Y, int Z>
struct X {
  char n;
};

template<typename C = int, int D = 6>
using B = X<C, D>;

// DW_TAG_typedef
//   DW_AT_name      ("B<>")"
B<> a;

// DW_TAG_typedef
//   DW_AT_name      ("B<int>")
B<int> b;


template<typename G = int, int H = 0>
struct F {
  char n;
};

// DW_TAG_structure_type
//   DW_AT_name      ("F<int, 0>")
F<> f;
```
Using template parameters to reconstruct the name, without the default values, would result in the same names as the typedefs above create. That said,  it does feel slightly "incomplete" to leave them off. I'll have a look today to see whether its possible to do anything about that.

I'll add a test for default args either way, and move the code out into a function.


https://github.com/llvm/llvm-project/pull/87623


More information about the cfe-commits mailing list