Michael137 created this revision.
Michael137 added reviewers: aprantl, dblaikie.
Herald added a project: All.
Michael137 requested review of this revision.
Herald added projects: clang, LLDB.
Herald added subscribers: lldb-commits, cfe-commits.

**Summary**

This patch makes debug-info generation aware of the
`[[clang::preferred_name]]` attribute. The attribute tells clang
to print the annotated class template as some typedef (e.g., in
diagnostics).

When printing a typename for emission into `DW_AT_name` this patch now
uses the preferred_name (if available). This is behind an LLDB tuning
because by default we try to avoid diverging GCC and Clang typename
format (which is why the `PrintingPolicy::UsePreferredNames` has
previously been disabled by default in `CGDebugInfo`).

**Motivation**

This will reduce noise in type summaries when showing variable
types in LLDB. E.g.,:

  (lldb) v
  (std::vector<std::basic_string<char> >) vec = size=0 {}

becomes

  (lldb) v
  (std::vector<std::string>) vec = size=0 {}

**Testing**

- Added Clang test
- Adjusted LLDB API tests


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D143501

Files:
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/test/CodeGen/debug-info-preferred-names.cpp
  
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py
  
lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py

Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
===================================================================
--- lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
+++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/unique_ptr/TestDataFormatterLibcxxUniquePtr.py
@@ -22,7 +22,7 @@
 
     def make_expected_basic_string_ptr(self) -> str:
         if self.expectedCompilerVersion(['>', '16.0']):
-            return f'std::unique_ptr<std::basic_string<char> >'
+            return f'std::unique_ptr<std::string>'
         else:
             return 'std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, ' \
                    'std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >'
Index: lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py
===================================================================
--- lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py
+++ lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py
@@ -59,13 +59,13 @@
         self.assertNotEqual(valobj.child[0].unsigned, 0)
 
         if self.expectedCompilerVersion(['>', '16.0']):
-            string_type = "std::basic_string<char>"
+            string_type = "std::string"
         else:
-            string_type = "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"
+            string_type = "std::basic_string<char, std::char_traits<char>, std::allocator<char> > "
 
         valobj = self.expect_var_path(
             "sp_str",
-            type="std::shared_ptr<" + string_type + " >",
+            type="std::shared_ptr<" + string_type + ">",
             children=[ValueCheck(name="__ptr_", summary='"hello"')],
         )
         self.assertRegex(valobj.summary, r'^"hello"( strong=1)? weak=1$')
Index: clang/test/CodeGen/debug-info-preferred-names.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/debug-info-preferred-names.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - -debugger-tuning=lldb | FileCheck --check-prefixes=COMMON,LLDB %s
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - -debugger-tuning=gdb | FileCheck --check-prefixes=COMMON,GDB %s
+
+template<typename T>
+class Qux {};
+
+template<typename T>
+struct Foo;
+
+template<typename T>
+using Bar = Foo<T>;
+
+template<typename T>
+struct [[clang::preferred_name(Bar<T>)]] Foo {};
+
+int main() {
+    /* Trivial cases */
+
+    Bar<int> b;
+// COMMON: !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<int>"
+
+    Foo<int> f1;
+// COMMON: !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<int>"
+
+    /* Alias template case */
+
+    Bar<Foo<int>> f2;
+// GDB:    !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<Foo<int> >"
+// LLDB:   !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<Bar<int> >"
+
+    /* Nested cases */
+
+    Foo<Foo<int>> f3; 
+// GDB:    !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<Foo<int> >"
+// LLDB:   !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<Bar<int> >"
+    
+    Qux<Foo<int>> f4;
+// GDB:    !DICompositeType(tag: DW_TAG_class_type, name: "Qux<Foo<int> >"
+// LLDB:   !DICompositeType(tag: DW_TAG_class_type, name: "Qux<Bar<int> >"
+
+    return 0;
+}
Index: clang/lib/CodeGen/CGDebugInfo.h
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.h
+++ clang/lib/CodeGen/CGDebugInfo.h
@@ -789,6 +789,11 @@
       std::memcpy(Data + A.size(), B.data(), B.size());
     return StringRef(Data, A.size() + B.size());
   }
+
+  /// Returns the QualType of the typedef that the PreferredNameAttr
+  /// of 'orig' refers to, if any such attribute exists. Returns 'orig'
+  /// otherwise.
+  QualType maybeGetPreferredNameType(QualType orig) const;
 };
 
 /// A scoped helper to set the current debug location to the specified
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -250,7 +250,7 @@
 
   PP.SuppressInlineNamespace = false;
   PP.PrintCanonicalTypes = true;
-  PP.UsePreferredNames = false;
+  PP.UsePreferredNames = CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB;
   PP.AlwaysIncludeTypeForTemplateArgument = true;
   PP.UseEnumerators = false;
 
@@ -2016,7 +2016,8 @@
 
     switch (TA.getKind()) {
     case TemplateArgument::Type: {
-      llvm::DIType *TTy = getOrCreateType(TA.getAsType(), Unit);
+      llvm::DIType *TTy =
+          getOrCreateType(maybeGetPreferredNameType(TA.getAsType()), Unit);
       TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
           TheCU, Name, TTy, defaultParameter));
 
@@ -2029,7 +2030,8 @@
     } break;
     case TemplateArgument::Declaration: {
       const ValueDecl *D = TA.getAsDecl();
-      QualType T = TA.getParamTypeForDecl().getDesugaredType(CGM.getContext());
+      QualType T = maybeGetPreferredNameType(
+          TA.getParamTypeForDecl().getDesugaredType(CGM.getContext()));
       llvm::DIType *TTy = getOrCreateType(T, Unit);
       llvm::Constant *V = nullptr;
       // Skip retrieve the value if that template parameter has cuda device
@@ -4461,7 +4463,7 @@
   if (VD->hasAttr<BlocksAttr>())
     Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset).WrappedType;
   else
-    Ty = getOrCreateType(VD->getType(), Unit);
+    Ty = getOrCreateType(maybeGetPreferredNameType(VD->getType()), Unit);
 
   // If there is no debug info for this type then do not emit debug info
   // for this variable.
@@ -5760,3 +5762,12 @@
 
   return llvm::DINode::FlagAllCallsDescribed;
 }
+
+QualType CGDebugInfo::maybeGetPreferredNameType(QualType orig) const {
+  if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
+    if (auto *RecordDecl = orig->getAsCXXRecordDecl())
+      if (auto *Attr = RecordDecl->getAttr<PreferredNameAttr>())
+        return Attr->getTypedefType();
+
+  return orig;
+}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to