This revision was automatically updated to reflect the committed changes. Closed by commit rGd48ef7cab558: [lldb] Print full Clang diagnostics when the ClangModulesDeclVendor fails to… (authored by teemperor). Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
Changed prior to commit: https://reviews.llvm.org/D79947?vs=263928&id=264179#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D79947/new/ https://reviews.llvm.org/D79947 Files: lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp lldb/test/API/lang/objc/modules-compile-error/Makefile lldb/test/API/lang/objc/modules-compile-error/TestModulesCompileError.py lldb/test/API/lang/objc/modules-compile-error/main.m lldb/test/API/lang/objc/modules-compile-error/module.h lldb/test/API/lang/objc/modules-compile-error/module.modulemap
Index: lldb/test/API/lang/objc/modules-compile-error/module.modulemap =================================================================== --- /dev/null +++ lldb/test/API/lang/objc/modules-compile-error/module.modulemap @@ -0,0 +1 @@ +module LLDBTestModule { header "module.h" export * } Index: lldb/test/API/lang/objc/modules-compile-error/module.h =================================================================== --- /dev/null +++ lldb/test/API/lang/objc/modules-compile-error/module.h @@ -0,0 +1,5 @@ +int foo() { return 123; } + +#ifndef ONLY_CLANG +syntax_error_for_lldb_to_find // comment that tests source printing +#endif Index: lldb/test/API/lang/objc/modules-compile-error/main.m =================================================================== --- /dev/null +++ lldb/test/API/lang/objc/modules-compile-error/main.m @@ -0,0 +1,5 @@ +@import LLDBTestModule; + +int main() { + return foo(); // break here +} Index: lldb/test/API/lang/objc/modules-compile-error/TestModulesCompileError.py =================================================================== --- /dev/null +++ lldb/test/API/lang/objc/modules-compile-error/TestModulesCompileError.py @@ -0,0 +1,23 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + def test(self): + self.build() + lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.m")) + + # Try importing our custom module. This will fail as LLDB won't define + # the CLANG_ONLY define when it compiles the module for the expression + # evaluator. + # Check that the error message shows file/line/column, prints the relevant + # line from the source code and mentions the module that failed to build. + self.expect("expr @import LLDBTestModule", error=True, + substrs=["module.h:4:1: error: unknown type name 'syntax_error_for_lldb_to_find'", + "syntax_error_for_lldb_to_find // comment that tests source printing", + "could not build module 'LLDBTestModule'"]) Index: lldb/test/API/lang/objc/modules-compile-error/Makefile =================================================================== --- /dev/null +++ lldb/test/API/lang/objc/modules-compile-error/Makefile @@ -0,0 +1,5 @@ +OBJC_SOURCES := main.m + +CFLAGS_EXTRAS = $(MANDATORY_MODULE_BUILD_CFLAGS) -I$(BUILDDIR) -DONLY_CLANG=1 + +include Makefile.rules Index: lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -347,7 +347,8 @@ return true; } -static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) { +static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target, + DiagnosticManager &diagnostic_manager) { ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor(); if (!decl_vendor) return; @@ -377,8 +378,23 @@ ClangModulesDeclVendor::ModuleVector modules_for_macros = persistent_state->GetHandLoadedClangModules(); - decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, - error_stream); + if (decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, + error_stream)) + return; + + // Failed to load some modules, so emit the error stream as a diagnostic. + if (!error_stream.Empty()) { + // The error stream already contains several Clang diagnostics that might + // be either errors or warnings, so just print them all as one remark + // diagnostic to prevent that the message starts with "error: error:". + diagnostic_manager.PutString(eDiagnosticSeverityRemark, + error_stream.GetString()); + return; + } + + diagnostic_manager.PutString(eDiagnosticSeverityError, + "Unknown error while loading modules needed for " + "current compilation unit."); } void ClangUserExpression::UpdateLanguageForExpr() { @@ -530,7 +546,7 @@ ApplyObjcCastHack(m_expr_text); - SetupDeclVendor(exe_ctx, m_target); + SetupDeclVendor(exe_ctx, m_target, diagnostic_manager); CppModuleConfiguration module_config = GetModuleConfig(m_language, exe_ctx); llvm::ArrayRef<std::string> imported_modules = Index: lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp @@ -11,6 +11,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendActions.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" #include "clang/Parse/Parser.h" @@ -54,10 +55,21 @@ void DumpDiagnostics(Stream &error_stream); + void BeginSourceFile(const clang::LangOptions &LangOpts, + const clang::Preprocessor *PP = nullptr) override; + void EndSourceFile() override; + private: typedef std::pair<clang::DiagnosticsEngine::Level, std::string> IDAndDiagnostic; std::vector<IDAndDiagnostic> m_diagnostics; + /// The DiagnosticPrinter used for creating the full diagnostic messages + /// that are stored in m_diagnostics. + std::shared_ptr<clang::TextDiagnosticPrinter> m_diag_printer; + /// Output stream of m_diag_printer. + std::shared_ptr<llvm::raw_string_ostream> m_os; + /// Output string filled by m_os. Will be reused for different diagnostics. + std::string m_output; Log *m_log; }; @@ -116,17 +128,21 @@ StoringDiagnosticConsumer::StoringDiagnosticConsumer() { m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + + clang::DiagnosticOptions *m_options = new clang::DiagnosticOptions(); + m_os.reset(new llvm::raw_string_ostream(m_output)); + m_diag_printer.reset(new clang::TextDiagnosticPrinter(*m_os, m_options)); } void StoringDiagnosticConsumer::HandleDiagnostic( clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) { - llvm::SmallVector<char, 256> diagnostic_string; + // Print the diagnostic to m_output. + m_output.clear(); + m_diag_printer->HandleDiagnostic(DiagLevel, info); + m_os->flush(); - info.FormatDiagnostic(diagnostic_string); - - m_diagnostics.push_back( - IDAndDiagnostic(DiagLevel, std::string(diagnostic_string.data(), - diagnostic_string.size()))); + // Store the diagnostic for later. + m_diagnostics.push_back(IDAndDiagnostic(DiagLevel, m_output)); } void StoringDiagnosticConsumer::ClearDiagnostics() { m_diagnostics.clear(); } @@ -144,6 +160,15 @@ } } +void StoringDiagnosticConsumer::BeginSourceFile( + const clang::LangOptions &LangOpts, const clang::Preprocessor *PP) { + m_diag_printer->BeginSourceFile(LangOpts, PP); +} + +void StoringDiagnosticConsumer::EndSourceFile() { + m_diag_printer->EndSourceFile(); +} + ClangModulesDeclVendor::ClangModulesDeclVendor() : ClangDeclVendor(eClangModuleDeclVendor) {}
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits