3636#include " llvm/Support/Regex.h"
3737#include " llvm/Support/StringSaver.h"
3838#include " llvm/Support/LockFileManager.h"
39+ #include " llvm/ADT/STLExtras.h"
3940
4041using namespace swift ;
4142using FileDependency = SerializationOptions::FileDependency;
@@ -152,6 +153,32 @@ bool ModuleInterfaceBuilder::collectDepsForSerialization(
152153 return false ;
153154}
154155
156+ struct ErrorDowngradeConsumerRAII : DiagnosticConsumer {
157+ DiagnosticEngine &Diag;
158+ std::vector<DiagnosticConsumer *> allConsumers;
159+ bool SeenError;
160+ ErrorDowngradeConsumerRAII (DiagnosticEngine &Diag): Diag(Diag),
161+ allConsumers (Diag.takeConsumers()), SeenError(false ) {
162+ Diag.addConsumer (*this );
163+ }
164+ ~ErrorDowngradeConsumerRAII () {
165+ for (auto *consumer: allConsumers) {
166+ Diag.addConsumer (*consumer);
167+ }
168+ Diag.removeConsumer (*this );
169+ }
170+ void handleDiagnostic (SourceManager &SM, const DiagnosticInfo &Info) override {
171+ DiagnosticInfo localInfo (Info);
172+ if (localInfo.Kind == DiagnosticKind::Error) {
173+ localInfo.Kind = DiagnosticKind::Warning;
174+ SeenError = true ;
175+ for (auto *consumer: allConsumers) {
176+ consumer->handleDiagnostic (SM, localInfo);
177+ }
178+ }
179+ }
180+ };
181+
155182bool ModuleInterfaceBuilder::buildSwiftModuleInternal (
156183 StringRef OutPath, bool ShouldSerializeDeps,
157184 std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
@@ -204,6 +231,12 @@ bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
204231 LLVM_DEBUG (llvm::dbgs () << " Setting up instance to compile "
205232 << InPath << " to " << OutPath << " \n " );
206233
234+ LLVM_DEBUG (llvm::dbgs () << " Performing sema\n " );
235+ if (isTypeChecking && FEOpts.DowngradeInterfaceVerificationError ) {
236+ ErrorDowngradeConsumerRAII R (SubInstance.getDiags ());
237+ SubInstance.performSema ();
238+ return std::error_code ();
239+ }
207240 SWIFT_DEFER {
208241 // Make sure to emit a generic top-level error if a module fails to
209242 // load. This is not only good for users; it also makes sure that we've
@@ -225,12 +258,14 @@ bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
225258 }
226259 };
227260
228- LLVM_DEBUG (llvm::dbgs () << " Performing sema\n " );
229261 SubInstance.performSema ();
230262 if (SubInstance.getASTContext ().hadError ()) {
231263 LLVM_DEBUG (llvm::dbgs () << " encountered errors\n " );
232264 return std::make_error_code (std::errc::not_supported);
233265 }
266+ // If we are just type-checking the interface, we are done.
267+ if (isTypeChecking)
268+ return std::error_code ();
234269
235270 SILOptions &SILOpts = subInvocation.getSILOptions ();
236271 auto Mod = SubInstance.getMainModule ();
@@ -268,9 +303,6 @@ bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
268303 SerializationOpts.IsOSSA = SILOpts.EnableOSSAModules ;
269304
270305 SILMod->setSerializeSILAction ([&]() {
271- if (isTypeChecking)
272- return ;
273-
274306 // We don't want to serialize module docs in the cache -- they
275307 // will be serialized beside the interface file.
276308 serializeToBuffers (Mod, SerializationOpts, ModuleBuffer,
0 commit comments