@@ -1364,12 +1364,8 @@ void ModuleDependencyScanner::resolveHeaderDependenciesForModule(
1364
1364
if (!moduleBuf)
1365
1365
return nullptr ;
1366
1366
1367
- auto content = extractEmbeddedBridgingHeaderContent (std::move (*moduleBuf),
1368
- ScanASTContext);
1369
- if (content.empty ())
1370
- return nullptr ;
1371
-
1372
- return llvm::MemoryBuffer::getMemBufferCopy (content, header);
1367
+ return extractEmbeddedBridgingHeaderContent (std::move (*moduleBuf), header,
1368
+ ScanASTContext);
1373
1369
};
1374
1370
1375
1371
if (isBinaryModuleWithHeaderInput) {
@@ -1636,85 +1632,116 @@ void ModuleDependencyScanner::resolveCrossImportOverlayDependencies(
1636
1632
allModules.end (), action);
1637
1633
}
1638
1634
1635
+ static void appendHeaderContent (llvm::raw_ostream &OS,
1636
+ llvm::MemoryBufferRef buffer,
1637
+ ModuleDependencyID fromModule) {
1638
+ // Use preprocessor directives to add some clues for where the content is
1639
+ // coming from.
1640
+ OS << " # 1 \" <module-" << fromModule.ModuleName << " >/"
1641
+ << llvm::sys::path::filename (buffer.getBufferIdentifier ()) << " \" 1\n " ;
1642
+ OS << buffer.getBuffer ();
1643
+ }
1644
+
1639
1645
llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining (
1640
1646
const ModuleDependencyID &rootModuleID, ModuleDependenciesCache &cache,
1641
1647
ModuleDependencyIDSetVector &allModules) {
1642
1648
if (rootModuleID.Kind != ModuleDependencyKind::SwiftSource)
1643
1649
return llvm::Error::success ();
1644
1650
1645
- bool hasBridgingHeader = false ;
1646
- llvm::vfs::OnDiskOutputBackend outputBackend;
1647
-
1648
- SmallString<256 > outputPath (
1649
- ScanCompilerInvocation.getFrontendOptions ().ScannerOutputDir );
1650
-
1651
- if (outputPath.empty ())
1652
- outputPath = " /<compiler-generated>" ;
1653
-
1654
- llvm::sys::path::append (
1655
- outputPath, ScanCompilerInvocation.getFrontendOptions ().ModuleName + " -" +
1656
- ScanCompilerInvocation.getModuleScanningHash () +
1657
- " -ChainedBridgingHeader.h" );
1658
-
1659
- llvm::SmallString<256 > sourceBuf;
1660
- llvm::raw_svector_ostream outOS (sourceBuf);
1651
+ llvm::SmallString<256 > chainedHeaderBuffer;
1652
+ llvm::raw_svector_ostream outOS (chainedHeaderBuffer);
1661
1653
1662
1654
// Iterate through all the modules and collect all the bridging header
1663
1655
// and chain them into a single file. The allModules list is in the order of
1664
1656
// discover, thus providing stable ordering for a deterministic generated
1665
1657
// buffer.
1666
1658
auto FS = ScanASTContext.SourceMgr .getFileSystem ();
1667
1659
for (const auto &moduleID : allModules) {
1668
- if (moduleID.Kind != ModuleDependencyKind::SwiftSource &&
1669
- moduleID.Kind != ModuleDependencyKind::SwiftBinary)
1660
+ if (moduleID.Kind != ModuleDependencyKind::SwiftBinary)
1670
1661
continue ;
1671
1662
1672
1663
auto moduleDependencyInfo = cache.findKnownDependency (moduleID);
1673
1664
if (auto *binaryMod = moduleDependencyInfo.getAsSwiftBinaryModule ()) {
1674
1665
if (!binaryMod->headerImport .empty ()) {
1675
- hasBridgingHeader = true ;
1676
- if (FS->exists (binaryMod->headerImport )) {
1677
- outOS << " #include \" " << binaryMod->headerImport << " \"\n " ;
1666
+ if (auto buffer= FS->getBufferForFile (binaryMod->headerImport )) {
1667
+ appendHeaderContent (outOS, (*buffer)->getMemBufferRef (), moduleID);
1678
1668
} else {
1679
1669
// Extract the embedded bridging header
1680
1670
auto moduleBuf = FS->getBufferForFile (binaryMod->compiledModulePath );
1681
1671
if (!moduleBuf)
1682
1672
return llvm::errorCodeToError (moduleBuf.getError ());
1683
1673
1684
1674
auto content = extractEmbeddedBridgingHeaderContent (
1685
- std::move (*moduleBuf), ScanASTContext);
1686
- if (content. empty () )
1675
+ std::move (*moduleBuf), /* headerPath= */ " " , ScanASTContext);
1676
+ if (! content)
1687
1677
return llvm::createStringError (" can't load embedded header from " +
1688
1678
binaryMod->compiledModulePath );
1689
1679
1690
- outOS << content << " \n " ;
1680
+ outOS << content-> getBuffer () << " \n " ;
1691
1681
}
1692
1682
}
1693
- } else if (auto *srcMod = moduleDependencyInfo.getAsSwiftSourceModule ()) {
1694
- if (srcMod->textualModuleDetails .bridgingHeaderFile ) {
1695
- hasBridgingHeader = true ;
1696
- outOS << " #include \" "
1697
- << *srcMod->textualModuleDetails .bridgingHeaderFile << " \"\n " ;
1698
- }
1699
1683
}
1700
1684
}
1701
1685
1702
- if (!hasBridgingHeader)
1703
- return llvm::Error::success ();
1686
+ // Handle bridging header in main module.
1687
+ auto mainModuleDeps = cache.findKnownDependency (rootModuleID);
1688
+ auto *mainModule = mainModuleDeps.getAsSwiftSourceModule ();
1689
+ assert (mainModule && " expect main module to be a swift source module" );
1690
+ std::unique_ptr<llvm::MemoryBuffer> sourceBuffer;
1691
+ bool needChainedHeader = !chainedHeaderBuffer.empty ();
1692
+ if (!needChainedHeader) {
1693
+ // There is no bridging header chained from dependencies.
1694
+ // If main module also has no bridging header, ther is nothing to scan.
1695
+ if (!mainModule->textualModuleDetails .bridgingHeaderFile )
1696
+ return llvm::Error::success ();
1697
+
1698
+ // Otherwise, there is no chaining needed. Just use the bridging header from
1699
+ // main module.
1700
+ if (auto headerBuffer = FS->getBufferForFile (
1701
+ *mainModule->textualModuleDetails .bridgingHeaderFile ))
1702
+ sourceBuffer = std::move (*headerBuffer);
1703
+ else
1704
+ return llvm::errorCodeToError (headerBuffer.getError ());
1705
+ } else {
1706
+ // There are bridging header needed to be chained. Append the bridging
1707
+ // header from main module if needed and create use a new source buffer.
1708
+ if (mainModule->textualModuleDetails .bridgingHeaderFile ) {
1709
+ auto srcBuf = FS->getBufferForFile (
1710
+ *mainModule->textualModuleDetails .bridgingHeaderFile );
1711
+ if (!srcBuf)
1712
+ return llvm::errorCodeToError (srcBuf.getError ());
1713
+ appendHeaderContent (outOS, (*srcBuf)->getMemBufferRef (), rootModuleID);
1714
+ }
1704
1715
1705
- if (ScanCompilerInvocation.getFrontendOptions ().WriteScannerOutput ) {
1706
- auto outFile = outputBackend.createFile (outputPath);
1707
- if (!outFile)
1708
- return outFile.takeError ();
1709
- *outFile << sourceBuf;
1710
- if (auto err = outFile->keep ())
1711
- return err;
1716
+ SmallString<256 > outputPath (
1717
+ ScanCompilerInvocation.getFrontendOptions ().ScannerOutputDir );
1718
+
1719
+ if (outputPath.empty ())
1720
+ outputPath = " /<compiler-generated>" ;
1721
+
1722
+ // Use the hash of the file content to differentiate the chained header.
1723
+ auto fileHash =
1724
+ llvm::toString (llvm::APInt (64 , llvm::hash_value (chainedHeaderBuffer)),
1725
+ 36 , /* Signed=*/ false );
1726
+ llvm::sys::path::append (
1727
+ outputPath, ScanCompilerInvocation.getFrontendOptions ().ModuleName +
1728
+ " -" + fileHash + " -ChainedBridgingHeader.h" );
1729
+
1730
+ if (ScanCompilerInvocation.getFrontendOptions ().WriteScannerOutput ) {
1731
+ llvm::vfs::OnDiskOutputBackend outputBackend;
1732
+ auto outFile = outputBackend.createFile (outputPath);
1733
+ if (!outFile)
1734
+ return outFile.takeError ();
1735
+ *outFile << chainedHeaderBuffer;
1736
+ if (auto err = outFile->keep ())
1737
+ return err;
1738
+ }
1739
+
1740
+ sourceBuffer =
1741
+ llvm::MemoryBuffer::getMemBufferCopy (chainedHeaderBuffer, outputPath);
1712
1742
}
1713
1743
1714
- auto sourceBuffer =
1715
- llvm::MemoryBuffer::getMemBufferCopy (sourceBuf, outputPath);
1716
1744
// Scan and update the main module dependency.
1717
- auto mainModuleDeps = cache.findKnownDependency (rootModuleID);
1718
1745
ModuleDependencyIDSetVector headerClangModuleDependencies;
1719
1746
std::optional<std::string> includeTreeID;
1720
1747
auto err = withDependencyScanningWorker (
@@ -1733,7 +1760,8 @@ llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
1733
1760
1734
1761
if (!headerScanResult)
1735
1762
return llvm::createStringError (
1736
- " failed to scan generated bridging header " + outputPath);
1763
+ " failed to scan generated bridging header " +
1764
+ sourceBuffer->getBufferIdentifier ());
1737
1765
1738
1766
// Record module dependencies for each new module we found.
1739
1767
cache.recordClangDependencies (
@@ -1774,9 +1802,25 @@ llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
1774
1802
}
1775
1803
mainModuleDeps.updateBridgingHeaderCommandLine (
1776
1804
bridgingHeaderCommandLine);
1805
+ if (needChainedHeader) {
1806
+ // As only the chained bridging header is scanned, the dependency will
1807
+ // not include the original bridging header passed by user. Fixup the
1808
+ // headerFileInputs to include original bridging header and not
1809
+ // include the generated header so build system can correctly computes
1810
+ // the dependencies.
1811
+ auto generated =
1812
+ llvm::find (headerFileInputs, sourceBuffer->getBufferIdentifier ());
1813
+ if (generated != headerFileInputs.end ()) {
1814
+ if (mainModule->textualModuleDetails .bridgingHeaderFile )
1815
+ *generated = *mainModule->textualModuleDetails .bridgingHeaderFile ;
1816
+ else
1817
+ headerFileInputs.erase (generated);
1818
+ }
1819
+ }
1777
1820
mainModuleDeps.setHeaderSourceFiles (headerFileInputs);
1778
- mainModuleDeps.setChainedBridgingHeaderBuffer (
1779
- outputPath, sourceBuffer->getBuffer ());
1821
+ if (needChainedHeader)
1822
+ mainModuleDeps.setChainedBridgingHeaderBuffer (
1823
+ sourceBuffer->getBufferIdentifier (), sourceBuffer->getBuffer ());
1780
1824
// Update the set of visible Clang modules
1781
1825
mainModuleDeps.addVisibleClangModules (headerScanResult->VisibleModules );
1782
1826
0 commit comments