36
36
#include " llvm/Support/Path.h"
37
37
#include " llvm/Support/Errc.h"
38
38
#include " llvm/Support/YAMLTraits.h"
39
+ #include " llvm/Support/YAMLParser.h"
39
40
#include " ModuleInterfaceBuilder.h"
40
41
41
42
using namespace swift ;
@@ -1218,6 +1219,15 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
1218
1219
GenericArgs.push_back (" -swift-module-file" );
1219
1220
GenericArgs.push_back (ArgSaver.save (EM));
1220
1221
}
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
+ }
1221
1231
if (clangImporter) {
1222
1232
// We need to add these extra clang flags because explict module building
1223
1233
// related flags are all there: -fno-implicit-modules, -fmodule-map-file=,
@@ -1418,14 +1428,99 @@ bool InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleN
1418
1428
}
1419
1429
1420
1430
struct ExplicitSwiftModuleLoader ::Implementation {
1431
+
1421
1432
// Information about explicitly specified Swift module files.
1422
1433
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.
1426
1441
std::unique_ptr<llvm::MemoryBuffer> moduleBuffer;
1427
1442
};
1443
+ ASTContext &Ctx;
1444
+ llvm::BumpPtrAllocator Allocator;
1445
+ llvm::StringSaver Saver;
1428
1446
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
+ }
1429
1524
};
1430
1525
1431
1526
ExplicitSwiftModuleLoader::ExplicitSwiftModuleLoader (
@@ -1435,7 +1530,7 @@ ExplicitSwiftModuleLoader::ExplicitSwiftModuleLoader(
1435
1530
bool IgnoreSwiftSourceInfoFile):
1436
1531
SerializedModuleLoaderBase(ctx, tracker, loadMode,
1437
1532
IgnoreSwiftSourceInfoFile),
1438
- Impl(*new Implementation()) {}
1533
+ Impl(*new Implementation(ctx )) {}
1439
1534
1440
1535
ExplicitSwiftModuleLoader::~ExplicitSwiftModuleLoader () { delete &Impl; }
1441
1536
@@ -1453,9 +1548,33 @@ std::error_code ExplicitSwiftModuleLoader::findModuleFilesInDirectory(
1453
1548
if (it == Impl.ExplicitModuleMap .end ()) {
1454
1549
return std::make_error_code (std::errc::not_supported);
1455
1550
}
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
+ }
1459
1578
return std::error_code ();
1460
1579
}
1461
1580
@@ -1470,19 +1589,24 @@ std::unique_ptr<ExplicitSwiftModuleLoader>
1470
1589
ExplicitSwiftModuleLoader::create (ASTContext &ctx,
1471
1590
DependencyTracker *tracker, ModuleLoadingMode loadMode,
1472
1591
ArrayRef<std::string> ExplicitModulePaths,
1592
+ StringRef ExplicitSwiftModuleMap,
1473
1593
bool IgnoreSwiftSourceInfoFile) {
1474
1594
auto result = std::unique_ptr<ExplicitSwiftModuleLoader>(
1475
1595
new ExplicitSwiftModuleLoader (ctx, tracker, loadMode,
1476
1596
IgnoreSwiftSourceInfoFile));
1477
1597
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.
1478
1602
for (auto path: ExplicitModulePaths) {
1479
1603
std::string name;
1480
1604
// Load the explicit module into a buffer and get its name.
1481
1605
std::unique_ptr<llvm::MemoryBuffer> buffer = getModuleName (ctx, path, name);
1482
1606
if (buffer) {
1483
1607
// Register this module for future loading.
1484
1608
auto &entry = Impl.ExplicitModuleMap [name];
1485
- entry.path = path;
1609
+ entry.modulePath = path;
1486
1610
entry.moduleBuffer = std::move (buffer);
1487
1611
} else {
1488
1612
// We cannot read the module content, diagnose.
0 commit comments