|
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