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