Michael137 created this revision.
Michael137 added a reviewer: aprantl.
Herald added a project: All.
Michael137 added a comment.
Michael137 updated this revision to Diff 504274.
Michael137 updated this revision to Diff 504276.
Michael137 edited the summary of this revision.
Michael137 added a reviewer: dblaikie.
Michael137 published this revision for review.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Yet another alternative for emitting preferred_names.

Makes the attribute introduced in https://reviews.llvm.org/D145077 redundant. 
Also doesn't require any changes to LLDB (making 
https://reviews.llvm.org/D145078 redundant, which got a bit hairy)


aprantl added a comment.

This seems to be a much simpler implementation that just automatically works. I 
think I'd prefer that over adding new DWARF attributes.


Michael137 added a comment.

- Add test


Michael137 added a comment.

- Update commit message


[clang][DebugInfo] Emit DW_AT_type of preferred name if available

With this patch, whenever we emit a `DW_AT_type` for some declaration
and the type is a template class with a `clang::PreferredNameAttr`, we
will emit the typedef that the attribute refers to instead. I.e.,

  0x123 DW_TAG_variable
  DW_AT_name "var"
  DW_AT_type (0x123 "basic_string<char>")
  
  0x124 DW_TAG_structure_type
  DW_AT_name "basic_string<char>"

...becomes

  0x123 DW_TAG_variable
  DW_AT_name "var"
  DW_AT_type (0x124 "std::string")
  
  0x124 DW_TAG_structure_type
  DW_AT_name "basic_string<char>"
  
  0x125 DW_TAG_typedef
  DW_AT_name "std::string"
  DW_AT_type (0x124 "basic_string<char>")

For now we keep this behind LLDB tuning.

**Testing**

- Added clang unit-test
- `check-llvm`, `check-clang` pass
- Confirmed that this change correctly repoints

`basic_string` references in some of my test programs.

- Will add follow-up LLDB API tests


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145803

Files:
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/test/CodeGen/preferred_name.cpp

Index: clang/test/CodeGen/preferred_name.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/preferred_name.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=standalone -debugger-tuning=lldb %s | FileCheck %s --check-prefixes=COMMON,LLDB
+// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=standalone -debugger-tuning=gdb %s | FileCheck %s --check-prefixes=COMMON,GDB
+
+template <typename T>
+struct Foo;
+
+typedef Foo<int> BarInt;
+typedef Foo<double> BarDouble;
+
+template <typename T>
+using Bar = Foo<T>;
+
+template <typename T>
+struct [[clang::preferred_name(BarInt),
+         clang::preferred_name(BarDouble),
+         clang::preferred_name(Bar<short>),
+         clang::preferred_name(Bar<char>)]] Foo{
+         };
+
+int main() {
+    Foo<int> varInt;
+
+// COMMON: !DILocalVariable(name: "varInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_INT_TY:[0-9]+]])
+// LLDB:   ![[BAR_INT_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarInt", file: ![[#]], line: [[#]], baseType: ![[BAR_INT_BASE:[0-9]+]])
+// LLDB:   ![[BAR_INT_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<int>", file: ![[#]], line: [[#]], size: [[#]]
+// GDB:    ![[BAR_INT_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<int>", file: ![[#]], line: [[#]], size: [[#]]
+
+    Foo<double> varDouble;
+
+// COMMON: !DILocalVariable(name: "varDouble", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_DOUBLE_TY:[0-9]+]])
+// LLDB:   ![[BAR_DOUBLE_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarDouble", file: ![[#]], line: [[#]], baseType: ![[BAR_DOUBLE_BASE:[0-9]+]])
+// LLDB:   ![[BAR_DOUBLE_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<double>"
+// GDB:    ![[BAR_DOUBLE_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<double>"
+
+    Foo<short> varShort;
+
+// COMMON: !DILocalVariable(name: "varShort", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_SHORT_TY:[0-9]+]])
+// LLDB:   ![[BAR_SHORT_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<short>", file: ![[#]], line: [[#]], baseType: ![[BAR_SHORT_BASE:[0-9]+]])
+// LLDB:   ![[BAR_SHORT_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<short>"
+// GDB:    ![[BAR_SHORT_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<short>"
+
+    Foo<char> varChar;
+
+// COMMON: !DILocalVariable(name: "varChar", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_CHAR_TY:[0-9]+]])
+// LLDB:   ![[BAR_CHAR_TY]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<char>", file: ![[#]], line: [[#]], baseType: ![[BAR_CHAR_BASE:[0-9]+]])
+// LLDB:   ![[BAR_CHAR_BASE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<char>"
+// GDB:    ![[BAR_CHAR_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<char>"
+
+    Foo<Foo<int>> varFooInt;
+
+// COMMON: !DILocalVariable(name: "varFooInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_FOO_INT_TY:[0-9]+]])
+// COMMON: ![[BAR_FOO_INT_TY]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo<Foo<int> >"
+
+    BarInt barInt;
+
+// LLDB:   !DILocalVariable(name: "barInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_INT_TY]])
+// GDB:    !DILocalVariable(name: "barInt", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_INT_TYPEDEF:[0-9]+]])
+// GDB:    ![[BAR_INT_TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarInt"
+
+    BarDouble barDouble;
+
+// LLDB:   !DILocalVariable(name: "barDouble", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_DOUBLE_TY]])
+// GDB:    !DILocalVariable(name: "barDouble", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_DOUBLE_TYPEDEF:[0-9]+]])
+// GDB:    ![[BAR_DOUBLE_TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "BarDouble"
+
+    Bar<short> barShort;
+
+// LLDB:   !DILocalVariable(name: "barShort", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_SHORT_TY_2:[0-9]+]])
+// GDB:    !DILocalVariable(name: "barShort", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_SHORT_TYPEDEF:[0-9]+]])
+// GDB:    ![[BAR_SHORT_TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<short>"
+
+    Bar<char> barChar;
+
+// LLDB:   ![[BAR_SHORT_TY_2]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<short>", file: ![[#]], line: [[#]], baseType: ![[BAR_SHORT_TY]])
+
+// LLDB:   !DILocalVariable(name: "barChar", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_CHAR_TY_2:[0-9]+]])
+// GDB:    !DILocalVariable(name: "barChar", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[BAR_CHAR_TYPEDEF:[0-9]+]])
+// GDB:    ![[BAR_CHAR_TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<char>"
+
+// LLDB:   ![[BAR_CHAR_TY_2]] = !DIDerivedType(tag: DW_TAG_typedef, name: "Bar<char>", file: ![[#]], line: [[#]], baseType: ![[BAR_CHAR_TY]])
+
+    return 0;
+}
+
+
Index: clang/lib/CodeGen/CGDebugInfo.h
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.h
+++ clang/lib/CodeGen/CGDebugInfo.h
@@ -276,6 +276,12 @@
       llvm::DenseSet<CanonicalDeclPtr<const CXXRecordDecl>> &SeenTypes,
       llvm::DINode::DIFlags StartingFlags);
 
+  /// Helper class that retrieves returns llvm::DIType the that
+  /// PreferredNameAttr attribute on \ref RD refers to. If no such
+  /// attribute exists, returns nullptr.
+  llvm::DIType *GetPreferredNameType(const CXXRecordDecl *RD,
+                                     llvm::DIFile *Unit);
+
   struct TemplateArgs {
     const TemplateParameterList *TList;
     llvm::ArrayRef<TemplateArgument> Args;
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2602,6 +2602,18 @@
   return CreateTypeDefinition(Ty);
 }
 
+llvm::DIType *CGDebugInfo::GetPreferredNameType(const CXXRecordDecl *RD,
+                                                llvm::DIFile *Unit) {
+  if (!RD)
+    return nullptr;
+
+  auto const *PNA = RD->getAttr<PreferredNameAttr>();
+  if (!PNA)
+    return nullptr;
+
+  return getOrCreateType(PNA->getTypedefType(), Unit);
+}
+
 llvm::DIType *CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
   RecordDecl *RD = Ty->getDecl();
 
@@ -2657,6 +2669,11 @@
         llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
 
   RegionMap[Ty->getDecl()].reset(FwdDecl);
+
+  if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
+    if (auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
+      return PrefDI;
+
   return FwdDecl;
 }
 
@@ -3685,7 +3702,7 @@
 void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD,
                                         llvm::DICompositeType *RealDecl) {
   // A class's primary base or the class itself contains the vtable.
-  llvm::DICompositeType *ContainingType = nullptr;
+  llvm::DIType *ContainingType = nullptr;
   const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
   if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {
     // Seek non-virtual primary base root.
@@ -3697,9 +3714,8 @@
       else
         break;
     }
-    ContainingType = cast<llvm::DICompositeType>(
-        getOrCreateType(QualType(PBase->getTypeForDecl(), 0),
-                        getOrCreateFile(RD->getLocation())));
+    ContainingType = getOrCreateType(QualType(PBase->getTypeForDecl(), 0),
+                                     getOrCreateFile(RD->getLocation()));
   } else if (RD->isDynamicClass())
     ContainingType = RealDecl;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to