Index: lldb/trunk/include/lldb/Symbol/ClangASTContext.h =================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTContext.h +++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h @@ -194,9 +194,10 @@ uint32_t GetPointerByteSize() override; - static clang::DeclContext *GetTranslationUnitDecl(clang::ASTContext *ast); + static clang::TranslationUnitDecl * + GetTranslationUnitDecl(clang::ASTContext *ast); - clang::DeclContext *GetTranslationUnitDecl() { + clang::TranslationUnitDecl *GetTranslationUnitDecl() { return GetTranslationUnitDecl(getASTContext()); } @@ -926,6 +927,8 @@ //---------------------------------------------------------------------- // Dumping types //---------------------------------------------------------------------- + void Dump(Stream &s); + void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, Index: lldb/trunk/include/lldb/Symbol/SymbolFile.h =================================================================== --- lldb/trunk/include/lldb/Symbol/SymbolFile.h +++ lldb/trunk/include/lldb/Symbol/SymbolFile.h @@ -161,6 +161,8 @@ uint32_t line, bool check_inlines, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list); + + virtual void DumpClangAST(Stream &s) {} virtual uint32_t FindGlobalVariables(const ConstString &name, const CompilerDeclContext *parent_decl_ctx, Index: lldb/trunk/source/Commands/CommandObjectTarget.cpp =================================================================== --- lldb/trunk/source/Commands/CommandObjectTarget.cpp +++ lldb/trunk/source/Commands/CommandObjectTarget.cpp @@ -2227,6 +2227,85 @@ } }; +#pragma mark CommandObjectTargetModulesDumpSections + +//---------------------------------------------------------------------- +// Clang AST dumping command +//---------------------------------------------------------------------- + +class CommandObjectTargetModulesDumpClangAST + : public CommandObjectTargetModulesModuleAutoComplete { +public: + CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter) + : CommandObjectTargetModulesModuleAutoComplete( + interpreter, "target modules dump ast", + "Dump the clang ast for a given module's symbol file.", + //"target modules dump ast [ ...]") + nullptr) {} + + ~CommandObjectTargetModulesDumpClangAST() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (target == nullptr) { + result.AppendError("invalid target, create a debug target using the " + "'target create' command"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + const size_t num_modules = target->GetImages().GetSize(); + if (num_modules == 0) { + result.AppendError("the target has no associated executable images"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + if (command.GetArgumentCount() == 0) { + // Dump all ASTs for all modules images + result.GetOutputStream().Printf("Dumping clang ast for %" PRIu64 + " modules.\n", + (uint64_t)num_modules); + for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { + if (m_interpreter.WasInterrupted()) + break; + Module *m = target->GetImages().GetModulePointerAtIndex(image_idx); + SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile(); + sf->DumpClangAST(result.GetOutputStream()); + } + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + + // Dump specified ASTs (by basename or fullpath) + for (const Args::ArgEntry &arg : command.entries()) { + ModuleList module_list; + const size_t num_matches = + FindModulesByName(target, arg.c_str(), module_list, true); + if (num_matches == 0) { + // Check the global list + std::lock_guard guard( + Module::GetAllocationModuleCollectionMutex()); + + result.AppendWarningWithFormat( + "Unable to find an image that matches '%s'.\n", arg.c_str()); + continue; + } + + for (size_t i = 0; i < num_matches; ++i) { + if (m_interpreter.WasInterrupted()) + break; + Module *m = module_list.GetModulePointerAtIndex(i); + SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile(); + sf->DumpClangAST(result.GetOutputStream()); + } + } + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } +}; + #pragma mark CommandObjectTargetModulesDumpSymfile //---------------------------------------------------------------------- @@ -2402,12 +2481,13 @@ // Constructors and Destructors //------------------------------------------------------------------ CommandObjectTargetModulesDump(CommandInterpreter &interpreter) - : CommandObjectMultiword(interpreter, "target modules dump", - "Commands for dumping information about one or " - "more target modules.", - "target modules dump " - "[headers|symtab|sections|symfile|line-table] " - "[ ...]") { + : CommandObjectMultiword( + interpreter, "target modules dump", + "Commands for dumping information about one or " + "more target modules.", + "target modules dump " + "[headers|symtab|sections|ast|symfile|line-table] " + "[ ...]") { LoadSubCommand("objfile", CommandObjectSP( new CommandObjectTargetModulesDumpObjfile(interpreter))); @@ -2420,6 +2500,9 @@ LoadSubCommand("symfile", CommandObjectSP( new CommandObjectTargetModulesDumpSymfile(interpreter))); + LoadSubCommand( + "ast", CommandObjectSP( + new CommandObjectTargetModulesDumpClangAST(interpreter))); LoadSubCommand("line-table", CommandObjectSP(new CommandObjectTargetModulesDumpLineTable( interpreter))); Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -329,6 +329,8 @@ void Dump(lldb_private::Stream &s) override; + void DumpClangAST(lldb_private::Stream &s) override; + protected: typedef llvm::DenseMap DIEToTypePtr; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3854,6 +3854,14 @@ void SymbolFileDWARF::Dump(lldb_private::Stream &s) { m_index->Dump(s); } +void SymbolFileDWARF::DumpClangAST(Stream &s) { + TypeSystem *ts = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); + ClangASTContext *clang = llvm::dyn_cast_or_null(ts); + if (!clang) + return; + clang->Dump(s); +} + SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired()) { lldb::ModuleSP module_sp(m_debug_map_module_wp.lock()); Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -126,6 +126,8 @@ std::vector ParseCallEdgesInFunction(lldb_private::UserID func_id) override; + void DumpClangAST(lldb_private::Stream &s) override; + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -1227,6 +1227,13 @@ return matching_namespace; } +void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) { + ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) -> bool { + oso_dwarf->DumpClangAST(s); + return true; + }); +} + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ Index: lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -155,6 +155,8 @@ ClangASTContext &GetASTContext() { return *m_clang; } ClangASTImporter &GetASTImporter() { return *m_importer; } + void DumpClangAST(Stream &s) override; + private: size_t FindTypesByName(llvm::StringRef name, uint32_t max_matches, TypeMap &types); Index: lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1391,6 +1391,12 @@ return 0; } +void SymbolFileNativePDB::DumpClangAST(Stream &s) { + if (!m_clang) + return; + m_clang->Dump(s); +} + uint32_t SymbolFileNativePDB::FindGlobalVariables( const ConstString &name, const CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, VariableList &variables) { Index: lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ lldb/trunk/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -967,7 +967,7 @@ return child_context; // Split context and retrieve nested namespaces - auto curr_context = m_ast.GetTranslationUnitDecl(); + clang::DeclContext *curr_context = m_ast.GetTranslationUnitDecl(); std::string::size_type from = 0; while (from < context_size) { auto to = context.find("::", from); Index: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -169,6 +169,8 @@ const llvm::pdb::IPDBSession &GetPDBSession() const; + void DumpClangAST(lldb_private::Stream &s) override; + private: struct SecContribInfo { uint32_t Offset; Index: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1356,6 +1356,14 @@ return types.GetSize(); } +void SymbolFilePDB::DumpClangAST(Stream &s) { + auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); + auto clang = llvm::dyn_cast_or_null(type_system); + if (!clang) + return; + clang->Dump(s); +} + void SymbolFilePDB::FindTypesByRegex( const lldb_private::RegularExpression ®ex, uint32_t max_matches, lldb_private::TypeMap &types) { Index: lldb/trunk/source/Symbol/ClangASTContext.cpp =================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp +++ lldb/trunk/source/Symbol/ClangASTContext.cpp @@ -1285,7 +1285,7 @@ return CompilerType(ast, ast->getPointerType(char_type)); } -clang::DeclContext * +clang::TranslationUnitDecl * ClangASTContext::GetTranslationUnitDecl(clang::ASTContext *ast) { return ast->getTranslationUnitDecl(); } @@ -8965,6 +8965,11 @@ //---------------------------------------------------------------------- #define DEPTH_INCREMENT 2 +void ClangASTContext::Dump(Stream &s) { + TranslationUnitDecl *tu = GetTranslationUnitDecl(); + tu->dump(s.AsRawOstream()); +} + void ClangASTContext::DumpValue( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format, const DataExtractor &data,