@@ -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) {
@@ -1636,85 +1632,116 @@ void ModuleDependencyScanner::resolveCrossImportOverlayDependencies(
16361632 allModules.end (), action);
16371633}
16381634
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+
16391645llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining (
16401646 const ModuleDependencyID &rootModuleID, ModuleDependenciesCache &cache,
16411647 ModuleDependencyIDSetVector &allModules) {
16421648 if (rootModuleID.Kind != ModuleDependencyKind::SwiftSource)
16431649 return llvm::Error::success ();
16441650
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);
16611653
16621654 // Iterate through all the modules and collect all the bridging header
16631655 // and chain them into a single file. The allModules list is in the order of
16641656 // discover, thus providing stable ordering for a deterministic generated
16651657 // buffer.
16661658 auto FS = ScanASTContext.SourceMgr .getFileSystem ();
16671659 for (const auto &moduleID : allModules) {
1668- if (moduleID.Kind != ModuleDependencyKind::SwiftSource &&
1669- moduleID.Kind != ModuleDependencyKind::SwiftBinary)
1660+ if (moduleID.Kind != ModuleDependencyKind::SwiftBinary)
16701661 continue ;
16711662
16721663 auto moduleDependencyInfo = cache.findKnownDependency (moduleID);
16731664 if (auto *binaryMod = moduleDependencyInfo.getAsSwiftBinaryModule ()) {
16741665 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);
16781668 } else {
16791669 // Extract the embedded bridging header
16801670 auto moduleBuf = FS->getBufferForFile (binaryMod->compiledModulePath );
16811671 if (!moduleBuf)
16821672 return llvm::errorCodeToError (moduleBuf.getError ());
16831673
16841674 auto content = extractEmbeddedBridgingHeaderContent (
1685- std::move (*moduleBuf), ScanASTContext);
1686- if (content. empty () )
1675+ std::move (*moduleBuf), /* headerPath= */ " " , ScanASTContext);
1676+ if (! content)
16871677 return llvm::createStringError (" can't load embedded header from " +
16881678 binaryMod->compiledModulePath );
16891679
1690- outOS << content << " \n " ;
1680+ outOS << content-> getBuffer () << " \n " ;
16911681 }
16921682 }
1693- } else if (auto *srcMod = moduleDependencyInfo.getAsSwiftSourceModule ()) {
1694- if (srcMod->textualModuleDetails .bridgingHeaderFile ) {
1695- hasBridgingHeader = true ;
1696- outOS << " #include \" "
1697- << *srcMod->textualModuleDetails .bridgingHeaderFile << " \"\n " ;
1698- }
16991683 }
17001684 }
17011685
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+ }
17041715
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);
17121742 }
17131743
1714- auto sourceBuffer =
1715- llvm::MemoryBuffer::getMemBufferCopy (sourceBuf, outputPath);
17161744 // Scan and update the main module dependency.
1717- auto mainModuleDeps = cache.findKnownDependency (rootModuleID);
17181745 ModuleDependencyIDSetVector headerClangModuleDependencies;
17191746 std::optional<std::string> includeTreeID;
17201747 auto err = withDependencyScanningWorker (
@@ -1733,7 +1760,8 @@ llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
17331760
17341761 if (!headerScanResult)
17351762 return llvm::createStringError (
1736- " failed to scan generated bridging header " + outputPath);
1763+ " failed to scan generated bridging header " +
1764+ sourceBuffer->getBufferIdentifier ());
17371765
17381766 // Record module dependencies for each new module we found.
17391767 cache.recordClangDependencies (
@@ -1774,9 +1802,25 @@ llvm::Error ModuleDependencyScanner::performBridgingHeaderChaining(
17741802 }
17751803 mainModuleDeps.updateBridgingHeaderCommandLine (
17761804 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+ }
17771820 mainModuleDeps.setHeaderSourceFiles (headerFileInputs);
1778- mainModuleDeps.setChainedBridgingHeaderBuffer (
1779- outputPath, sourceBuffer->getBuffer ());
1821+ if (needChainedHeader)
1822+ mainModuleDeps.setChainedBridgingHeaderBuffer (
1823+ sourceBuffer->getBufferIdentifier (), sourceBuffer->getBuffer ());
17801824 // Update the set of visible Clang modules
17811825 mainModuleDeps.addVisibleClangModules (headerScanResult->VisibleModules );
17821826
0 commit comments