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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits