Skip to content

Commit 82453cf

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-next
2 parents 518bbb3 + c05d4bf commit 82453cf

File tree

9 files changed

+177
-8
lines changed

9 files changed

+177
-8
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,14 @@ ERROR(previous_installname_map_corrupted,none,
251251
"previous install name map from %0 is malformed",
252252
(StringRef))
253253

254+
ERROR(explicit_swift_module_map_missing,none,
255+
"cannot open explicit Swift module map from %0",
256+
(StringRef))
257+
258+
ERROR(explicit_swift_module_map_corrupted,none,
259+
"explicit Swift module map from %0 is malformed",
260+
(StringRef))
261+
254262
REMARK(default_previous_install_name, none,
255263
"default previous install name for %0 is %1", (StringRef, StringRef))
256264

include/swift/AST/SearchPathOptions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ class SearchPathOptions {
8585
/// The paths to a set of explicitly built modules from interfaces.
8686
std::vector<std::string> ExplicitSwiftModules;
8787

88+
/// A map of explict Swift module information.
89+
std::string ExplicitSwiftModuleMap;
8890
private:
8991
static StringRef
9092
pathStringFromFrameworkSearchPath(const FrameworkSearchPath &next) {

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase {
150150
create(ASTContext &ctx,
151151
DependencyTracker *tracker, ModuleLoadingMode loadMode,
152152
ArrayRef<std::string> ExplicitModulePaths,
153+
StringRef ExplicitSwiftModuleMap,
153154
bool IgnoreSwiftSourceInfoFile);
154155

155156
/// Append visible module names to \p names. Note that names are possibly

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ def disable_implicit_swift_modules: Flag<["-"], "disable-implicit-swift-modules"
220220
def swift_module_file
221221
: Separate<["-"], "swift-module-file">, MetaVarName<"<path>">,
222222
HelpText<"Specify Swift module explicitly built from textual interface">;
223+
224+
def explict_swift_module_map
225+
: Separate<["-"], "explicit-swift-module-map-file">, MetaVarName<"<path>">,
226+
HelpText<"Specify a JSON file containing information of explict Swift modules">;
223227
}
224228

225229

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,8 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts,
872872
for (auto A: Args.filtered(OPT_swift_module_file)) {
873873
Opts.ExplicitSwiftModules.push_back(resolveSearchPath(A->getValue()));
874874
}
875+
if (const Arg *A = Args.getLastArg(OPT_explict_swift_module_map))
876+
Opts.ExplicitSwiftModuleMap = A->getValue();
875877
// Opts.RuntimeIncludePath is set by calls to
876878
// setRuntimeIncludePath() or setMainExecutablePath().
877879
// Opts.RuntimeImportPath is set by calls to

lib/Frontend/Frontend.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ bool CompilerInstance::setUpModuleLoaders() {
457457
*Context,
458458
getDependencyTracker(), MLM,
459459
Invocation.getSearchPathOptions().ExplicitSwiftModules,
460+
Invocation.getSearchPathOptions().ExplicitSwiftModuleMap,
460461
IgnoreSourceInfoFile);
461462
Context->addModuleLoader(std::move(ESML));
462463
}

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 132 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "llvm/Support/Path.h"
3737
#include "llvm/Support/Errc.h"
3838
#include "llvm/Support/YAMLTraits.h"
39+
#include "llvm/Support/YAMLParser.h"
3940
#include "ModuleInterfaceBuilder.h"
4041

4142
using namespace swift;
@@ -1218,6 +1219,15 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
12181219
GenericArgs.push_back("-swift-module-file");
12191220
GenericArgs.push_back(ArgSaver.save(EM));
12201221
}
1222+
// Pass down -explicit-swift-module-map-file
1223+
// FIXME: we shouldn't need this. Remove it?
1224+
StringRef explictSwiftModuleMap = searchPathOpts.ExplicitSwiftModuleMap;
1225+
subInvocation.getSearchPathOptions().ExplicitSwiftModuleMap =
1226+
explictSwiftModuleMap;
1227+
if (!explictSwiftModuleMap.empty()) {
1228+
GenericArgs.push_back("-explicit-swift-module-map-file");
1229+
GenericArgs.push_back(explictSwiftModuleMap);
1230+
}
12211231
if (clangImporter) {
12221232
// We need to add these extra clang flags because explict module building
12231233
// related flags are all there: -fno-implicit-modules, -fmodule-map-file=,
@@ -1418,14 +1428,99 @@ bool InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleN
14181428
}
14191429

14201430
struct ExplicitSwiftModuleLoader::Implementation {
1431+
14211432
// Information about explicitly specified Swift module files.
14221433
struct ExplicitModuleInfo {
1423-
// Path of the module file.
1424-
StringRef path;
1425-
// Buffer of the module content.
1434+
// Path of the .swiftmodule file.
1435+
StringRef modulePath;
1436+
// Path of the .swiftmoduledoc file.
1437+
StringRef moduleDocPath;
1438+
// Path of the .swiftsourceinfo file.
1439+
StringRef moduleSourceInfoPath;
1440+
// Opened buffer for the .swiftmodule file.
14261441
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
14271442
};
1443+
ASTContext &Ctx;
1444+
llvm::BumpPtrAllocator Allocator;
1445+
llvm::StringSaver Saver;
14281446
llvm::StringMap<ExplicitModuleInfo> ExplicitModuleMap;
1447+
Implementation(ASTContext &Ctx): Ctx(Ctx), Saver(Allocator) {}
1448+
1449+
StringRef getScalaNodeText(llvm::yaml::Node *N) {
1450+
SmallString<32> Buffer;
1451+
return Saver.save(cast<llvm::yaml::ScalarNode>(N)->getValue(Buffer));
1452+
}
1453+
1454+
bool parseSingleModuleEntry(llvm::yaml::KeyValueNode &node) {
1455+
using namespace llvm::yaml;
1456+
auto moduleName = getScalaNodeText(node.getKey());
1457+
auto insertRes = ExplicitModuleMap.insert({moduleName,
1458+
ExplicitModuleInfo()});
1459+
if (!insertRes.second) {
1460+
return true;
1461+
}
1462+
auto moduleDetails = dyn_cast<MappingNode>(node.getValue());
1463+
if (!moduleDetails)
1464+
return true;
1465+
for (auto &entry: *moduleDetails) {
1466+
auto key = getScalaNodeText(entry.getKey());
1467+
auto val = getScalaNodeText(entry.getValue());
1468+
if (key == "SwiftModulePath") {
1469+
insertRes.first->second.modulePath = val;
1470+
} else if (key == "SwiftDocPath") {
1471+
insertRes.first->second.moduleDocPath = val;
1472+
} else if (key == "SwiftSourceInfoPath") {
1473+
insertRes.first->second.moduleSourceInfoPath = val;
1474+
} else {
1475+
return true;
1476+
}
1477+
}
1478+
return false;
1479+
}
1480+
// {
1481+
// "A": {
1482+
// "SwiftModulePath": "A.swiftmodule",
1483+
// "SwiftDocPath": "A.swiftdoc",
1484+
// "SwiftSourceInfoPath": "A.swiftsourceinfo"
1485+
// },
1486+
// "B": {
1487+
// "SwiftModulePath": "B.swiftmodule",
1488+
// "SwiftDocPath": "B.swiftdoc",
1489+
// "SwiftSourceInfoPath": "B.swiftsourceinfo"
1490+
// }
1491+
// }
1492+
void parseSwiftExplicitModuleMap(StringRef fileName) {
1493+
using namespace llvm::yaml;
1494+
// Load the input file.
1495+
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBufOrErr =
1496+
llvm::MemoryBuffer::getFile(fileName);
1497+
if (!fileBufOrErr) {
1498+
Ctx.Diags.diagnose(SourceLoc(), diag::explicit_swift_module_map_missing,
1499+
fileName);
1500+
return;
1501+
}
1502+
StringRef Buffer = fileBufOrErr->get()->getBuffer();
1503+
Stream Stream(llvm::MemoryBufferRef(Buffer, fileName),
1504+
Ctx.SourceMgr.getLLVMSourceMgr());
1505+
for (auto DI = Stream.begin(); DI != Stream.end(); ++ DI) {
1506+
assert(DI != Stream.end() && "Failed to read a document");
1507+
if (auto *MN = dyn_cast_or_null<MappingNode>(DI->getRoot())) {
1508+
for (auto &entry: *MN) {
1509+
if (parseSingleModuleEntry(entry)) {
1510+
Ctx.Diags.diagnose(SourceLoc(),
1511+
diag::explicit_swift_module_map_corrupted,
1512+
fileName);
1513+
return;
1514+
}
1515+
}
1516+
} else {
1517+
Ctx.Diags.diagnose(SourceLoc(),
1518+
diag::explicit_swift_module_map_corrupted,
1519+
fileName);
1520+
return;
1521+
}
1522+
}
1523+
}
14291524
};
14301525

14311526
ExplicitSwiftModuleLoader::ExplicitSwiftModuleLoader(
@@ -1435,7 +1530,7 @@ ExplicitSwiftModuleLoader::ExplicitSwiftModuleLoader(
14351530
bool IgnoreSwiftSourceInfoFile):
14361531
SerializedModuleLoaderBase(ctx, tracker, loadMode,
14371532
IgnoreSwiftSourceInfoFile),
1438-
Impl(*new Implementation()) {}
1533+
Impl(*new Implementation(ctx)) {}
14391534

14401535
ExplicitSwiftModuleLoader::~ExplicitSwiftModuleLoader() { delete &Impl; }
14411536

@@ -1453,9 +1548,33 @@ std::error_code ExplicitSwiftModuleLoader::findModuleFilesInDirectory(
14531548
if (it == Impl.ExplicitModuleMap.end()) {
14541549
return std::make_error_code(std::errc::not_supported);
14551550
}
1456-
// We found an explicit module matches the given name, give the buffer
1457-
// back to the caller side.
1458-
*ModuleBuffer = std::move(it->getValue().moduleBuffer);
1551+
auto &moduleInfo = it->getValue();
1552+
if (moduleInfo.moduleBuffer) {
1553+
// We found an explicit module matches the given name, give the buffer
1554+
// back to the caller side.
1555+
*ModuleBuffer = std::move(moduleInfo.moduleBuffer);
1556+
return std::error_code();
1557+
}
1558+
1559+
auto &fs = *Ctx.SourceMgr.getFileSystem();
1560+
// Open .swiftmodule file
1561+
auto moduleBuf = fs.getBufferForFile(moduleInfo.modulePath);
1562+
if (!moduleBuf)
1563+
return moduleBuf.getError();
1564+
*ModuleBuffer = std::move(moduleBuf.get());
1565+
1566+
// Open .swiftdoc file
1567+
if (!moduleInfo.moduleDocPath.empty()) {
1568+
auto moduleDocBuf = fs.getBufferForFile(moduleInfo.moduleDocPath);
1569+
if (moduleBuf)
1570+
*ModuleDocBuffer = std::move(moduleDocBuf.get());
1571+
}
1572+
// Open .swiftsourceinfo file
1573+
if (!moduleInfo.moduleSourceInfoPath.empty()) {
1574+
auto moduleSourceInfoBuf = fs.getBufferForFile(moduleInfo.moduleSourceInfoPath);
1575+
if (moduleSourceInfoBuf)
1576+
*ModuleSourceInfoBuffer = std::move(moduleSourceInfoBuf.get());
1577+
}
14591578
return std::error_code();
14601579
}
14611580

@@ -1470,19 +1589,24 @@ std::unique_ptr<ExplicitSwiftModuleLoader>
14701589
ExplicitSwiftModuleLoader::create(ASTContext &ctx,
14711590
DependencyTracker *tracker, ModuleLoadingMode loadMode,
14721591
ArrayRef<std::string> ExplicitModulePaths,
1592+
StringRef ExplicitSwiftModuleMap,
14731593
bool IgnoreSwiftSourceInfoFile) {
14741594
auto result = std::unique_ptr<ExplicitSwiftModuleLoader>(
14751595
new ExplicitSwiftModuleLoader(ctx, tracker, loadMode,
14761596
IgnoreSwiftSourceInfoFile));
14771597
auto &Impl = result->Impl;
1598+
// Parse a JSON file to collect explicitly built modules.
1599+
Impl.parseSwiftExplicitModuleMap(ExplicitSwiftModuleMap);
1600+
// Collect .swiftmodule paths from -swift-module-path
1601+
// FIXME: remove these.
14781602
for (auto path: ExplicitModulePaths) {
14791603
std::string name;
14801604
// Load the explicit module into a buffer and get its name.
14811605
std::unique_ptr<llvm::MemoryBuffer> buffer = getModuleName(ctx, path, name);
14821606
if (buffer) {
14831607
// Register this module for future loading.
14841608
auto &entry = Impl.ExplicitModuleMap[name];
1485-
entry.path = path;
1609+
entry.modulePath = path;
14861610
entry.moduleBuffer = std::move(buffer);
14871611
} else {
14881612
// We cannot read the module content, diagnose.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: mkdir -p %t/clang-module-cache
3+
// RUN: mkdir -p %t/inputs
4+
// RUN: echo "/// Some cool comments" > %t/foo.swift
5+
// RUN: echo "public func foo() {}" >> %t/foo.swift
6+
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/inputs/Foo.swiftmodule -emit-module-doc-path %t/inputs/Foo.swiftdoc -emit-module-source-info -emit-module-source-info-path %t/inputs/Foo.swiftsourceinfo -module-cache-path %t.module-cache %t/foo.swift -module-name Foo
7+
8+
// RUN: echo "{" > %t/inputs/map.json
9+
// RUN: echo "\"Foo\": {" >> %t/inputs/map.json
10+
// RUN: echo "\"SwiftModulePath\": \"%t/inputs/Foo.swiftmodule\"," >> %t/inputs/map.json
11+
// RUN: echo "\"SwiftDocPath\": \"%t/inputs/Foo.swiftdoc\"," >> %t/inputs/map.json
12+
// RUN: echo "\"SwiftSourceInfoPath\": \"%t/inputs/Foo.swiftsourceinfo\"" >> %t/inputs/map.json
13+
// RUN: echo "}" >> %t/inputs/map.json
14+
// RUN: echo "}" >> %t/inputs/map.json
15+
16+
// RUN: %target-swift-ide-test -print-module-comments -module-to-print=Foo -enable-swiftsourceinfo -source-filename %s -explicit-swift-module-map-file %t/inputs/map.json | %FileCheck %s
17+
18+
// CHECK: foo.swift:2:13: Func/foo RawComment=[/// Some cool comments

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,10 @@ EnableSwiftSourceInfo("enable-swiftsourceinfo",
723723
llvm::cl::cat(Category),
724724
llvm::cl::init(false));
725725

726+
static llvm::cl::opt<std::string>
727+
ExplicitSwiftModuleMap("explicit-swift-module-map-file",
728+
llvm::cl::desc("JSON file to include explicit Swift modules"),
729+
llvm::cl::cat(Category));
726730
} // namespace options
727731

728732
static std::unique_ptr<llvm::MemoryBuffer>
@@ -3462,6 +3466,11 @@ int main(int argc, char *argv[]) {
34623466
for (auto ConfigName : options::BuildConfigs)
34633467
InitInvok.getLangOptions().addCustomConditionalCompilationFlag(ConfigName);
34643468

3469+
if (!options::ExplicitSwiftModuleMap.empty()) {
3470+
InitInvok.getSearchPathOptions().ExplicitSwiftModuleMap =
3471+
options::ExplicitSwiftModuleMap;
3472+
InitInvok.getFrontendOptions().DisableImplicitModules = true;
3473+
}
34653474
// Process the clang arguments last and allow them to override previously
34663475
// set options.
34673476
if (!CCArgs.empty()) {

0 commit comments

Comments
 (0)