Skip to content

Eng/pr swift frontend tweaks for caching #65925

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions include/swift/ClangImporter/ClangImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,8 @@ class ClangImporter final : public ClangModuleLoader {
/// replica.
///
/// \sa clang::GeneratePCHAction
bool emitBridgingPCH(StringRef headerPath, StringRef outputPCHPath);
bool emitBridgingPCH(StringRef headerPath, StringRef outputPCHPath,
bool cached);

/// Returns true if a clang CompilerInstance can successfully read in a PCH,
/// assuming it exists, with the current options. This can be used to find out
Expand Down Expand Up @@ -505,7 +506,7 @@ class ClangImporter final : public ClangModuleLoader {

Optional<std::string>
getOrCreatePCH(const ClangImporterOptions &ImporterOptions,
StringRef SwiftPCHHash);
StringRef SwiftPCHHash, bool Cached);
Optional<std::string>
/// \param isExplicit true if the PCH filename was passed directly
/// with -import-objc-header option.
Expand Down
47 changes: 28 additions & 19 deletions lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ namespace {
Importer.addSearchPath(path, /*isFramework*/false, /*isSystem=*/false);
}

auto PCH = Importer.getOrCreatePCH(ImporterOpts, SwiftPCHHash);
auto PCH =
Importer.getOrCreatePCH(ImporterOpts, SwiftPCHHash, /*Cached=*/true);
if (PCH.has_value()) {
Impl.getClangInstance()->getPreprocessorOpts().ImplicitPCHInclude =
PCH.value();
Expand Down Expand Up @@ -546,8 +547,10 @@ importer::getNormalInvocationArguments(
});
}

if (auto path = getCxxShimModuleMapPath(searchPathOpts, triple)) {
invocationArgStrs.push_back((Twine("-fmodule-map-file=") + *path).str());
if (LangOpts.EnableCXXInterop) {
if (auto path = getCxxShimModuleMapPath(searchPathOpts, triple)) {
invocationArgStrs.push_back((Twine("-fmodule-map-file=") + *path).str());
}
}

// Set C language options.
Expand Down Expand Up @@ -942,8 +945,9 @@ ClangImporter::getPCHFilename(const ClangImporterOptions &ImporterOptions,
return PCHFilename.str().str();
}

Optional<std::string> ClangImporter::getOrCreatePCH(
const ClangImporterOptions &ImporterOptions, StringRef SwiftPCHHash) {
Optional<std::string>
ClangImporter::getOrCreatePCH(const ClangImporterOptions &ImporterOptions,
StringRef SwiftPCHHash, bool Cached) {
bool isExplicit;
auto PCHFilename = getPCHFilename(ImporterOptions, SwiftPCHHash,
isExplicit);
Expand All @@ -959,8 +963,8 @@ Optional<std::string> ClangImporter::getOrCreatePCH(
<< EC.message();
return None;
}
auto FailedToEmit =
emitBridgingPCH(ImporterOptions.BridgingHeader, PCHFilename.value());
auto FailedToEmit = emitBridgingPCH(ImporterOptions.BridgingHeader,
PCHFilename.value(), Cached);
if (FailedToEmit) {
return None;
}
Expand All @@ -972,9 +976,10 @@ Optional<std::string> ClangImporter::getOrCreatePCH(
std::vector<std::string>
ClangImporter::getClangArguments(ASTContext &ctx) {
std::vector<std::string> invocationArgStrs;
// Clang expects this to be like an actual command line. So we need to pass in
// "clang" for argv[0]
invocationArgStrs.push_back(ctx.ClangImporterOpts.clangPath);
// When creating from driver commands, clang expects this to be like an actual
// command line. So we need to pass in "clang" for argv[0]
if (!ctx.ClangImporterOpts.DirectClangCC1ModuleBuild)
invocationArgStrs.push_back(ctx.ClangImporterOpts.clangPath);
if (ctx.ClangImporterOpts.ExtraArgsOnly) {
invocationArgStrs.insert(invocationArgStrs.end(),
ctx.ClangImporterOpts.ExtraArgs.begin(),
Expand Down Expand Up @@ -1702,13 +1707,13 @@ ClangImporter::cloneCompilerInstanceForPrecompiling() {
}

bool ClangImporter::emitBridgingPCH(
StringRef headerPath, StringRef outputPCHPath) {
StringRef headerPath, StringRef outputPCHPath, bool cached) {
auto emitInstance = cloneCompilerInstanceForPrecompiling();
auto &invocation = emitInstance->getInvocation();

auto LangOpts = invocation.getLangOpts();
LangOpts->NeededByPCHOrCompilationUsesPCH = true;
LangOpts->CacheGeneratedPCH = true;
LangOpts->CacheGeneratedPCH = cached;

auto language = getLanguageFromOptions(LangOpts);
auto inputFile = clang::FrontendInputFile(headerPath, language);
Expand Down Expand Up @@ -1959,12 +1964,16 @@ ModuleDecl *ClangImporter::Implementation::loadModuleClang(
auto &clangHeaderSearch = getClangPreprocessor().getHeaderSearchInfo();
auto realModuleName = SwiftContext.getRealModuleName(path.front().Item).str();

// Look up the top-level module first, to see if it exists at all.
clang::Module *clangModule = clangHeaderSearch.lookupModule(
realModuleName, /*ImportLoc=*/clang::SourceLocation(),
/*AllowSearch=*/true, /*AllowExtraModuleMapSearch=*/true);
if (!clangModule)
return nullptr;
// For explicit module build, module should always exist but module map might
// not be exist. Go straight to module loader.
if (Instance->getInvocation().getLangOpts()->ImplicitModules) {
// Look up the top-level module first, to see if it exists at all.
clang::Module *clangModule = clangHeaderSearch.lookupModule(
realModuleName, /*ImportLoc=*/clang::SourceLocation(),
/*AllowSearch=*/true, /*AllowExtraModuleMapSearch=*/true);
if (!clangModule)
return nullptr;
}

// Convert the Swift import path over to a Clang import path.
SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>, 4>
Expand Down Expand Up @@ -2019,7 +2028,7 @@ ModuleDecl *ClangImporter::Implementation::loadModuleClang(

// Now load the top-level module, so that we can check if the submodule
// exists without triggering a fatal error.
clangModule = loadModule(clangPath.front(), clang::Module::AllVisible);
auto clangModule = loadModule(clangPath.front(), clang::Module::AllVisible);
if (!clangModule)
return nullptr;

Expand Down
10 changes: 8 additions & 2 deletions lib/FrontendTool/FrontendTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,13 @@ static bool precompileBridgingHeader(const CompilerInstance &Instance) {
if (!PCHOutDir.empty()) {
// Create or validate a persistent PCH.
auto SwiftPCHHash = Invocation.getPCHHash();
auto PCH = clangImporter->getOrCreatePCH(ImporterOpts, SwiftPCHHash);
auto PCH = clangImporter->getOrCreatePCH(ImporterOpts, SwiftPCHHash,
/*cached=*/false);
return !PCH.has_value();
}
return clangImporter->emitBridgingPCH(
opts.InputsAndOutputs.getFilenameOfFirstInput(),
opts.InputsAndOutputs.getSingleOutputFilename());
opts.InputsAndOutputs.getSingleOutputFilename(), /*cached=*/false);
}

static bool precompileClangModule(const CompilerInstance &Instance) {
Expand Down Expand Up @@ -2075,6 +2076,11 @@ int swift::performFrontend(ArrayRef<const char *> Args,
auto finishDiagProcessing = [&](int retValue, bool verifierEnabled) -> int {
FinishDiagProcessingCheckRAII.CalledFinishDiagProcessing = true;
PDC.setSuppressOutput(false);
if (auto *CDP = Instance->getCachingDiagnosticsProcessor()) {
// Don't cache if build failed.
if (retValue)
CDP->endDiagnosticCapture();
}
bool diagnosticsError = Instance->getDiags().finishProcessing();
// If the verifier is enabled and did not encounter any verification errors,
// return 0 even if the compile failed. This behavior isn't ideal, but large
Expand Down
6 changes: 3 additions & 3 deletions test/CAS/loc-directive-diagnostics.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %empty-directory(%t)
// RUN: not %target-swift-frontend -emit-module -emit-module-path %t/test.module \
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/test.module \
// RUN: -enable-cas -cas-path %t/cas -allow-unstable-cache-key-for-testing %s 2>&1 | %FileCheck %s
// RUN: %cache-tool -cas-path %t/cas -cache-tool-action print-output-keys -- \
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/test.module -enable-cas -cas-path %t/cas \
Expand All @@ -9,7 +9,7 @@
// RUN: -allow-unstable-cache-key-for-testing %s 2>&1 | %FileCheck %s

#sourceLocation(file: "anything.swift", line: 1)
func 1() {}
#warning("this is a warning")
#sourceLocation()

// CHECK: anything.swift:1:6: error: function name
// CHECK: anything.swift:1:10: warning: this is a warning
4 changes: 2 additions & 2 deletions test/ClangImporter/pcm-emit-direct-cc1-mode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
// CHECK-DUMP: Module map file: {{.*[/\\]}}Inputs{{/|\\}}custom-modules{{/|\\}}module.map

// Verify that the clang command-line used is cc1
// RUN: %FileCheck -check-prefix CHECK-CLANG %s < %t.diags.txt
// CHECK-CLANG: '{{.*[/\\]}}clang'{{.*}}'-fmodules'
// RUN: %FileCheck -check-prefix CHECK-CLANG -DTRIPLE=%target-triple %s < %t.diags.txt
// CHECK-CLANG: '{{.*[/\\]}}module.map' '-o' '{{.*[/\\]}}script.pcm' '-fmodules' '-triple' '[[TRIPLE]]' '-x' 'objective-c'

import script
var _ : ScriptTy
2 changes: 1 addition & 1 deletion unittests/ClangImporter/ClangImporterTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ TEST(ClangImporterTest, emitPCHInMemory) {

std::string PCH = createFilename(cache, "bridging.h.pch");
ASSERT_FALSE(importer->canReadPCH(PCH));
ASSERT_FALSE(importer->emitBridgingPCH(options.BridgingHeader, PCH));
ASSERT_FALSE(importer->emitBridgingPCH(options.BridgingHeader, PCH, true));
ASSERT_TRUE(importer->canReadPCH(PCH));

// Overwrite the PCH with garbage. We should still be able to read it from
Expand Down