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