Skip to content

Commit 13cb4a4

Browse files
authored
Merge pull request #31553 from nkcsgexi/62612027
DependencyScanner: honor additional compiler flags in interfaces files when collecting imports
2 parents 1d5b70f + 3cb8d8e commit 13cb4a4

File tree

16 files changed

+220
-77
lines changed

16 files changed

+220
-77
lines changed

include/swift/AST/ASTContext.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ namespace swift {
121121
class UnifiedStatsReporter;
122122
class IndexSubset;
123123
struct SILAutoDiffDerivativeFunctionKey;
124+
struct SubASTContextDelegate;
124125

125126
enum class KnownProtocolKind : uint8_t;
126127

@@ -719,7 +720,8 @@ class ASTContext final {
719720
Optional<ModuleDependencies> getModuleDependencies(
720721
StringRef moduleName,
721722
bool isUnderlyingClangModule,
722-
ModuleDependenciesCache &cache);
723+
ModuleDependenciesCache &cache,
724+
SubASTContextDelegate &delegate);
723725

724726
/// Load extensions to the given nominal type from the external
725727
/// module loaders.

include/swift/AST/ModuleLoader.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/ADT/SmallSet.h"
2626
#include "llvm/ADT/StringSet.h"
2727
#include "llvm/ADT/TinyPtrVector.h"
28+
#include "swift/AST/ModuleDependencies.h"
2829

2930
namespace llvm {
3031
class FileCollector;
@@ -84,6 +85,15 @@ class DependencyTracker {
8485
std::shared_ptr<clang::DependencyCollector> getClangCollector();
8586
};
8687

88+
/// Abstract interface to run an action in a sub ASTContext.
89+
struct SubASTContextDelegate {
90+
virtual bool runInSubContext(ASTContext &ctx, StringRef interfacePath,
91+
llvm::function_ref<bool(ASTContext&)> action) {
92+
llvm_unreachable("function should be overriden");
93+
}
94+
virtual ~SubASTContextDelegate() = default;
95+
};
96+
8797
/// Abstract interface that loads named modules into the AST.
8898
class ModuleLoader {
8999
virtual void anchor();
@@ -186,7 +196,7 @@ class ModuleLoader {
186196
/// if no such module exists.
187197
virtual Optional<ModuleDependencies> getModuleDependencies(
188198
StringRef moduleName,
189-
ModuleDependenciesCache &cache) = 0;
199+
ModuleDependenciesCache &cache, SubASTContextDelegate &delegate) = 0;
190200
};
191201

192202
} // namespace swift

include/swift/ClangImporter/ClangImporter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,8 @@ class ClangImporter final : public ClangModuleLoader {
370370
void verifyAllModules() override;
371371

372372
Optional<ModuleDependencies> getModuleDependencies(
373-
StringRef moduleName, ModuleDependenciesCache &cache) override;
373+
StringRef moduleName, ModuleDependenciesCache &cache,
374+
SubASTContextDelegate &delegate) override;
374375

375376
/// Add dependency information for the bridging header.
376377
///

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
#include "swift/Basic/LLVM.h"
111111
#include "swift/Frontend/ModuleInterfaceSupport.h"
112112
#include "swift/Serialization/SerializedModuleLoader.h"
113+
#include "llvm/Support/StringSaver.h"
113114

114115
namespace clang {
115116
class CompilerInstance;
@@ -123,6 +124,7 @@ namespace swift {
123124

124125
class LangOptions;
125126
class SearchPathOptions;
127+
class CompilerInvocation;
126128

127129
/// A ModuleLoader that runs a subordinate \c CompilerInvocation and
128130
/// \c CompilerInstance to convert .swiftinterface files to .swiftmodule
@@ -201,6 +203,18 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
201203
std::string
202204
getModuleCachePathFromClang(const clang::CompilerInstance &Instance);
203205

206+
bool extractSwiftInterfaceVersionAndArgs(SourceManager &SM,
207+
DiagnosticEngine &Diags,
208+
StringRef InterfacePath,
209+
version::Version &Vers,
210+
StringRef &CompilerVersion,
211+
llvm::StringSaver &SubArgSaver,
212+
SmallVectorImpl<const char *> &SubArgs,
213+
SourceLoc diagnosticLoc = SourceLoc());
214+
215+
void inheritOptionsForBuildingInterface(CompilerInvocation &Invok,
216+
const SearchPathOptions &SearchPathOpts,
217+
const LangOptions &LangOpts);
204218
}
205219

206220
#endif

include/swift/Sema/SourceLoader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ class SourceLoader : public ModuleLoader {
9393
}
9494

9595
Optional<ModuleDependencies> getModuleDependencies(
96-
StringRef moduleName, ModuleDependenciesCache &cache) override {
96+
StringRef moduleName, ModuleDependenciesCache &cache,
97+
SubASTContextDelegate &delegate) override {
9798
// FIXME: Implement?
9899
return None;
99100
}

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,8 @@ class SerializedModuleLoaderBase : public ModuleLoader {
194194
virtual void verifyAllModules() override;
195195

196196
virtual Optional<ModuleDependencies> getModuleDependencies(
197-
StringRef moduleName, ModuleDependenciesCache &cache) override;
197+
StringRef moduleName, ModuleDependenciesCache &cache,
198+
SubASTContextDelegate &delegate) override;
198199
};
199200

200201
/// Imports serialized Swift modules into an ASTContext.

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,13 +1462,14 @@ void ASTContext::addModuleLoader(std::unique_ptr<ModuleLoader> loader,
14621462

14631463
Optional<ModuleDependencies> ASTContext::getModuleDependencies(
14641464
StringRef moduleName, bool isUnderlyingClangModule,
1465-
ModuleDependenciesCache &cache) {
1465+
ModuleDependenciesCache &cache, SubASTContextDelegate &delegate) {
14661466
for (auto &loader : getImpl().ModuleLoaders) {
14671467
if (isUnderlyingClangModule &&
14681468
loader.get() != getImpl().TheClangModuleLoader)
14691469
continue;
14701470

1471-
if (auto dependencies = loader->getModuleDependencies(moduleName, cache))
1471+
if (auto dependencies = loader->getModuleDependencies(moduleName, cache,
1472+
delegate))
14721473
return dependencies;
14731474
}
14741475

lib/ClangImporter/ClangModuleDependencyScanner.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ static void recordModuleDependencies(
224224
}
225225

226226
Optional<ModuleDependencies> ClangImporter::getModuleDependencies(
227-
StringRef moduleName, ModuleDependenciesCache &cache) {
227+
StringRef moduleName, ModuleDependenciesCache &cache,
228+
SubASTContextDelegate &delegate) {
228229
// Check whether there is already a cached result.
229230
if (auto found = cache.findDependencies(
230231
moduleName, ModuleDependenciesKind::Clang))

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#define DEBUG_TYPE "textual-module-interface"
1414

15+
#include "swift/Frontend/ModuleInterfaceLoader.h"
1516
#include "ModuleInterfaceBuilder.h"
1617
#include "swift/AST/ASTContext.h"
1718
#include "swift/AST/DiagnosticsFrontend.h"
@@ -82,19 +83,37 @@ void ModuleInterfaceBuilder::configureSubInvocationInputsAndOutputs(
8283
.setMainAndSupplementaryOutputs({MainOut}, {SOPs});
8384
}
8485

85-
void ModuleInterfaceBuilder::configureSubInvocation(
86+
void swift::inheritOptionsForBuildingInterface(
87+
CompilerInvocation &Invok,
8688
const SearchPathOptions &SearchPathOpts,
87-
const LangOptions &LangOpts,
88-
ClangModuleLoader *ClangLoader) {
89+
const LangOptions &LangOpts) {
8990
// Start with a SubInvocation that copies various state from our
9091
// invoking ASTContext.
91-
subInvocation.setImportSearchPaths(SearchPathOpts.ImportSearchPaths);
92-
subInvocation.setFrameworkSearchPaths(SearchPathOpts.FrameworkSearchPaths);
93-
subInvocation.setSDKPath(SearchPathOpts.SDKPath);
94-
subInvocation.setInputKind(InputFileKind::SwiftModuleInterface);
95-
subInvocation.setRuntimeResourcePath(SearchPathOpts.RuntimeResourcePath);
96-
subInvocation.setTargetTriple(LangOpts.Target);
92+
Invok.setImportSearchPaths(SearchPathOpts.ImportSearchPaths);
93+
Invok.setFrameworkSearchPaths(SearchPathOpts.FrameworkSearchPaths);
94+
Invok.setSDKPath(SearchPathOpts.SDKPath);
95+
Invok.setInputKind(InputFileKind::SwiftModuleInterface);
96+
Invok.setRuntimeResourcePath(SearchPathOpts.RuntimeResourcePath);
97+
Invok.setTargetTriple(LangOpts.Target);
98+
99+
// Inhibit warnings from the SubInvocation since we are assuming the user
100+
// is not in a position to fix them.
101+
Invok.getDiagnosticOptions().SuppressWarnings = true;
102+
103+
// Inherit this setting down so that it can affect error diagnostics (mostly
104+
// by making them non-fatal).
105+
Invok.getLangOptions().DebuggerSupport = LangOpts.DebuggerSupport;
97106

107+
// Disable this; deinitializers always get printed with `@objc` even in
108+
// modules that don't import Foundation.
109+
Invok.getLangOptions().EnableObjCAttrRequiresFoundation = false;
110+
}
111+
112+
void ModuleInterfaceBuilder::configureSubInvocation(
113+
const SearchPathOptions &SearchPathOpts,
114+
const LangOptions &LangOpts,
115+
ClangModuleLoader *ClangLoader) {
116+
inheritOptionsForBuildingInterface(subInvocation, SearchPathOpts, LangOpts);
98117
subInvocation.setModuleName(moduleName);
99118
subInvocation.setClangModuleCachePath(moduleCachePath);
100119
subInvocation.getFrontendOptions().PrebuiltModuleCachePath =
@@ -111,18 +130,6 @@ void ModuleInterfaceBuilder::configureSubInvocation(
111130
}
112131
}
113132

114-
// Inhibit warnings from the SubInvocation since we are assuming the user
115-
// is not in a position to fix them.
116-
subInvocation.getDiagnosticOptions().SuppressWarnings = true;
117-
118-
// Inherit this setting down so that it can affect error diagnostics (mostly
119-
// by making them non-fatal).
120-
subInvocation.getLangOptions().DebuggerSupport = LangOpts.DebuggerSupport;
121-
122-
// Disable this; deinitializers always get printed with `@objc` even in
123-
// modules that don't import Foundation.
124-
subInvocation.getLangOptions().EnableObjCAttrRequiresFoundation = false;
125-
126133
// Tell the subinvocation to serialize dependency hashes if asked to do so.
127134
auto &frontendOpts = subInvocation.getFrontendOptions();
128135
frontendOpts.SerializeModuleInterfaceDependencyHashes =
@@ -134,35 +141,44 @@ void ModuleInterfaceBuilder::configureSubInvocation(
134141
remarkOnRebuildFromInterface;
135142
}
136143

137-
bool ModuleInterfaceBuilder::extractSwiftInterfaceVersionAndArgs(
138-
swift::version::Version &Vers, StringRef &CompilerVersion,
139-
llvm::StringSaver &SubArgSaver, SmallVectorImpl<const char *> &SubArgs) {
140-
llvm::vfs::FileSystem &fs = *sourceMgr.getFileSystem();
141-
auto FileOrError = swift::vfs::getFileOrSTDIN(fs, interfacePath);
144+
bool swift::extractSwiftInterfaceVersionAndArgs(
145+
SourceManager &SM,
146+
DiagnosticEngine &Diags,
147+
StringRef InterfacePath,
148+
version::Version &Vers,
149+
StringRef &CompilerVersion,
150+
llvm::StringSaver &SubArgSaver,
151+
SmallVectorImpl<const char *> &SubArgs,
152+
SourceLoc diagnosticLoc) {
153+
llvm::vfs::FileSystem &fs = *SM.getFileSystem();
154+
auto FileOrError = swift::vfs::getFileOrSTDIN(fs, InterfacePath);
142155
if (!FileOrError) {
143156
// Don't use this->diagnose() because it'll just try to re-open
144157
// interfacePath.
145-
diags.diagnose(diagnosticLoc, diag::error_open_input_file,
146-
interfacePath, FileOrError.getError().message());
158+
Diags.diagnose(diagnosticLoc, diag::error_open_input_file,
159+
InterfacePath, FileOrError.getError().message());
147160
return true;
148161
}
149162
auto SB = FileOrError.get()->getBuffer();
150163
auto VersRe = getSwiftInterfaceFormatVersionRegex();
151164
auto CompRe = getSwiftInterfaceCompilerVersionRegex();
152165
auto FlagRe = getSwiftInterfaceModuleFlagsRegex();
153166
SmallVector<StringRef, 1> VersMatches, FlagMatches, CompMatches;
167+
154168
if (!VersRe.match(SB, &VersMatches)) {
155-
diagnose(diag::error_extracting_version_from_module_interface);
169+
ModuleInterfaceBuilder::diagnose(Diags, SM, InterfacePath, diagnosticLoc,
170+
diag::error_extracting_version_from_module_interface);
156171
return true;
157172
}
158173
if (!FlagRe.match(SB, &FlagMatches)) {
159-
diagnose(diag::error_extracting_flags_from_module_interface);
174+
ModuleInterfaceBuilder::diagnose(Diags, SM, InterfacePath, diagnosticLoc,
175+
diag::error_extracting_version_from_module_interface);
160176
return true;
161177
}
162178
assert(VersMatches.size() == 2);
163179
assert(FlagMatches.size() == 2);
164180
// FIXME We should diagnose this at a location that makes sense:
165-
Vers = swift::version::Version(VersMatches[1], SourceLoc(), &diags);
181+
Vers = swift::version::Version(VersMatches[1], SourceLoc(), &Diags);
166182
llvm::cl::TokenizeGNUCommandLine(FlagMatches[1], SubArgSaver, SubArgs);
167183

168184
if (CompRe.match(SB, &CompMatches)) {
@@ -177,6 +193,13 @@ bool ModuleInterfaceBuilder::extractSwiftInterfaceVersionAndArgs(
177193
return false;
178194
}
179195

196+
bool ModuleInterfaceBuilder::extractSwiftInterfaceVersionAndArgs(
197+
swift::version::Version &Vers, StringRef &CompilerVersion,
198+
llvm::StringSaver &SubArgSaver, SmallVectorImpl<const char *> &SubArgs) {
199+
return swift::extractSwiftInterfaceVersionAndArgs(sourceMgr, diags,
200+
interfacePath, Vers, CompilerVersion, SubArgSaver, SubArgs, diagnosticLoc);
201+
}
202+
180203
bool ModuleInterfaceBuilder::collectDepsForSerialization(
181204
CompilerInstance &SubInstance, SmallVectorImpl<FileDependency> &Deps,
182205
bool IsHashBased) {

lib/Frontend/ModuleInterfaceBuilder.h

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,31 @@ class ModuleInterfaceBuilder {
4848
CompilerInvocation subInvocation;
4949
SmallVector<StringRef, 3> extraDependencies;
5050

51+
public:
5152
/// Emit a diagnostic tied to this declaration.
5253
template<typename ...ArgTypes>
53-
InFlightDiagnostic diagnose(
54+
static InFlightDiagnostic diagnose(
55+
DiagnosticEngine &Diags,
56+
SourceManager &SM,
57+
StringRef InterfacePath,
58+
SourceLoc Loc,
5459
Diag<ArgTypes...> ID,
55-
typename detail::PassArgument<ArgTypes>::type... Args) const {
56-
SourceLoc loc = diagnosticLoc;
57-
if (loc.isInvalid()) {
60+
typename detail::PassArgument<ArgTypes>::type... Args) {
61+
if (Loc.isInvalid()) {
5862
// Diagnose this inside the interface file, if possible.
59-
loc = sourceMgr.getLocFromExternalSource(interfacePath, 1, 1);
63+
Loc = SM.getLocFromExternalSource(InterfacePath, 1, 1);
6064
}
61-
return diags.diagnose(loc, ID, std::move(Args)...);
65+
return Diags.diagnose(Loc, ID, std::move(Args)...);
66+
}
67+
68+
private:
69+
/// Emit a diagnostic tied to this declaration.
70+
template<typename ...ArgTypes>
71+
InFlightDiagnostic diagnose(
72+
Diag<ArgTypes...> ID,
73+
typename detail::PassArgument<ArgTypes>::type... Args) const {
74+
return diagnose(diags, sourceMgr, interfacePath, diagnosticLoc,
75+
ID, std::move(Args)...);
6276
}
6377

6478
void configureSubInvocationInputsAndOutputs(StringRef OutPath);

0 commit comments

Comments
 (0)