Skip to content

Commit 53b5c09

Browse files
authored
Merge pull request #11781 from swiftlang/lldb/module-error-handling-to-21.x
🍒[lldb][ClangModulesDeclVendor] Cherry-pick Clang modules error handling refactor
2 parents 40fd075 + e35b628 commit 53b5c09

19 files changed

+599
-128
lines changed

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks {
115115
ClangModulesDeclVendor &m_decl_vendor;
116116
ClangPersistentVariables &m_persistent_vars;
117117
clang::SourceManager &m_source_mgr;
118+
/// Accumulates error messages across all moduleImport calls.
118119
StreamString m_error_stream;
119120
bool m_has_errors = false;
120121

@@ -140,11 +141,12 @@ class ClangExpressionParser::LLDBPreprocessorCallbacks : public PPCallbacks {
140141
module.path.push_back(
141142
ConstString(component.getIdentifierInfo()->getName()));
142143

143-
StreamString error_stream;
144-
145144
ClangModulesDeclVendor::ModuleVector exported_modules;
146-
if (!m_decl_vendor.AddModule(module, &exported_modules, m_error_stream))
145+
if (auto err = m_decl_vendor.AddModule(module, &exported_modules)) {
147146
m_has_errors = true;
147+
m_error_stream.PutCString(llvm::toString(std::move(err)));
148+
m_error_stream.PutChar('\n');
149+
}
148150

149151
for (ClangModulesDeclVendor::ModuleID module : exported_modules)
150152
m_persistent_vars.AddHandLoadedClangModule(module);

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -383,10 +383,11 @@ bool ClangExpressionSourceCode::GetText(
383383
block->CalculateSymbolContext(&sc);
384384

385385
if (sc.comp_unit) {
386-
StreamString error_stream;
387-
388-
decl_vendor->AddModulesForCompileUnit(
389-
*sc.comp_unit, modules_for_macros, error_stream);
386+
if (auto err = decl_vendor->AddModulesForCompileUnit(
387+
*sc.comp_unit, modules_for_macros))
388+
LLDB_LOG_ERROR(
389+
GetLog(LLDBLog::Expressions), std::move(err),
390+
"Error while loading hand-imported modules:\n{0}");
390391
}
391392
}
392393
}

lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp

Lines changed: 56 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {
9292

9393
~ClangModulesDeclVendorImpl() override = default;
9494

95-
bool AddModule(const SourceModule &module, ModuleVector *exported_modules,
96-
Stream &error_stream) override;
95+
llvm::Error AddModule(const SourceModule &module,
96+
ModuleVector *exported_modules) override;
9797

98-
bool AddModulesForCompileUnit(CompileUnit &cu, ModuleVector &exported_modules,
99-
Stream &error_stream) override;
98+
llvm::Error AddModulesForCompileUnit(CompileUnit &cu,
99+
ModuleVector &exported_modules) override;
100100

101101
uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches,
102102
std::vector<CompilerDecl> &decls) override;
@@ -273,16 +273,14 @@ void ClangModulesDeclVendorImpl::ReportModuleExports(
273273
exports.push_back(module);
274274
}
275275

276-
bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
277-
ModuleVector *exported_modules,
278-
Stream &error_stream) {
276+
llvm::Error
277+
ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
278+
ModuleVector *exported_modules) {
279279
// Fail early.
280280

281-
if (m_compiler_instance->hadModuleLoaderFatalFailure()) {
282-
error_stream.PutCString("error: Couldn't load a module because the module "
283-
"loader is in a fatal state.\n");
284-
return false;
285-
}
281+
if (m_compiler_instance->hadModuleLoaderFatalFailure())
282+
return llvm::createStringError(
283+
"couldn't load a module because the module loader is in a fatal state");
286284

287285
// Check if we've already imported this module.
288286

@@ -297,7 +295,7 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
297295
if (mi != m_imported_modules.end()) {
298296
if (exported_modules)
299297
ReportModuleExports(*exported_modules, mi->second);
300-
return true;
298+
return llvm::Error::success();
301299
}
302300
}
303301

@@ -315,30 +313,30 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
315313
std::equal(sysroot_begin, sysroot_end, path_begin);
316314
// No need to inject search paths to modules in the sysroot.
317315
if (!is_system_module) {
318-
auto error = [&]() {
319-
error_stream.Printf("error: No module map file in %s\n",
320-
module.search_path.AsCString());
321-
return false;
322-
};
323-
324316
bool is_system = true;
325317
bool is_framework = false;
326318
auto dir = HS.getFileMgr().getOptionalDirectoryRef(
327319
module.search_path.GetStringRef());
328320
if (!dir)
329-
return error();
321+
return llvm::createStringError(
322+
"couldn't find module search path directory %s",
323+
module.search_path.GetCString());
324+
330325
auto file = HS.lookupModuleMapFile(*dir, is_framework);
331326
if (!file)
332-
return error();
327+
return llvm::createStringError("couldn't find modulemap file in %s",
328+
module.search_path.GetCString());
329+
333330
if (HS.loadModuleMapFile(*file, is_system))
334-
return error();
331+
return llvm::createStringError(
332+
"failed to parse and load modulemap file in %s",
333+
module.search_path.GetCString());
335334
}
336335
}
337-
if (!HS.lookupModule(module.path.front().GetStringRef())) {
338-
error_stream.Printf("error: Header search couldn't locate module '%s'\n",
339-
module.path.front().AsCString());
340-
return false;
341-
}
336+
337+
if (!HS.lookupModule(module.path.front().GetStringRef()))
338+
return llvm::createStringError("header search couldn't locate module '%s'",
339+
module.path.front().AsCString());
342340

343341
llvm::SmallVector<clang::IdentifierLoc, 4> clang_path;
344342

@@ -364,22 +362,29 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
364362
clang::Module *top_level_module = DoGetModule(clang_path.front(), false);
365363

366364
if (!top_level_module) {
365+
lldb_private::StreamString error_stream;
367366
diagnostic_consumer->DumpDiagnostics(error_stream);
368-
error_stream.Printf("error: Couldn't load top-level module %s\n",
369-
module.path.front().AsCString());
370-
return false;
367+
368+
return llvm::createStringError(llvm::formatv(
369+
"couldn't load top-level module {0}:\n{1}",
370+
module.path.front().GetStringRef(), error_stream.GetString()));
371371
}
372372

373373
clang::Module *submodule = top_level_module;
374374

375375
for (auto &component : llvm::ArrayRef<ConstString>(module.path).drop_front()) {
376-
submodule = submodule->findSubmodule(component.GetStringRef());
377-
if (!submodule) {
376+
clang::Module *found = submodule->findSubmodule(component.GetStringRef());
377+
if (!found) {
378+
lldb_private::StreamString error_stream;
378379
diagnostic_consumer->DumpDiagnostics(error_stream);
379-
error_stream.Printf("error: Couldn't load submodule %s\n",
380-
component.GetCString());
381-
return false;
380+
381+
return llvm::createStringError(llvm::formatv(
382+
"couldn't load submodule '{0}' of module '{1}':\n{2}",
383+
component.GetStringRef(), submodule->getFullModuleName(),
384+
error_stream.GetString()));
382385
}
386+
387+
submodule = found;
383388
}
384389

385390
// If we didn't make the submodule visible here, Clang wouldn't allow LLDB to
@@ -399,10 +404,12 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
399404

400405
m_enabled = true;
401406

402-
return true;
407+
return llvm::Error::success();
403408
}
404409

405-
return false;
410+
return llvm::createStringError(
411+
llvm::formatv("unknown error while loading module {0}\n",
412+
module.path.front().GetStringRef()));
406413
}
407414

408415
bool ClangModulesDeclVendor::LanguageSupportsClangModules(
@@ -424,15 +431,18 @@ bool ClangModulesDeclVendor::LanguageSupportsClangModules(
424431
}
425432
}
426433

427-
bool ClangModulesDeclVendorImpl::AddModulesForCompileUnit(
428-
CompileUnit &cu, ClangModulesDeclVendor::ModuleVector &exported_modules,
429-
Stream &error_stream) {
430-
if (LanguageSupportsClangModules(cu.GetLanguage())) {
431-
for (auto &imported_module : cu.GetImportedModules())
432-
if (!AddModule(imported_module, &exported_modules, error_stream))
433-
return false;
434-
}
435-
return true;
434+
llvm::Error ClangModulesDeclVendorImpl::AddModulesForCompileUnit(
435+
CompileUnit &cu, ClangModulesDeclVendor::ModuleVector &exported_modules) {
436+
if (!LanguageSupportsClangModules(cu.GetLanguage()))
437+
return llvm::Error::success();
438+
439+
llvm::Error errors = llvm::Error::success();
440+
441+
for (auto &imported_module : cu.GetImportedModules())
442+
if (auto err = AddModule(imported_module, &exported_modules))
443+
errors = llvm::joinErrors(std::move(errors), std::move(err));
444+
445+
return errors;
436446
}
437447

438448
// ClangImporter::lookupValue

lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,44 +42,34 @@ class ClangModulesDeclVendor : public ClangDeclVendor {
4242
/// The path to the exact module to be loaded. E.g., if the desired
4343
/// module is std.io, then this should be { "std", "io" }.
4444
///
45-
/// \param[in] exported_modules
45+
/// \param[out] exported_modules
4646
/// If non-NULL, a pointer to a vector to populate with the ID of every
4747
/// module that is re-exported by the specified module.
4848
///
49-
/// \param[in] error_stream
50-
/// A stream to populate with the output of the Clang parser when
51-
/// it tries to load the module.
52-
///
5349
/// \return
5450
/// True if the module could be loaded; false if not. If the
5551
/// compiler encountered a fatal error during a previous module
5652
/// load, then this will always return false for this ModuleImporter.
57-
virtual bool AddModule(const SourceModule &module,
58-
ModuleVector *exported_modules,
59-
Stream &error_stream) = 0;
53+
virtual llvm::Error AddModule(const SourceModule &module,
54+
ModuleVector *exported_modules) = 0;
6055

6156
/// Add all modules referred to in a given compilation unit to the list
6257
/// of modules to search.
6358
///
6459
/// \param[in] cu
6560
/// The compilation unit to scan for imported modules.
6661
///
67-
/// \param[in] exported_modules
62+
/// \param[out] exported_modules
6863
/// A vector to populate with the ID of each module loaded (directly
6964
/// and via re-exports) in this way.
7065
///
71-
/// \param[in] error_stream
72-
/// A stream to populate with the output of the Clang parser when
73-
/// it tries to load the modules.
74-
///
7566
/// \return
7667
/// True if all modules referred to by the compilation unit could be
7768
/// loaded; false if one could not be loaded. If the compiler
7869
/// encountered a fatal error during a previous module
7970
/// load, then this will always return false for this ModuleImporter.
80-
virtual bool AddModulesForCompileUnit(CompileUnit &cu,
81-
ModuleVector &exported_modules,
82-
Stream &error_stream) = 0;
71+
virtual llvm::Error
72+
AddModulesForCompileUnit(CompileUnit &cu, ModuleVector &exported_modules) = 0;
8373

8474
/// Enumerate all the macros that are defined by a given set of modules
8575
/// that are already imported.

lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -371,26 +371,20 @@ static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target,
371371

372372
if (!sc.comp_unit)
373373
return;
374-
StreamString error_stream;
375-
376374
ClangModulesDeclVendor::ModuleVector modules_for_macros =
377375
persistent_state->GetHandLoadedClangModules();
378-
if (decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros,
379-
error_stream))
380-
return;
381376

382-
// Failed to load some modules, so emit the error stream as a diagnostic.
383-
if (!error_stream.Empty()) {
384-
// The error stream already contains several Clang diagnostics that might
385-
// be either errors or warnings, so just print them all as one remark
386-
// diagnostic to prevent that the message starts with "error: error:".
387-
diagnostic_manager.PutString(lldb::eSeverityInfo, error_stream.GetString());
377+
auto err =
378+
decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros);
379+
if (!err)
388380
return;
389-
}
390381

391-
diagnostic_manager.PutString(lldb::eSeverityError,
392-
"Unknown error while loading modules needed for "
393-
"current compilation unit.");
382+
// Module load errors aren't fatal to the expression evaluator. Printing
383+
// them as diagnostics to the console would be too noisy and misleading
384+
// Hence just print them to the expression log.
385+
llvm::handleAllErrors(std::move(err), [](const llvm::StringError &e) {
386+
LLDB_LOG(GetLog(LLDBLog::Expressions), "{0}", e.getMessage());
387+
});
394388
}
395389

396390
ClangExpressionSourceCode::WrapKind ClangUserExpression::GetWrapKind() const {

lldb/test/API/lang/objc/modules-compile-error/Makefile

Lines changed: 0 additions & 5 deletions
This file was deleted.

lldb/test/API/lang/objc/modules-compile-error/TestModulesCompileError.py

Lines changed: 0 additions & 28 deletions
This file was deleted.

lldb/test/API/lang/objc/modules-compile-error/main.m

Lines changed: 0 additions & 5 deletions
This file was deleted.

lldb/test/API/lang/objc/modules-compile-error/module.h

Lines changed: 0 additions & 5 deletions
This file was deleted.

lldb/test/API/lang/objc/modules-compile-error/module.modulemap

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)