Skip to content

Commit c58fd27

Browse files
[BrdigingHeader] Auto bridging header chaining
Add ability to automatically chaining the bridging headers discovered from all dependencies module when doing swift caching build. This will elminiate all implicit bridging header imports from the build and make the bridging header importing behavior much more reliable, while keep the compatibility at maximum. For example, if the current module `A` depends on module `B` and `C` and both `B` and `C` are binary modules that uses bridging header, when building module A, dependency scanner will construct a new header that chains three bridging headers together with the option to build a PCH from it. This will make all importing errors more obvious while improving the performance. This is currently only enabled for swift caching since the new chained header is written into CAS directly without the need to serialization.
1 parent e89abf8 commit c58fd27

28 files changed

+475
-161
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -786,11 +786,11 @@ class ModuleDependencyInfo {
786786
setLinkLibraries(const ArrayRef<LinkLibrary> linkLibraries) {
787787
storage->linkLibraries.assign(linkLibraries.begin(), linkLibraries.end());
788788
}
789-
789+
790790
const ArrayRef<std::string> getAuxiliaryFiles() const {
791791
return storage->auxiliaryFiles;
792792
}
793-
793+
794794
void
795795
setAuxiliaryFiles(const ArrayRef<std::string> auxiliaryFiles) {
796796
storage->auxiliaryFiles.assign(auxiliaryFiles.begin(), auxiliaryFiles.end());
@@ -1196,11 +1196,11 @@ class ModuleDependenciesCache {
11961196
/// Query all dependencies
11971197
ModuleDependencyIDSetVector
11981198
getAllDependencies(const ModuleDependencyID &moduleID) const;
1199-
1199+
12001200
/// Query all Clang module dependencies.
12011201
ModuleDependencyIDSetVector
12021202
getClangDependencies(const ModuleDependencyID &moduleID) const;
1203-
1203+
12041204
/// Query all directly-imported Swift dependencies
12051205
llvm::ArrayRef<ModuleDependencyID>
12061206
getImportedSwiftDependencies(const ModuleDependencyID &moduleID) const;

include/swift/Basic/LangOptions.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ namespace swift {
201201
/// Maximum number of typo corrections we are allowed to perform.
202202
/// This is disabled by default until we can get typo-correction working within acceptable performance bounds.
203203
unsigned TypoCorrectionLimit = 0;
204-
204+
205205
/// Should access control be respected?
206206
bool EnableAccessControl = true;
207207

@@ -260,7 +260,7 @@ namespace swift {
260260

261261
/// Emit a remark when indexing a system module.
262262
bool EnableIndexingSystemModuleRemarks = false;
263-
263+
264264
/// Emit a remark on early exit in explicit interface build
265265
bool EnableSkipExplicitInterfaceModuleBuildRemarks = false;
266266

@@ -691,7 +691,7 @@ namespace swift {
691691
void clearAllPlatformConditionValues() {
692692
PlatformConditionValues.clear();
693693
}
694-
694+
695695
/// Returns the value for the given platform condition or an empty string.
696696
StringRef getPlatformConditionValue(PlatformConditionKind Kind) const;
697697

@@ -871,7 +871,7 @@ namespace swift {
871871
/// 4.2 GHz Intel Core i7.
872872
/// (It's arbitrary, but will keep the compiler from taking too much time.)
873873
unsigned SwitchCheckingInvocationThreshold = 200000;
874-
874+
875875
/// If true, the time it takes to type-check each function will be dumped
876876
/// to llvm::errs().
877877
bool DebugTimeFunctionBodies = false;
@@ -922,7 +922,7 @@ namespace swift {
922922

923923
/// Enable experimental operator designated types feature.
924924
bool EnableOperatorDesignatedTypes = false;
925-
925+
926926
/// Disable constraint system performance hacks.
927927
bool DisableConstraintSolverPerformanceHacks = false;
928928

@@ -967,6 +967,9 @@ namespace swift {
967967
/// The bridging header or PCH that will be imported.
968968
std::string BridgingHeader;
969969

970+
/// The bridging header PCH file.
971+
std::string BridgingHeaderPCH;
972+
970973
/// When automatically generating a precompiled header from the bridging
971974
/// header, place it in this directory.
972975
std::string PrecompiledHeaderOutputDir;
@@ -1088,6 +1091,9 @@ namespace swift {
10881091
/// compilation source targets.
10891092
std::vector<std::string>
10901093
getReducedExtraArgsForSwiftModuleDependency() const;
1094+
1095+
/// Get PCH input path. Return empty string if there is no PCH input.
1096+
std::string getPCHInputPath() const;
10911097
};
10921098

10931099
} // end namespace swift

include/swift/ClangImporter/ClangImporter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,9 @@ class ClangImporter final : public ClangModuleLoader {
506506
/// information will be augmented with information about the given
507507
/// textual header inputs.
508508
///
509+
/// \param bridgingHeaderContent an optional buffer that pass the briding
510+
/// heaer content to the scanner instead of relying on the filename.
511+
///
509512
/// \param clangScanningTool The clang dependency scanner.
510513
///
511514
/// \param cache The module dependencies cache to update, with information
@@ -514,6 +517,7 @@ class ClangImporter final : public ClangModuleLoader {
514517
/// \returns \c true if an error occurred, \c false otherwise
515518
bool getHeaderDependencies(
516519
ModuleDependencyID moduleID,
520+
std::optional<std::string> bridgingHeaderContent,
517521
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
518522
ModuleDependenciesCache &cache,
519523
ModuleDependencyIDSetVector &headerClangModuleDependencies,

include/swift/DependencyScan/ModuleDependencyScanner.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,10 @@ class ModuleDependencyScanner {
116116
resolveAllClangModuleDependencies(ArrayRef<ModuleDependencyID> swiftModules,
117117
ModuleDependenciesCache &cache,
118118
ModuleDependencyIDSetVector &discoveredClangModules);
119-
void
120-
resolveHeaderDependencies(ArrayRef<ModuleDependencyID> swiftModules,
121-
ModuleDependenciesCache &cache,
122-
ModuleDependencyIDSetVector &discoveredHeaderDependencyClangModules);
119+
void resolveHeaderDependencies(
120+
const ModuleDependencyID &rootModuleID,
121+
ArrayRef<ModuleDependencyID> swiftModules, ModuleDependenciesCache &cache,
122+
ModuleDependencyIDSetVector &discoveredHeaderDependencyClangModules);
123123
void
124124
resolveSwiftOverlayDependencies(ArrayRef<ModuleDependencyID> swiftModules,
125125
ModuleDependenciesCache &cache,
@@ -171,6 +171,8 @@ class ModuleDependencyScanner {
171171
std::mutex WorkersLock;
172172
/// Count of filesystem queries performed
173173
std::atomic<unsigned> NumLookups = 0;
174+
/// If using auto bridging header chaining.
175+
bool BridgingHeaderChaining = false;
174176
};
175177

176178
} // namespace swift

include/swift/Frontend/FrontendOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ class FrontendOptions {
5454
/// An Objective-C header to import and make implicitly visible.
5555
std::string ImplicitObjCHeaderPath;
5656

57+
/// An Objective-C pch to import and make implicitly visible.
58+
std::string ImplicitObjCPCHPath;
59+
5760
/// The map of aliases and real names of imported or referenced modules.
5861
llvm::StringMap<StringRef> ModuleAliasMap;
5962

include/swift/Option/Options.td

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,12 @@ def verify_incremental_dependencies :
173173
Flag<["-"], "verify-incremental-dependencies">,
174174
Flags<[FrontendOption, HelpHidden]>,
175175
HelpText<"Enable the dependency verifier for each frontend job">;
176-
176+
177177
def strict_implicit_module_context :
178178
Flag<["-"], "strict-implicit-module-context">,
179179
Flags<[FrontendOption, HelpHidden]>,
180180
HelpText<"Enable the strict forwarding of compilation context to downstream implicit module dependencies">;
181-
181+
182182
def no_strict_implicit_module_context :
183183
Flag<["-"], "no-strict-implicit-module-context">,
184184
Flags<[FrontendOption, HelpHidden]>,
@@ -315,7 +315,7 @@ def tools_directory : Separate<["-"], "tools-directory">,
315315

316316
def D : JoinedOrSeparate<["-"], "D">, Flags<[FrontendOption]>,
317317
HelpText<"Marks a conditional compilation flag as true">;
318-
318+
319319
def e : Separate<["-"], "e">, Flags<[NewDriverOnlyOption]>,
320320
HelpText<"Executes a line of code provided on the command line">;
321321

@@ -353,6 +353,9 @@ def import_objc_header : Separate<["-"], "import-objc-header">,
353353
def import_bridging_header : Separate<["-"], "import-bridging-header">,
354354
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
355355
Alias<import_objc_header>;
356+
def import_pch : Separate<["-"], "import-pch">,
357+
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
358+
HelpText<"Import bridging header PCH file">;
356359

357360
def pch_output_dir: Separate<["-"], "pch-output-dir">,
358361
Flags<[FrontendOption, HelpHidden, ArgumentIsPath]>,
@@ -2117,7 +2120,7 @@ def external_plugin_path : Separate<["-"], "external-plugin-path">, Group<plugin
21172120
Flags<[FrontendOption, ArgumentIsPath, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>,
21182121
HelpText<"Add directory to the plugin search path with a plugin server executable">,
21192122
MetaVarName<"<path>#<plugin-server-path>">;
2120-
2123+
21212124
def cas_backend: Flag<["-"], "cas-backend">,
21222125
Flags<[FrontendOption, NoDriverOption]>,
21232126
HelpText<"Enable using CASBackend for object file output">;

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ class SerializedASTFile final : public LoadedFile {
430430
getFilenameForPrivateDecl(const Decl *decl) const override;
431431

432432
virtual TypeDecl *lookupLocalType(StringRef MangledName) const override;
433-
433+
434434
virtual OpaqueTypeDecl *
435435
lookupOpaqueResultType(StringRef MangledName) override;
436436

@@ -577,6 +577,11 @@ bool extractCompilerFlagsFromInterface(
577577

578578
/// Extract the user module version number from an interface file.
579579
llvm::VersionTuple extractUserModuleVersionFromInterface(StringRef moduleInterfacePath);
580+
581+
/// Extract embedded bridging header from binary module.
582+
std::string
583+
extractEmbeddedBridgingHeaderContent(std::unique_ptr<llvm::MemoryBuffer> file,
584+
ASTContext &Context);
580585
} // end namespace swift
581586

582587
#endif

lib/AST/ModuleDependencies.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -770,14 +770,14 @@ ModuleDependenciesCache::findDependency(
770770
}
771771
return std::nullopt;
772772
}
773-
773+
774774
assert(kind.has_value() && "Expected dependencies kind for lookup.");
775775
std::optional<const ModuleDependencyInfo *> optionalDep = std::nullopt;
776776
const auto &map = getDependenciesMap(kind.value());
777777
auto known = map.find(moduleName);
778778
if (known != map.end())
779779
optionalDep = &(known->second);
780-
780+
781781
// During a scan, only produce the cached source module info for the current
782782
// module under scan.
783783
if (optionalDep.has_value()) {

lib/Basic/LangOptions.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/Basic/LangOptions.h"
1919
#include "swift/AST/DiagnosticEngine.h"
2020
#include "swift/Basic/Feature.h"
21+
#include "swift/Basic/FileTypes.h"
2122
#include "swift/Basic/Platform.h"
2223
#include "swift/Basic/PlaygroundOption.h"
2324
#include "swift/Basic/Range.h"
@@ -814,3 +815,14 @@ ClangImporterOptions::getReducedExtraArgsForSwiftModuleDependency() const {
814815

815816
return filtered_args;
816817
}
818+
819+
std::string ClangImporterOptions::getPCHInputPath() const {
820+
if (!BridgingHeaderPCH.empty())
821+
return BridgingHeaderPCH;
822+
823+
if (llvm::sys::path::extension(BridgingHeader)
824+
.ends_with(file_types::getExtension(file_types::TY_PCH)))
825+
return BridgingHeader;
826+
827+
return {};
828+
}

lib/ClangImporter/ClangImporter.cpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -476,11 +476,10 @@ void importer::getNormalInvocationArguments(
476476
ClangImporterOptions &importerOpts = ctx.ClangImporterOpts;
477477
auto languageVersion = ctx.LangOpts.EffectiveLanguageVersion;
478478

479-
if (isPCHFilenameExtension(importerOpts.BridgingHeader)) {
480-
invocationArgStrs.insert(invocationArgStrs.end(), {
481-
"-include-pch", importerOpts.BridgingHeader
482-
});
483-
}
479+
auto bridgingPCH = importerOpts.getPCHInputPath();
480+
if (!bridgingPCH.empty())
481+
invocationArgStrs.insert(invocationArgStrs.end(),
482+
{"-include-pch", bridgingPCH});
484483

485484
// If there are no shims in the resource dir, add a search path in the SDK.
486485
SmallString<128> shimsPath(searchPathOpts.RuntimeResourcePath);
@@ -1066,9 +1065,10 @@ void ClangImporter::addClangInvovcationDependencies(
10661065
std::optional<std::string>
10671066
ClangImporter::getPCHFilename(const ClangImporterOptions &ImporterOptions,
10681067
StringRef SwiftPCHHash, bool &isExplicit) {
1069-
if (isPCHFilenameExtension(ImporterOptions.BridgingHeader)) {
1068+
auto bridgingPCH = ImporterOptions.getPCHInputPath();
1069+
if (!bridgingPCH.empty()) {
10701070
isExplicit = true;
1071-
return ImporterOptions.BridgingHeader;
1071+
return bridgingPCH;
10721072
}
10731073
isExplicit = false;
10741074

@@ -1302,16 +1302,17 @@ ClangImporter::create(ASTContext &ctx,
13021302
new ClangImporter(ctx, tracker, dwarfImporterDelegate)};
13031303
auto &importerOpts = ctx.ClangImporterOpts;
13041304

1305-
if (isPCHFilenameExtension(importerOpts.BridgingHeader)) {
1306-
importer->Impl.setSinglePCHImport(importerOpts.BridgingHeader);
1305+
auto bridgingPCH = importerOpts.getPCHInputPath();
1306+
if (!bridgingPCH.empty()) {
1307+
importer->Impl.setSinglePCHImport(bridgingPCH);
13071308
importer->Impl.IsReadingBridgingPCH = true;
13081309
if (tracker) {
13091310
// Currently ignoring dependency on bridging .pch files because they are
13101311
// temporaries; if and when they are no longer temporaries, this condition
13111312
// should be removed.
13121313
auto &coll = static_cast<ClangImporterDependencyCollector &>(
13131314
*tracker->getClangCollector());
1314-
coll.excludePath(importerOpts.BridgingHeader);
1315+
coll.excludePath(bridgingPCH);
13151316
}
13161317
}
13171318

@@ -6328,7 +6329,7 @@ static bool isImplValid(ExtensionDecl *ext) {
63286329
// This is diagnosed in AttributeChecker::visitObjCImplementationAttr().
63296330
if (!attr->isEarlyAdopter() && !attr->CategoryName.empty())
63306331
return false;
6331-
6332+
63326333
return !attr->isCategoryNameInvalid();
63336334
}
63346335

@@ -7928,7 +7929,7 @@ CxxRecordSemantics::evaluate(Evaluator &evaluator,
79287929
if (hasIteratorAPIAttr(cxxDecl) || isIterator(cxxDecl)) {
79297930
return CxxRecordSemanticsKind::Iterator;
79307931
}
7931-
7932+
79327933
if (hasCopyTypeOperations(cxxDecl)) {
79337934
return CxxRecordSemanticsKind::Owned;
79347935
}
@@ -7985,7 +7986,7 @@ bool anySubobjectsSelfContained(const clang::CXXRecordDecl *decl) {
79857986

79867987
if (hasCustomCopyOrMoveConstructor(decl) || hasOwnedValueAttr(decl))
79877988
return true;
7988-
7989+
79897990
auto checkType = [](clang::QualType t) {
79907991
if (auto recordType = dyn_cast<clang::RecordType>(t.getCanonicalType())) {
79917992
if (auto cxxRecord =
@@ -8006,7 +8007,7 @@ bool anySubobjectsSelfContained(const clang::CXXRecordDecl *decl) {
80068007
if (checkType(base.getType()))
80078008
return true;
80088009
}
8009-
8010+
80108011
return false;
80118012
}
80128013

0 commit comments

Comments
 (0)