22
22
#include " swift/AST/SILOptions.h"
23
23
#include " swift/Basic/Assertions.h"
24
24
#include " swift/Basic/LLVMInitialize.h"
25
+ #include " swift/Basic/QuotedString.h"
25
26
#include " swift/Frontend/DiagnosticVerifier.h"
26
27
#include " swift/Frontend/Frontend.h"
27
28
#include " swift/Frontend/PrintingDiagnosticConsumer.h"
49
50
#include < cstdio>
50
51
using namespace swift ;
51
52
53
+ namespace {
54
+ enum class SILOptStrictConcurrency {
55
+ None = 0 ,
56
+ Complete,
57
+ Targeted,
58
+ Minimal,
59
+ };
60
+ }
61
+
62
+ static std::optional<StrictConcurrency>
63
+ convertSILOptToRawStrictConcurrencyLevel (SILOptStrictConcurrency level) {
64
+ switch (level) {
65
+ case SILOptStrictConcurrency::None:
66
+ return {};
67
+ case SILOptStrictConcurrency::Complete:
68
+ return StrictConcurrency::Complete;
69
+ case SILOptStrictConcurrency::Targeted:
70
+ return StrictConcurrency::Targeted;
71
+ case SILOptStrictConcurrency::Minimal:
72
+ return StrictConcurrency::Minimal;
73
+ }
74
+ }
75
+
52
76
struct SILLLVMGenOptions {
53
77
llvm::cl::opt<std::string>
54
78
InputFilename = llvm::cl::opt<std::string>(llvm::cl::desc(" input file" ),
@@ -66,12 +90,29 @@ struct SILLLVMGenOptions {
66
90
FrameworkPaths = llvm::cl::list<std::string>(
67
91
" F" , llvm::cl::desc(" add a directory to the framework search path" ));
68
92
93
+ llvm::cl::list<std::string> VFSOverlays = llvm::cl::list<std::string>(
94
+ " vfsoverlay" , llvm::cl::desc(" add a VFS overlay" ));
95
+
69
96
llvm::cl::opt<std::string>
70
97
ModuleName = llvm::cl::opt<std::string>(" module-name" ,
71
98
llvm::cl::desc (" The name of the module if processing"
72
99
" a module. Necessary for processing "
73
100
" stdin." ));
74
101
102
+ llvm::cl::opt<bool > StrictImplicitModuleContext = llvm::cl::opt<bool >(
103
+ " strict-implicit-module-context" ,
104
+ llvm::cl::desc (" Enable the strict forwarding of compilation "
105
+ " context to downstream implicit module dependencies" ));
106
+
107
+ llvm::cl::opt<bool > DisableImplicitModules =
108
+ llvm::cl::opt<bool >(" disable-implicit-swift-modules" ,
109
+ llvm::cl::desc (" Disable implicit swift modules." ));
110
+
111
+ llvm::cl::opt<std::string> ExplicitSwiftModuleMapPath =
112
+ llvm::cl::opt<std::string>(
113
+ " explicit-swift-module-map-file" ,
114
+ llvm::cl::desc (" Explict swift module map file path" ));
115
+
75
116
llvm::cl::opt<std::string>
76
117
ResourceDir = llvm::cl::opt<std::string>(
77
118
" resource-dir" ,
@@ -114,11 +155,76 @@ struct SILLLVMGenOptions {
114
155
llvm::cl::opt<bool >
115
156
DisableLegacyTypeInfo = llvm::cl::opt<bool >(" disable-legacy-type-info" ,
116
157
llvm::cl::desc (" Don't try to load backward deployment layouts" ));
158
+
159
+ llvm::cl::opt<std::string> SwiftVersionString = llvm::cl::opt<std::string>(
160
+ " swift-version" ,
161
+ llvm::cl::desc (
162
+ " The swift version to assume AST declarations correspond to" ));
163
+
164
+ llvm::cl::opt<bool > EnableExperimentalConcurrency = llvm::cl::opt<bool >(
165
+ " enable-experimental-concurrency" ,
166
+ llvm::cl::desc (" Enable experimental concurrency model." ));
167
+
168
+ llvm::cl::opt<llvm::cl::boolOrDefault> EnableExperimentalMoveOnly =
169
+ llvm::cl::opt<llvm::cl::boolOrDefault>(
170
+ " enable-experimental-move-only" , llvm::cl::init(llvm::cl::BOU_UNSET),
171
+ llvm::cl::desc(" Enable experimental move-only semantics." ));
172
+
173
+ llvm::cl::list<std::string> ExperimentalFeatures =
174
+ llvm::cl::list<std::string>(
175
+ " enable-experimental-feature" ,
176
+ llvm::cl::desc (" Enable the given experimental feature." ));
177
+
178
+ llvm::cl::list<std::string> UpcomingFeatures = llvm::cl::list<std::string>(
179
+ " enable-upcoming-feature" ,
180
+ llvm::cl::desc (" Enable the given upcoming feature." ));
181
+
182
+ llvm::cl::opt<bool > EnableCxxInterop = llvm::cl::opt<bool >(
183
+ " enable-experimental-cxx-interop" , llvm::cl::desc(" Enable C++ interop." ),
184
+ llvm::cl::init (false ));
185
+
186
+ llvm::cl::opt<bool > EnableObjCInterop = llvm::cl::opt<bool >(
187
+ " enable-objc-interop" ,
188
+ llvm::cl::desc (" Enable Objective-C interoperability." ));
189
+
190
+ llvm::cl::opt<bool > DisableObjCInterop = llvm::cl::opt<bool >(
191
+ " disable-objc-interop" ,
192
+ llvm::cl::desc (" Disable Objective-C interoperability." ));
193
+
194
+ // Strict Concurrency
195
+ llvm::cl::opt<SILOptStrictConcurrency> StrictConcurrencyLevel =
196
+ llvm::cl::opt<SILOptStrictConcurrency>(
197
+ " strict-concurrency" , llvm::cl::desc(" strict concurrency level" ),
198
+ llvm::cl::init (SILOptStrictConcurrency::None),
199
+ llvm::cl::values(
200
+ clEnumValN (SILOptStrictConcurrency::Complete, " complete" ,
201
+ " Enable complete strict concurrency" ),
202
+ clEnumValN(SILOptStrictConcurrency::Targeted, " targeted" ,
203
+ " Enable targeted strict concurrency" ),
204
+ clEnumValN(SILOptStrictConcurrency::Minimal, " minimal" ,
205
+ " Enable minimal strict concurrency" ),
206
+ clEnumValN(SILOptStrictConcurrency::None, " disabled" ,
207
+ " Strict concurrency disabled" )));
117
208
};
118
209
210
+ static std::optional<bool > toOptionalBool (llvm::cl::boolOrDefault defaultable) {
211
+ switch (defaultable) {
212
+ case llvm::cl::BOU_TRUE:
213
+ return true ;
214
+ case llvm::cl::BOU_FALSE:
215
+ return false ;
216
+ case llvm::cl::BOU_UNSET:
217
+ return std::nullopt ;
218
+ }
219
+ llvm_unreachable (" Bad case for llvm::cl::boolOrDefault!" );
220
+ }
221
+
119
222
int sil_llvm_gen_main (ArrayRef<const char *> argv, void *MainAddr) {
120
223
INITIALIZE_LLVM ();
121
224
225
+ llvm::setBugReportMsg (SWIFT_CRASH_BUG_REPORT_MESSAGE " \n " );
226
+ llvm::EnablePrettyStackTraceOnSigInfoForThisThread ();
227
+
122
228
SILLLVMGenOptions options;
123
229
124
230
llvm::cl::ParseCommandLineOptions (argv.size (), argv.data (), " Swift LLVM IR Generator\n " );
@@ -141,6 +247,9 @@ int sil_llvm_gen_main(ArrayRef<const char *> argv, void *MainAddr) {
141
247
FramePaths.push_back ({path, /* isSystem=*/ false });
142
248
}
143
249
Invocation.setFrameworkSearchPaths (FramePaths);
250
+
251
+ Invocation.setVFSOverlays (options.VFSOverlays );
252
+
144
253
// Set the SDK path and target if given.
145
254
if (options.SDKPath .getNumOccurrences () == 0 ) {
146
255
const char *SDKROOT = getenv (" SDKROOT" );
@@ -153,17 +262,110 @@ int sil_llvm_gen_main(ArrayRef<const char *> argv, void *MainAddr) {
153
262
Invocation.setTargetTriple (options.Target );
154
263
if (!options.ResourceDir .empty ())
155
264
Invocation.setRuntimeResourcePath (options.ResourceDir );
265
+
266
+ Invocation.getFrontendOptions ().StrictImplicitModuleContext =
267
+ options.StrictImplicitModuleContext ;
268
+
269
+ Invocation.getFrontendOptions ().DisableImplicitModules =
270
+ options.DisableImplicitModules ;
271
+ Invocation.getSearchPathOptions ().ExplicitSwiftModuleMapPath =
272
+ options.ExplicitSwiftModuleMapPath ;
273
+
156
274
// Set the module cache path. If not passed in we use the default swift module
157
275
// cache.
158
276
Invocation.getClangImporterOptions ().ModuleCachePath = options.ModuleCachePath ;
159
277
Invocation.setParseStdlib ();
160
278
161
279
// Setup the language options
162
- auto &LangOpts = Invocation.getLangOptions ();
163
- LangOpts.DisableAvailabilityChecking = true ;
164
- LangOpts.EnableAccessControl = false ;
165
- LangOpts.EnableObjCAttrRequiresFoundation = false ;
166
- LangOpts.EnableObjCInterop = LangOpts.Target .isOSDarwin ();
280
+ if (options.SwiftVersionString .size ()) {
281
+ auto vers = VersionParser::parseVersionString (options.SwiftVersionString ,
282
+ SourceLoc (), nullptr );
283
+ bool isValid = false ;
284
+ if (vers.has_value ()) {
285
+ if (auto effectiveVers = vers.value ().getEffectiveLanguageVersion ()) {
286
+ Invocation.getLangOptions ().EffectiveLanguageVersion =
287
+ effectiveVers.value ();
288
+ isValid = true ;
289
+ }
290
+ }
291
+ if (!isValid) {
292
+ llvm::errs () << " error: invalid swift version "
293
+ << options.SwiftVersionString << ' \n ' ;
294
+ exit (-1 );
295
+ }
296
+ }
297
+ Invocation.getLangOptions ().DisableAvailabilityChecking = true ;
298
+ Invocation.getLangOptions ().EnableAccessControl = false ;
299
+ Invocation.getLangOptions ().EnableObjCAttrRequiresFoundation = false ;
300
+ Invocation.getLangOptions ().EnableDeserializationSafety = false ;
301
+ Invocation.getLangOptions ().EnableExperimentalConcurrency =
302
+ options.EnableExperimentalConcurrency ;
303
+ std::optional<bool > enableExperimentalMoveOnly =
304
+ toOptionalBool (options.EnableExperimentalMoveOnly );
305
+ if (enableExperimentalMoveOnly && *enableExperimentalMoveOnly) {
306
+ // FIXME: drop addition of Feature::MoveOnly once its queries are gone.
307
+ Invocation.getLangOptions ().enableFeature (Feature::MoveOnly);
308
+ Invocation.getLangOptions ().enableFeature (Feature::NoImplicitCopy);
309
+ Invocation.getLangOptions ().enableFeature (
310
+ Feature::OldOwnershipOperatorSpellings);
311
+ }
312
+
313
+ for (auto &featureName : options.UpcomingFeatures ) {
314
+ auto feature = Feature::getUpcomingFeature (featureName);
315
+ if (!feature) {
316
+ llvm::errs () << " error: unknown upcoming feature "
317
+ << QuotedString (featureName) << " \n " ;
318
+ exit (-1 );
319
+ }
320
+
321
+ if (auto firstVersion = feature->getLanguageVersion ()) {
322
+ if (Invocation.getLangOptions ().isSwiftVersionAtLeast (*firstVersion)) {
323
+ llvm::errs () << " error: upcoming feature " << QuotedString (featureName)
324
+ << " is already enabled as of Swift version "
325
+ << *firstVersion << ' \n ' ;
326
+ exit (-1 );
327
+ }
328
+ }
329
+ Invocation.getLangOptions ().enableFeature (*feature);
330
+ }
331
+
332
+ for (auto &featureName : options.ExperimentalFeatures ) {
333
+ if (auto feature = Feature::getExperimentalFeature (featureName)) {
334
+ Invocation.getLangOptions ().enableFeature (*feature);
335
+ } else {
336
+ llvm::errs () << " error: unknown experimental feature "
337
+ << QuotedString (featureName) << " \n " ;
338
+ exit (-1 );
339
+ }
340
+ }
341
+
342
+ // Enable strict concurrency if we have the feature specified or if it was
343
+ // specified via a command line option to sil-opt.
344
+ if (Invocation.getLangOptions ().hasFeature (Feature::StrictConcurrency)) {
345
+ Invocation.getLangOptions ().StrictConcurrencyLevel =
346
+ StrictConcurrency::Complete;
347
+ } else if (auto level = convertSILOptToRawStrictConcurrencyLevel (
348
+ options.StrictConcurrencyLevel )) {
349
+ // If strict concurrency was enabled from the cmdline so the feature flag as
350
+ // well.
351
+ if (*level == StrictConcurrency::Complete)
352
+ Invocation.getLangOptions ().enableFeature (Feature::StrictConcurrency);
353
+ Invocation.getLangOptions ().StrictConcurrencyLevel = *level;
354
+ }
355
+
356
+ // If we have strict concurrency set as a feature and were told to turn off
357
+ // region-based isolation... do so now.
358
+ if (Invocation.getLangOptions ().hasFeature (Feature::StrictConcurrency)) {
359
+ Invocation.getLangOptions ().enableFeature (Feature::RegionBasedIsolation);
360
+ }
361
+
362
+ Invocation.getLangOptions ().EnableObjCInterop =
363
+ options.EnableObjCInterop ? true
364
+ : options.DisableObjCInterop ? false
365
+ : llvm::Triple (options.Target ).isOSDarwin ();
366
+
367
+ Invocation.getLangOptions ().EnableCXXInterop = options.EnableCxxInterop ;
368
+ Invocation.computeCXXStdlibOptions ();
167
369
168
370
// Setup the IRGen Options.
169
371
IRGenOptions &Opts = Invocation.getIRGenOptions ();
0 commit comments