From c9a39a896c95402ede07061380346c725556e308 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Tue, 21 Jan 2020 12:44:11 +0100 Subject: [PATCH] [lldb] Add a display name to ClangASTContext instances Summary: I often struggle to understand what exactly LLDB is doing by looking at our expression evaluation logging as our messages look like this: ``` CompleteTagDecl[2] on (ASTContext*)0x7ff31f01d240 Completing (TagDecl*)0x7ff31f01d568 named DeclName1 ``` From the log messages it's unclear what this ASTContext is. Is it the scratch context, the expression context, some decl vendor context or a context from a module? The pointer value isn't helpful for anyone unless I'm in a debugger where I could inspect the memory at the address. But even with a debugger it's not easy to figure out what this ASTContext is without having deeper understanding about all the different ASTContext instances in LLDB (e.g., valid SourceLocation from the file system usually means that this is the Objective-C decl vendor, a file name from multiple expressions is probably the scratch context, etc.). This patch adds a name field to ClangASTContext instances that we can use to store a name which can be used for logging and debugging. With this our log messages now look like this: ``` CompleteTagDecl[2] on scratch ASTContext. Completing (TagDecl*)0x7ff31f01d568 named Foo ``` We can now also just print a ClangASTContext from the debugger and see a useful name in the `m_display_name` field, e.g. ``` m_display_name = "AST for /Users/user/test/main.o"; ``` Reviewers: shafik, labath, JDevlieghere, mib Reviewed By: shafik Subscribers: clayborg, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D72391 --- lldb/include/lldb/Symbol/ClangASTContext.h | 15 +++- .../ExpressionParser/Clang/ClangASTSource.cpp | 97 ++++++++++++---------- .../Clang/ClangExpressionParser.cpp | 3 +- .../Clang/ClangModulesDeclVendor.cpp | 4 +- .../ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp | 7 +- .../AppleObjCTypeEncodingParser.cpp | 7 +- lldb/source/Symbol/ClangASTContext.cpp | 19 +++-- lldb/unittests/Symbol/TestClangASTContext.cpp | 13 ++- .../SymbolFile/DWARF/DWARFASTParserClangTests.cpp | 2 +- .../TestingSupport/Symbol/ClangTestUtils.h | 3 +- 10 files changed, 104 insertions(+), 66 deletions(-) diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h index 338417b..d59fee8 100644 --- a/lldb/include/lldb/Symbol/ClangASTContext.h +++ b/lldb/include/lldb/Symbol/ClangASTContext.h @@ -57,17 +57,20 @@ public: /// Constructs a ClangASTContext with an ASTContext using the given triple. /// + /// \param name The name for the ClangASTContext (for logging purposes) /// \param triple The llvm::Triple used for the ASTContext. The triple defines /// certain characteristics of the ASTContext and its types /// (e.g., whether certain primitive types exist or what their /// signedness is). - explicit ClangASTContext(llvm::Triple triple); + explicit ClangASTContext(llvm::StringRef name, llvm::Triple triple); /// Constructs a ClangASTContext that uses an existing ASTContext internally. /// Useful when having an existing ASTContext created by Clang. /// + /// \param name The name for the ClangASTContext (for logging purposes) /// \param existing_ctxt An existing ASTContext. - explicit ClangASTContext(clang::ASTContext &existing_ctxt); + explicit ClangASTContext(llvm::StringRef name, + clang::ASTContext &existing_ctxt); ~ClangASTContext() override; @@ -104,6 +107,10 @@ public: return llvm::dyn_cast(&type_system_or_err.get()); } + /// Returns the display name of this ClangASTContext that indicates what + /// purpose it serves in LLDB. Used for example in logs. + llvm::StringRef getDisplayName() const { return m_display_name; } + clang::ASTContext &getASTContext(); clang::MangleContext *getMangleContext(); @@ -947,6 +954,10 @@ private: std::unique_ptr m_mangle_ctx_up; uint32_t m_pointer_byte_size = 0; bool m_ast_owned = false; + /// A string describing what this ClangASTContext represents (e.g., + /// AST for debug information, an expression, some other utility ClangAST). + /// Useful for logging and debugging. + std::string m_display_name; typedef llvm::DenseMap DeclMetadataMap; /// Maps Decls to their associated ClangASTMetadata. diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index fed0e6e..d47113b 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -203,8 +203,8 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { LLDB_LOG(log, " CompleteTagDecl[{0}] on (ASTContext*){1} Completing " "(TagDecl*){2} named {3}", - current_id, static_cast(m_ast_context), - static_cast(tag_decl), tag_decl->getName()); + current_id, m_clang_ast_context->getDisplayName(), tag_decl, + tag_decl->getName()); LLDB_LOG(log, " CTD[%u] Before:\n{0}", current_id, ClangUtil::DumpDecl(tag_decl)); @@ -336,9 +336,10 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); LLDB_LOG(log, - " [CompleteObjCInterfaceDecl] on (ASTContext*){0} Completing " - "an ObjCInterfaceDecl named {1}", - m_ast_context, interface_decl->getName()); + " [CompleteObjCInterfaceDecl] on (ASTContext*){0} '{1}' " + "Completing an ObjCInterfaceDecl named {1}", + m_ast_context, m_clang_ast_context->getDisplayName(), + interface_decl->getName()); LLDB_LOG(log, " [COID] Before:\n{0}", ClangUtil::DumpDecl(interface_decl)); @@ -441,24 +442,25 @@ void ClangASTSource::FindExternalLexicalDecls( if (log) { if (const NamedDecl *context_named_decl = dyn_cast(context_decl)) LLDB_LOG(log, - "FindExternalLexicalDecls[{0}] on (ASTContext*){1} in '{2}' " - "(%sDecl*){3}", - current_id, static_cast(m_ast_context), + "FindExternalLexicalDecls[{0}] on (ASTContext*){1} '{2}' in " + "'{3}' (%sDecl*){4}", + current_id, m_ast_context, m_clang_ast_context->getDisplayName(), context_named_decl->getNameAsString().c_str(), context_decl->getDeclKindName(), static_cast(context_decl)); else if (context_decl) - LLDB_LOG( - log, - "FindExternalLexicalDecls[{0}] on (ASTContext*){1} in ({2}Decl*){3}", - current_id, static_cast(m_ast_context), - context_decl->getDeclKindName(), - static_cast(context_decl)); + LLDB_LOG(log, + "FindExternalLexicalDecls[{0}] on (ASTContext*){1} '{2}' in " + "({3}Decl*){4}", + current_id, m_ast_context, m_clang_ast_context->getDisplayName(), + context_decl->getDeclKindName(), + static_cast(context_decl)); else - LLDB_LOG( - log, - "FindExternalLexicalDecls[{0}] on (ASTContext*){1} in a NULL context", - current_id, static_cast(m_ast_context)); + LLDB_LOG(log, + "FindExternalLexicalDecls[{0}] on (ASTContext*){1} '{2}' in a " + "NULL context", + current_id, m_ast_context, + m_clang_ast_context->getDisplayName()); } ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(context_decl); @@ -466,10 +468,10 @@ void ClangASTSource::FindExternalLexicalDecls( if (!original.Valid()) return; - LLDB_LOG( - log, " FELD[{0}] Original decl (ASTContext*){1:x} (Decl*){2:x}:\n{3}", - current_id, static_cast(original.ctx), - static_cast(original.decl), ClangUtil::DumpDecl(original.decl)); + LLDB_LOG(log, " FELD[{0}] Original decl {1} (Decl*){2:x}:\n{3}", current_id, + static_cast(original.ctx), + static_cast(original.decl), + ClangUtil::DumpDecl(original.decl)); if (ObjCInterfaceDecl *original_iface_decl = dyn_cast(original.decl)) { @@ -563,20 +565,22 @@ void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { if (!context.m_decl_context) LLDB_LOG(log, "ClangASTSource::FindExternalVisibleDecls[{0}] on " - "(ASTContext*){1} for '{2}' in a NULL DeclContext", - current_id, m_ast_context, name); + "(ASTContext*){1} '{2}' for '{3}' in a NULL DeclContext", + current_id, m_ast_context, m_clang_ast_context->getDisplayName(), + name); else if (const NamedDecl *context_named_decl = dyn_cast(context.m_decl_context)) LLDB_LOG(log, "ClangASTSource::FindExternalVisibleDecls[{0}] on " - "(ASTContext*){1} for '{2}' in '{3}'", - current_id, m_ast_context, name, context_named_decl->getName()); + "(ASTContext*){1} '{2}' for '{3}' in '{4}'", + current_id, m_ast_context, m_clang_ast_context->getDisplayName(), + name, context_named_decl->getName()); else LLDB_LOG(log, "ClangASTSource::FindExternalVisibleDecls[{0}] on " - "(ASTContext*){1} for '{2}' in a '{3}'", - current_id, m_ast_context, name, - context.m_decl_context->getDeclKindName()); + "(ASTContext*){1} '{2}' for '{3}' in a '{4}'", + current_id, m_ast_context, m_clang_ast_context->getDisplayName(), + name, context.m_decl_context->getDeclKindName()); } context.m_namespace_map = std::make_shared(); @@ -1042,9 +1046,10 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { ConstString selector_name(ss.GetString()); LLDB_LOG(log, - "ClangASTSource::FindObjCMethodDecls[{0}] on (ASTContext*){1} " - "for selector [{2} {3}]", - current_id, m_ast_context, interface_decl->getName(), selector_name); + "ClangASTSource::FindObjCMethodDecls[{0}] on (ASTContext*){1} '{2}' " + "for selector [{3} {4}]", + current_id, m_ast_context, m_clang_ast_context->getDisplayName(), + interface_decl->getName(), selector_name); SymbolContextList sc_list; const bool include_symbols = false; @@ -1337,9 +1342,9 @@ void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { LLDB_LOG(log, "ClangASTSource::FindObjCPropertyAndIvarDecls[{0}] on " - "(ASTContext*){1} for '{2}.{3}'", - current_id, m_ast_context, parser_iface_decl->getName(), - context.m_decl_name.getAsString()); + "(ASTContext*){1} '{2}' for '{3}.{4}'", + current_id, m_ast_context, m_clang_ast_context->getDisplayName(), + parser_iface_decl->getName(), context.m_decl_name.getAsString()); if (FindObjCPropertyAndIvarDeclsWithOrigin( current_id, context, *this, origin_iface_decl)) @@ -1553,9 +1558,10 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); LLDB_LOG(log, - "LayoutRecordType[{0}] on (ASTContext*){1} for (RecordDecl*){2} " - "[name = '{3}']", - current_id, m_ast_context, record, record->getName()); + "LayoutRecordType[{0}] on (ASTContext*){1} '{2}' for (RecordDecl*)" + "{3} [name = '{4}']", + current_id, m_ast_context, m_clang_ast_context->getDisplayName(), + record, record->getName()); DeclFromParser parser_record(record); DeclFromUser origin_record( @@ -1676,15 +1682,16 @@ void ClangASTSource::CompleteNamespaceMap( if (log) { if (parent_map && parent_map->size()) LLDB_LOG(log, - "CompleteNamespaceMap[{0}] on (ASTContext*){1} Searching for " - "namespace {2} in namespace {3}", - current_id, m_ast_context, name, - parent_map->begin()->second.GetName()); + "CompleteNamespaceMap[{0}] on (ASTContext*){1} '{2}' Searching " + "for namespace {3} in namespace {4}", + current_id, m_ast_context, m_clang_ast_context->getDisplayName(), + name, parent_map->begin()->second.GetName()); else LLDB_LOG(log, - "CompleteNamespaceMap[{0}] on (ASTContext*){1} Searching for " - "namespace {2}", - current_id, m_ast_context, name); + "CompleteNamespaceMap[{0}] on (ASTContext*){1} '{2}' Searching " + "for namespace {3}", + current_id, m_ast_context, m_clang_ast_context->getDisplayName(), + name); } if (parent_map) { diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index 8dfdd76..92f3b79 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -606,7 +606,8 @@ ClangExpressionParser::ClangExpressionParser( m_compiler->createASTContext(); clang::ASTContext &ast_context = m_compiler->getASTContext(); - m_ast_context.reset(new ClangASTContext(ast_context)); + m_ast_context.reset(new ClangASTContext( + "Expression ASTContext for '" + m_filename + "'", ast_context)); std::string module_name("$__lldb_module"); diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp index 40bf740..f394265 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp @@ -160,7 +160,9 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl( m_parser(std::move(parser)) { // Initialize our ClangASTContext. - m_ast_context.reset(new ClangASTContext(m_compiler_instance->getASTContext())); + m_ast_context.reset( + new ClangASTContext("ClangModulesDeclVendor ASTContext", + m_compiler_instance->getASTContext())); } void ClangModulesDeclVendorImpl::ReportModuleExportsHelper( diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp index 7384306..3259dd0 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp @@ -143,10 +143,9 @@ private: AppleObjCDeclVendor::AppleObjCDeclVendor(ObjCLanguageRuntime &runtime) : ClangDeclVendor(eAppleObjCDeclVendor), m_runtime(runtime), - m_ast_ctx(runtime.GetProcess() - ->GetTarget() - .GetArchitecture() - .GetTriple()), + m_ast_ctx( + "AppleObjCDeclVendor AST", + runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple()), m_type_realizer_sp(m_runtime.GetEncodingToType()) { m_external_source = new AppleObjCExternalASTSource(*this); llvm::IntrusiveRefCntPtr external_source_owning_ptr( diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp index 66f04be..e12340c 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp @@ -23,10 +23,9 @@ AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser( ObjCLanguageRuntime &runtime) : ObjCLanguageRuntime::EncodingToType(), m_runtime(runtime) { if (!m_scratch_ast_ctx_up) - m_scratch_ast_ctx_up.reset(new ClangASTContext(runtime.GetProcess() - ->GetTarget() - .GetArchitecture() - .GetTriple())); + m_scratch_ast_ctx_up.reset(new ClangASTContext( + "AppleObjCTypeEncodingParser ASTContext", + runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple())); } std::string AppleObjCTypeEncodingParser::ReadStructName(StringLexer &type) { diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 6d2bf3a..b286cde 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -499,7 +499,9 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { Opts.NoInlineDefine = !Opt; } -ClangASTContext::ClangASTContext(llvm::Triple target_triple) { +ClangASTContext::ClangASTContext(llvm::StringRef name, + llvm::Triple target_triple) { + m_display_name = name.str(); if (!target_triple.str().empty()) SetTargetTriple(target_triple.str()); // The caller didn't pass an ASTContext so create a new one for this @@ -507,7 +509,9 @@ ClangASTContext::ClangASTContext(llvm::Triple target_triple) { CreateASTContext(); } -ClangASTContext::ClangASTContext(ASTContext &existing_ctxt) { +ClangASTContext::ClangASTContext(llvm::StringRef name, + ASTContext &existing_ctxt) { + m_display_name = name.str(); SetTargetTriple(existing_ctxt.getTargetInfo().getTriple().str()); m_ast_up.reset(&existing_ctxt); @@ -556,9 +560,11 @@ lldb::TypeSystemSP ClangASTContext::CreateInstance(lldb::LanguageType language, } } - if (module) - return std::make_shared(triple); - else if (target && target->IsValid()) + if (module) { + std::string ast_name = + "ASTContext for '" + module->GetFileSpec().GetPath() + "'"; + return std::make_shared(ast_name, triple); + } else if (target && target->IsValid()) return std::make_shared(*target, triple); return lldb::TypeSystemSP(); } @@ -9252,7 +9258,8 @@ ClangASTContext::DeclContextGetClangASTContext(const CompilerDeclContext &dc) { ClangASTContextForExpressions::ClangASTContextForExpressions( Target &target, llvm::Triple triple) - : ClangASTContext(triple), m_target_wp(target.shared_from_this()), + : ClangASTContext("scratch ASTContext", triple), + m_target_wp(target.shared_from_this()), m_persistent_variables(new ClangPersistentVariables) { m_scratch_ast_source_up.reset(new ClangASTSource( target.shared_from_this(), target.GetClangASTImporter())); diff --git a/lldb/unittests/Symbol/TestClangASTContext.cpp b/lldb/unittests/Symbol/TestClangASTContext.cpp index 653c9ce..1d9277d 100644 --- a/lldb/unittests/Symbol/TestClangASTContext.cpp +++ b/lldb/unittests/Symbol/TestClangASTContext.cpp @@ -26,7 +26,8 @@ public: SubsystemRAII subsystems; void SetUp() override { - m_ast.reset(new ClangASTContext(HostInfo::GetTargetTriple())); + m_ast.reset( + new ClangASTContext("test ASTContext", HostInfo::GetTargetTriple())); } void TearDown() override { m_ast.reset(); } @@ -220,6 +221,16 @@ TEST_F(TestClangASTContext, TestBuiltinTypeForEncodingAndBitSize) { VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 64); } +TEST_F(TestClangASTContext, TestDisplayName) { + ClangASTContext ast("some name", llvm::Triple()); + EXPECT_EQ("some name", ast.getDisplayName()); +} + +TEST_F(TestClangASTContext, TestDisplayNameEmpty) { + ClangASTContext ast("", llvm::Triple()); + EXPECT_EQ("", ast.getDisplayName()); +} + TEST_F(TestClangASTContext, TestIsClangType) { clang::ASTContext &context = m_ast->getASTContext(); lldb::opaque_compiler_type_t bool_ctype = diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp index 8f0368d..b681ae8 100644 --- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp @@ -39,7 +39,7 @@ public: // defining here, causing this test to fail, feel free to delete it. TEST_F(DWARFASTParserClangTests, EnsureAllDIEsInDeclContextHaveBeenParsedParsesOnlyMatchingEntries) { - ClangASTContext ast_ctx(HostInfoBase::GetTargetTriple()); + ClangASTContext ast_ctx("dummy ASTContext", HostInfoBase::GetTargetTriple()); DWARFASTParserClangStub ast_parser(ast_ctx); DWARFUnit *unit = nullptr; diff --git a/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h b/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h index 2c94aa5..5523b6f 100644 --- a/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h +++ b/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h @@ -22,7 +22,8 @@ inline clang::DeclarationName getDeclarationName(ClangASTContext &ast, } inline std::unique_ptr createAST() { - return std::make_unique(HostInfo::GetTargetTriple()); + return std::make_unique("test ASTContext", + HostInfo::GetTargetTriple()); } inline CompilerType createRecord(ClangASTContext &ast, llvm::StringRef name) { -- 2.7.4