|
61 | 61 | #include "llvm/ADT/SmallPtrSet.h" |
62 | 62 | #include "llvm/ADT/StringExtras.h" |
63 | 63 | #include "llvm/ADT/TinyPtrVector.h" |
| 64 | +#include "llvm/Support/CommandLine.h" |
64 | 65 | #include "llvm/Support/MD5.h" |
65 | 66 | #include "llvm/Support/MemoryBuffer.h" |
66 | 67 | #include "llvm/Support/Path.h" |
@@ -4195,20 +4196,41 @@ version::Version ModuleDecl::getLanguageVersionBuiltWith() const { |
4195 | 4196 | // MARK: SwiftSettings |
4196 | 4197 | //===----------------------------------------------------------------------===// |
4197 | 4198 |
|
| 4199 | +static llvm::cl::opt<bool> AllowForDuplicateSwiftSettings( |
| 4200 | + "swift-settings-allow-duplicates", |
| 4201 | + llvm::cl::desc("Option that allows for duplicate SwiftSettings. Just for " |
| 4202 | + "compiler testing"), |
| 4203 | + llvm::cl::Hidden); |
| 4204 | + |
4198 | 4205 | namespace { |
4199 | 4206 |
|
4200 | 4207 | enum class SwiftSettingKind { |
4201 | 4208 | Unknown = 0, |
4202 | 4209 | DefaultIsolation, |
| 4210 | + |
| 4211 | + LastKind = DefaultIsolation, |
4203 | 4212 | }; |
4204 | 4213 |
|
4205 | 4214 | struct SwiftSettingsWalker : ASTWalker { |
4206 | 4215 | SourceFile &sf; |
4207 | 4216 | ASTContext &ctx; |
4208 | 4217 | SourceFileLangOptions result; |
4209 | 4218 |
|
| 4219 | + SmallVector<Expr *, 1> swiftSettingIndexToOriginalExprMap; |
| 4220 | + |
4210 | 4221 | SwiftSettingsWalker(SourceFile &sf, ASTContext &ctx) |
4211 | | - : sf(sf), ctx(ctx), result() {} |
| 4222 | + : sf(sf), ctx(ctx), result() { |
| 4223 | + // NOTE: We do not store a value for Unknown. |
| 4224 | + for (unsigned i : range(unsigned(SwiftSettingKind::LastKind))) { |
| 4225 | + (void)i; |
| 4226 | + swiftSettingIndexToOriginalExprMap.push_back(nullptr); |
| 4227 | + } |
| 4228 | + } |
| 4229 | + |
| 4230 | + Expr *&getOriginalSwiftSetting(SwiftSettingKind kind) { |
| 4231 | + assert(kind != SwiftSettingKind::Unknown); |
| 4232 | + return swiftSettingIndexToOriginalExprMap[unsigned(kind) - 1]; |
| 4233 | + } |
4212 | 4234 |
|
4213 | 4235 | /// Given a specific CallExpr, pattern matches the CallExpr's first argument |
4214 | 4236 | /// to validate it is MainActor.self. Returns CanType() if the CallExpr has |
@@ -4267,13 +4289,30 @@ struct SwiftSettingsWalker : ASTWalker { |
4267 | 4289 | continue; |
4268 | 4290 |
|
4269 | 4291 | case SwiftSettingKind::DefaultIsolation: |
| 4292 | + auto *&expr = |
| 4293 | + getOriginalSwiftSetting(SwiftSettingKind::DefaultIsolation); |
| 4294 | + |
| 4295 | + // If we already have an expr, emit an error and continue. |
| 4296 | + if (!AllowForDuplicateSwiftSettings && expr) { |
| 4297 | + ctx.Diags.diagnose(arg.getStartLoc(), |
| 4298 | + diag::swift_settings_duplicate_setting); |
| 4299 | + ctx.Diags.diagnose( |
| 4300 | + expr->getLoc(), |
| 4301 | + diag::swift_settings_duplicate_setting_original_loc); |
| 4302 | + foundValidArg = true; |
| 4303 | + continue; |
| 4304 | + } |
| 4305 | + |
| 4306 | + // Otherwise, set things up appropriately. |
4270 | 4307 | if (auto actor = patternMatchDefaultIsolationMainActor(callExpr)) { |
| 4308 | + expr = callExpr; |
4271 | 4309 | result.defaultIsolation = actor; |
4272 | 4310 | foundValidArg = true; |
4273 | 4311 | continue; |
4274 | 4312 | } |
4275 | 4313 |
|
4276 | 4314 | if (isa<NilLiteralExpr>(callExpr->getArgs()->getExpr(0))) { |
| 4315 | + expr = callExpr; |
4277 | 4316 | result.defaultIsolation = {Type()}; |
4278 | 4317 | foundValidArg = true; |
4279 | 4318 | continue; |
@@ -4344,7 +4383,7 @@ SwiftSettingsWalker::getSwiftSettingArgDecl(Argument arg) { |
4344 | 4383 | return {}; |
4345 | 4384 |
|
4346 | 4385 | // Now lookup our swiftSettingDecl. |
4347 | | - NominalTypeDecl *swiftSettingsDecl; |
| 4386 | + NominalTypeDecl *swiftSettingsDecl = nullptr; |
4348 | 4387 | { |
4349 | 4388 | SmallVector<ValueDecl *, 1> decls; |
4350 | 4389 | ctx.lookupInSwiftModule("SwiftSetting", decls); |
|
0 commit comments