Skip to content

Commit 9bc036c

Browse files
committed
DependencyScanner: honor additional compiler flags in interfaces files when collecting imports
Additional flags in interface files may change parsing behavior like #if statements. We should use a fresh ASTContext with these additional flags when parsing interface files to collect imports. rdar://62612027
1 parent d9b1d8f commit 9bc036c

File tree

16 files changed

+185
-56
lines changed

16 files changed

+185
-56
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: 9 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;
@@ -201,6 +202,14 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
201202
std::string
202203
getModuleCachePathFromClang(const clang::CompilerInstance &Instance);
203204

205+
bool extractSwiftInterfaceVersionAndArgs(SourceManager &SM,
206+
DiagnosticEngine &Diags,
207+
StringRef InterfacePath,
208+
version::Version &Vers,
209+
StringRef &CompilerVersion,
210+
llvm::StringSaver &SubArgSaver,
211+
SmallVectorImpl<const char *> &SubArgs,
212+
SourceLoc diagnosticLoc = SourceLoc());
204213
}
205214

206215
#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: 27 additions & 10 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"
@@ -134,35 +135,44 @@ void ModuleInterfaceBuilder::configureSubInvocation(
134135
remarkOnRebuildFromInterface;
135136
}
136137

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);
138+
bool swift::extractSwiftInterfaceVersionAndArgs(
139+
SourceManager &SM,
140+
DiagnosticEngine &Diags,
141+
StringRef InterfacePath,
142+
version::Version &Vers,
143+
StringRef &CompilerVersion,
144+
llvm::StringSaver &SubArgSaver,
145+
SmallVectorImpl<const char *> &SubArgs,
146+
SourceLoc diagnosticLoc) {
147+
llvm::vfs::FileSystem &fs = *SM.getFileSystem();
148+
auto FileOrError = swift::vfs::getFileOrSTDIN(fs, InterfacePath);
142149
if (!FileOrError) {
143150
// Don't use this->diagnose() because it'll just try to re-open
144151
// interfacePath.
145-
diags.diagnose(diagnosticLoc, diag::error_open_input_file,
146-
interfacePath, FileOrError.getError().message());
152+
Diags.diagnose(diagnosticLoc, diag::error_open_input_file,
153+
InterfacePath, FileOrError.getError().message());
147154
return true;
148155
}
149156
auto SB = FileOrError.get()->getBuffer();
150157
auto VersRe = getSwiftInterfaceFormatVersionRegex();
151158
auto CompRe = getSwiftInterfaceCompilerVersionRegex();
152159
auto FlagRe = getSwiftInterfaceModuleFlagsRegex();
153160
SmallVector<StringRef, 1> VersMatches, FlagMatches, CompMatches;
161+
154162
if (!VersRe.match(SB, &VersMatches)) {
155-
diagnose(diag::error_extracting_version_from_module_interface);
163+
ModuleInterfaceBuilder::diagnose(Diags, SM, InterfacePath, diagnosticLoc,
164+
diag::error_extracting_version_from_module_interface);
156165
return true;
157166
}
158167
if (!FlagRe.match(SB, &FlagMatches)) {
159-
diagnose(diag::error_extracting_flags_from_module_interface);
168+
ModuleInterfaceBuilder::diagnose(Diags, SM, InterfacePath, diagnosticLoc,
169+
diag::error_extracting_version_from_module_interface);
160170
return true;
161171
}
162172
assert(VersMatches.size() == 2);
163173
assert(FlagMatches.size() == 2);
164174
// FIXME We should diagnose this at a location that makes sense:
165-
Vers = swift::version::Version(VersMatches[1], SourceLoc(), &diags);
175+
Vers = swift::version::Version(VersMatches[1], SourceLoc(), &Diags);
166176
llvm::cl::TokenizeGNUCommandLine(FlagMatches[1], SubArgSaver, SubArgs);
167177

168178
if (CompRe.match(SB, &CompMatches)) {
@@ -177,6 +187,13 @@ bool ModuleInterfaceBuilder::extractSwiftInterfaceVersionAndArgs(
177187
return false;
178188
}
179189

190+
bool ModuleInterfaceBuilder::extractSwiftInterfaceVersionAndArgs(
191+
swift::version::Version &Vers, StringRef &CompilerVersion,
192+
llvm::StringSaver &SubArgSaver, SmallVectorImpl<const char *> &SubArgs) {
193+
return swift::extractSwiftInterfaceVersionAndArgs(sourceMgr, diags,
194+
interfacePath, Vers, CompilerVersion, SubArgSaver, SubArgs, diagnosticLoc);
195+
}
196+
180197
bool ModuleInterfaceBuilder::collectDepsForSerialization(
181198
CompilerInstance &SubInstance, SmallVectorImpl<FileDependency> &Deps,
182199
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)