Skip to content

Commit 2892eef

Browse files
authored
[lldb] Fallback to implicit modules when explicit modules are missing (#8356) (#8427)
Handle the case where an explicit module path does not exist, by falling back to implicit modules. The initial logic is: If any one explicit module is nonexistent, then remove all references to explicit modules. Additionally, remove all explicit module maps. (cherry-picked from commit 2abff47)
1 parent 725ddc7 commit 2892eef

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,15 @@
5757
#include "clang/Driver/Driver.h"
5858

5959
#include "llvm/ADT/ArrayRef.h"
60+
#include "llvm/ADT/STLExtras.h"
6061
#include "llvm/ADT/StringRef.h"
6162
#include "llvm/ADT/StringSet.h"
6263
#include "llvm/CodeGen/TargetSubtargetInfo.h"
6364
#include "llvm/IR/DataLayout.h"
6465
#include "llvm/IR/LLVMContext.h"
6566
#include "llvm/IR/Module.h"
6667
#include "llvm/MC/TargetRegistry.h"
68+
#include "llvm/Support/FileSystem.h"
6769
#include "llvm/Support/MemoryBuffer.h"
6870
#include "llvm/Support/Path.h"
6971
#include "llvm/Support/TargetSelect.h"
@@ -1595,9 +1597,50 @@ void SwiftASTContext::AddExtraClangArgs(const std::vector<std::string> &source,
15951597
}
15961598
}
15971599

1600+
namespace {
1601+
1602+
bool HasNonexistentExplicitModule(const std::vector<std::string> &args) {
1603+
for (const std::string &arg : args) {
1604+
StringRef value = arg;
1605+
if (!value.consume_front("-fmodule-file="))
1606+
continue;
1607+
StringRef path = value;
1608+
size_t eq = value.find('=');
1609+
// The value that follows is in one of two formats:
1610+
// 1. ModuleName=ModulePath
1611+
// 2. ModulePath
1612+
if (eq != std::string::npos)
1613+
// The value appears to be in ModuleName=ModulePath forat.
1614+
path = value.drop_front(eq + 1);
1615+
// Check both path and value. This is to handle paths containing '='.
1616+
if (!llvm::sys::fs::exists(path) && !llvm::sys::fs::exists(value)) {
1617+
std::string m_description;
1618+
HEALTH_LOG_PRINTF("Nonexistent explicit module file %s", arg.data());
1619+
return true;
1620+
}
1621+
}
1622+
return false;
1623+
}
1624+
1625+
void RemoveExplicitModules(std::vector<std::string> &args) {
1626+
llvm::erase_if(args, [](const std::string &arg) {
1627+
if (arg == "-fno-implicit-modules" || arg == "-fno-implicit-module-maps")
1628+
return true;
1629+
StringRef s = arg;
1630+
if (s.starts_with("-fmodule-file=") || s.starts_with("-fmodule-map-file="))
1631+
return true;
1632+
1633+
return false;
1634+
});
1635+
}
1636+
1637+
} // namespace
1638+
15981639
void SwiftASTContext::AddExtraClangArgs(const std::vector<std::string> &ExtraArgs) {
15991640
swift::ClangImporterOptions &importer_options = GetClangImporterOptions();
16001641
AddExtraClangArgs(ExtraArgs, importer_options.ExtraArgs);
1642+
if (HasNonexistentExplicitModule(importer_options.ExtraArgs))
1643+
RemoveExplicitModules(importer_options.ExtraArgs);
16011644
}
16021645

16031646
void SwiftASTContext::AddUserClangArgs(TargetProperties &props) {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SWIFT_SOURCES := main.swift
2+
SWIFT_ENABLE_EXPLICIT_MODULES := YES
3+
USE_PRIVATE_MODULE_CACHE := YES
4+
include Makefile.rules
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import shutil
2+
import lldb
3+
from lldbsuite.test.decorators import *
4+
import lldbsuite.test.lldbtest as lldbtest
5+
import lldbsuite.test.lldbutil as lldbutil
6+
7+
8+
class TestCase(lldbtest.TestBase):
9+
@swiftTest
10+
@skipIf(oslist=["linux"], bugnumber="rdar://124691219")
11+
def test_missing_explicit_modules(self):
12+
"""Test missing explicit Swift modules and fallback to implicit modules."""
13+
self.build()
14+
15+
# This test verifies the case where explicit modules are missing.
16+
# Remove explicit modules from their place in the module cache.
17+
mod_cache = self.getBuildArtifact("private-module-cache")
18+
shutil.rmtree(mod_cache)
19+
20+
lldbutil.run_to_source_breakpoint(
21+
self, "Set breakpoint here", lldb.SBFileSpec("main.swift")
22+
)
23+
24+
log = self.getBuildArtifact("types.log")
25+
self.runCmd(f"log enable lldb types -f '{log}'")
26+
27+
self.expect("expression c", substrs=["hello implicit fallback"])
28+
29+
self.filecheck(f"platform shell cat {log}", __file__)
30+
# CHECK: Nonexistent explicit module file
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Class {
2+
var msg : String = "hello implicit fallback"
3+
}
4+
5+
func main() {
6+
let c = Class()
7+
print(c) // Set breakpoint here
8+
}
9+
10+
main()

0 commit comments

Comments
 (0)