@@ -1364,12 +1364,8 @@ void ModuleDependencyScanner::resolveHeaderDependenciesForModule(
13641364 if (!moduleBuf)
13651365 return nullptr ;
13661366
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);
13731369 };
13741370
13751371 if (isBinaryModuleWithHeaderInput) {
@@ -1643,85 +1639,116 @@ void ModuleDependencyScanner::resolveCrossImportOverlayDependencies(
16431639 allModules.end (), action);
16441640}
16451641
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+
16461652llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining (
16471653 const ModuleDependencyID &rootModuleID, ModuleDependenciesCache &cache,
16481654 ModuleDependencyIDSetVector &allModules) {
16491655 if (rootModuleID.Kind != ModuleDependencyKind::SwiftSource)
16501656 return llvm::Error::success ();
16511657
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);
16681660
16691661 // Iterate through all the modules and collect all the bridging header
16701662 // and chain them into a single file. The allModules list is in the order of
16711663 // discover, thus providing stable ordering for a deterministic generated
16721664 // buffer.
16731665 auto FS = ScanASTContext.SourceMgr .getFileSystem ();
16741666 for (const auto &moduleID : allModules) {
1675- if (moduleID.Kind != ModuleDependencyKind::SwiftSource &&
1676- moduleID.Kind != ModuleDependencyKind::SwiftBinary)
1667+ if (moduleID.Kind != ModuleDependencyKind::SwiftBinary)
16771668 continue ;
16781669
16791670 auto moduleDependencyInfo = cache.findKnownDependency (moduleID);
16801671 if (auto *binaryMod = moduleDependencyInfo.getAsSwiftBinaryModule ()) {
16811672 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);
16851675 } else {
16861676 // Extract the embedded bridging header
16871677 auto moduleBuf = FS->getBufferForFile (binaryMod->compiledModulePath );
16881678 if (!moduleBuf)
16891679 return llvm::errorCodeToError (moduleBuf.getError ());
16901680
16911681 auto content = extractEmbeddedBridgingHeaderContent (
1692- std::move (*moduleBuf), ScanASTContext);
1693- if (content. empty () )
1682+ std::move (*moduleBuf), /* headerPath= */ " " , ScanASTContext);
1683+ if (! content)
16941684 return llvm::createStringError (" can't load embedded header from " +
16951685 binaryMod->compiledModulePath );
16961686
1697- outOS << content << " \n " ;
1687+ outOS << content-> getBuffer () << " \n " ;
16981688 }
16991689 }
1700- } else if (auto *srcMod = moduleDependencyInfo.getAsSwiftSourceModule ()) {
1701- if (srcMod->textualModuleDetails .bridgingHeaderFile ) {
1702- hasBridgingHeader = true ;
1703- outOS << " #include \" "
1704- << *srcMod->textualModuleDetails .bridgingHeaderFile << " \"\n " ;
1705- }
17061690 }
17071691 }
17081692
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+ }
17111722
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);
17191749 }
17201750
1721- auto sourceBuffer =
1722- llvm::MemoryBuffer::getMemBufferCopy (sourceBuf, outputPath);
17231751 // Scan and update the main module dependency.
1724- auto mainModuleDeps = cache.findKnownDependency (rootModuleID);
17251752 ModuleDependencyIDSetVector headerClangModuleDependencies;
17261753 std::optional<std::string> includeTreeID;
17271754 auto err = withDependencyScanningWorker (
@@ -1740,7 +1767,8 @@ llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
17401767
17411768 if (!headerScanResult)
17421769 return llvm::createStringError (
1743- " failed to scan generated bridging header " + outputPath);
1770+ " failed to scan generated bridging header " +
1771+ sourceBuffer->getBufferIdentifier ());
17441772
17451773 // Record module dependencies for each new module we found.
17461774 cache.recordClangDependencies (
@@ -1781,9 +1809,25 @@ llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
17811809 }
17821810 mainModuleDeps.updateBridgingHeaderCommandLine (
17831811 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+ }
17841827 mainModuleDeps.setHeaderSourceFiles (headerFileInputs);
1785- mainModuleDeps.setChainedBridgingHeaderBuffer (
1786- outputPath, sourceBuffer->getBuffer ());
1828+ if (needChainedHeader)
1829+ mainModuleDeps.setChainedBridgingHeaderBuffer (
1830+ sourceBuffer->getBufferIdentifier (), sourceBuffer->getBuffer ());
17871831 // Update the set of visible Clang modules
17881832 mainModuleDeps.addVisibleClangModules (headerScanResult->VisibleModules );
17891833
0 commit comments