[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
Fri Apr 12 11:06:15 PDT 2024


================
@@ -5361,7 +5383,56 @@ static bool IsReconstitutableType(QualType QT) {
   return T.Reconstitutable;
 }
 
-std::string CGDebugInfo::GetName(const Decl *D, bool Qualified) const {
+bool CGDebugInfo::HasReconstitutableArgs(
+    ArrayRef<TemplateArgument> Args) const {
+  return llvm::all_of(Args, [&](const TemplateArgument &TA) {
+    switch (TA.getKind()) {
+    case TemplateArgument::Template:
+      // Easy to reconstitute - the value of the parameter in the debug
+      // info is the string name of the template. (so the template name
+      // itself won't benefit from any name rebuilding, but that's a
+      // representational limitation - maybe DWARF could be
+      // changed/improved to use some more structural representation)
+      return true;
+    case TemplateArgument::Declaration:
+      // Reference and pointer non-type template parameters point to
+      // variables, functions, etc and their value is, at best (for
+      // variables) represented as an address - not a reference to the
+      // DWARF describing the variable/function/etc. This makes it hard,
+      // possibly impossible to rebuild the original name - looking up
+      // the address in the executable file's symbol table would be
+      // needed.
+      return false;
+    case TemplateArgument::NullPtr:
+      // These could be rebuilt, but figured they're close enough to the
+      // declaration case, and not worth rebuilding.
+      return false;
+    case TemplateArgument::Pack:
+      // A pack is invalid if any of the elements of the pack are
+      // invalid.
+      return HasReconstitutableArgs(TA.getPackAsArray());
+    case TemplateArgument::Integral:
+      // Larger integers get encoded as DWARF blocks which are a bit
+      // harder to parse back into a large integer, etc - so punting on
+      // this for now. Re-parsing the integers back into APInt is
+      // probably feasible some day.
+      return TA.getAsIntegral().getBitWidth() <= 64 &&
+             IsReconstitutableType(TA.getIntegralType());
+    case TemplateArgument::StructuralValue:
+      return false;
+    case TemplateArgument::Type:
+      return IsReconstitutableType(TA.getAsType());
+    case TemplateArgument::Expression:
+      return IsReconstitutableType(TA.getAsExpr()->getType());
+    default:
+      llvm_unreachable("Other, unresolved, template arguments should "
+                       "not be seen here");
+    }
+  });
+}
+
+std::string CGDebugInfo::GetName(const Decl *D, bool Qualified,
+                                 const Type *Ty) const {
----------------
OCHyams wrote:

Aha, good catch. You're correct on both counts - it's not used in this patch and that was one of the approaches I tried out.

This is discussed a bit on the issue starting here https://github.com/llvm/llvm-project/issues/54624#issuecomment-2024754144.

IIRC, we _could_ pass in the `TemplateSpecializationType` to get the template arguments for this case, but I think we'd need to introduce a special case for building the name where we can't use `D`'s  `getNameForDiagnostic` on line 5461 and 5481 of the original file.

My memory is slightly blurred by the conference - I think I was erring on the side of caution given my unfamiliarity with the code, preferring to have a special case localised at the usage site rather than inside a utility function. I'd be happy to change the patch to use the `TemplateSpecializationType` parameter if you'd like to see what it looks like?




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


More information about the cfe-commits mailing list