From da121fff1184267a405f81a87f7314df2d474e1c Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 12 Nov 2020 11:33:36 +0100 Subject: [PATCH] [lldb] Introduce a LLDB printing policy for Clang type names that suppressed inline namespaces Commit 5f12f4ff9078455cad9d4806da01f570553a5bf9 made suppressing inline namespaces when printing typenames default to true. As we're using the inline namespaces in LLDB to construct internal type names (which need internal namespaces in them to, for example, differentiate libc++'s std::__1::string from the std::string from libstdc++), this broke most of the type formatting logic. --- .../Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 31 ++++++++++++++++------ .../Plugins/TypeSystem/Clang/TypeSystemClang.h | 7 +++++ .../libcxx/string/TestDataFormatterLibcxxString.py | 3 +++ 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 6a5c5cb..6e27386 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -1991,6 +1991,24 @@ TypeSystemClang::GetDeclarationName(llvm::StringRef name, return getASTContext().DeclarationNames.getCXXOperatorName(op_kind); } +PrintingPolicy TypeSystemClang::GetTypePrintingPolicy() { + clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy()); + printing_policy.SuppressTagKeyword = true; + // Inline namespaces are important for some type formatters (e.g., libc++ + // and libstdc++ are differentiated by their inline namespaces). + printing_policy.SuppressInlineNamespace = false; + printing_policy.SuppressUnwrittenScope = false; + return printing_policy; +} + +std::string TypeSystemClang::GetTypeNameForDecl(const NamedDecl *named_decl) { + clang::PrintingPolicy printing_policy = GetTypePrintingPolicy(); + std::string result; + llvm::raw_string_ostream os(result); + named_decl->printQualifiedName(os, printing_policy); + return result; +} + FunctionDecl *TypeSystemClang::CreateFunctionDeclaration( clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, llvm::StringRef name, const CompilerType &function_clang_type, @@ -3652,12 +3670,10 @@ ConstString TypeSystemClang::GetTypeName(lldb::opaque_compiler_type_t type) { // For a typedef just return the qualified name. if (const auto *typedef_type = qual_type->getAs()) { const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl(); - return ConstString(typedef_decl->getQualifiedNameAsString()); + return ConstString(GetTypeNameForDecl(typedef_decl)); } - clang::PrintingPolicy printing_policy(getASTContext().getPrintingPolicy()); - printing_policy.SuppressTagKeyword = true; - return ConstString(qual_type.getAsString(printing_policy)); + return ConstString(qual_type.getAsString(GetTypePrintingPolicy())); } ConstString @@ -3670,6 +3686,7 @@ TypeSystemClang::GetDisplayTypeName(lldb::opaque_compiler_type_t type) { printing_policy.SuppressTagKeyword = true; printing_policy.SuppressScope = false; printing_policy.SuppressUnwrittenScope = true; + printing_policy.SuppressInlineNamespace = true; return ConstString(qual_type.getAsString(printing_policy)); } @@ -8934,8 +8951,7 @@ void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type, if (level == eDescriptionLevelVerbose) typedef_decl->dump(llvm_ostrm); else { - std::string clang_typedef_name( - typedef_decl->getQualifiedNameAsString()); + std::string clang_typedef_name(GetTypeNameForDecl(typedef_decl)); if (!clang_typedef_name.empty()) { s->PutCString("typedef "); s->PutCString(clang_typedef_name); @@ -9412,8 +9428,7 @@ TypeSystemClang::DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) { clang::NamedDecl *named_decl = llvm::dyn_cast((clang::DeclContext *)opaque_decl_ctx); if (named_decl) - return ConstString( - llvm::StringRef(named_decl->getQualifiedNameAsString())); + return ConstString(GetTypeNameForDecl(named_decl)); } return ConstString(); } diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index 061e6cb..5eb492f 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -1063,6 +1063,13 @@ public: } private: + /// Returns the PrintingPolicy used when generating the internal type names. + /// These type names are mostly used for the formatter selection. + clang::PrintingPolicy GetTypePrintingPolicy(); + /// Returns the internal type name for the given NamedDecl using the + /// type printing policy. + std::string GetTypeNameForDecl(const clang::NamedDecl *named_decl); + const clang::ClassTemplateSpecializationDecl * GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type); diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py index 863e7bc..0f6d8a4 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py @@ -24,6 +24,9 @@ class LibcxxStringDataFormatterTestCase(TestBase): @add_test_categories(["libc++"]) @expectedFailureAll(bugnumber="llvm.org/pr36109", debug_info="gmodules", triple=".*-android") + # Inline namespace is randomly ignored as Clang due to broken lookup inside + # the std namespace. + @expectedFailureAll(debug_info="gmodules") def test_with_run_command(self): """Test that that file and class static variables display correctly.""" self.build() -- 2.7.4