From 8572b7e38cba2974ef2c1f29194c70fdbb4244a7 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Tue, 2 Dec 2025 17:13:08 +0000 Subject: [PATCH] Address `llvm::StringSwitch` deprecations in advance There's a whole bunch of these, e.g. - https://github.com/llvm/llvm-project/pull/163405 - https://github.com/llvm/llvm-project/pull/164276 - https://github.com/llvm/llvm-project/pull/165119 - https://github.com/llvm/llvm-project/pull/166016 - https://github.com/llvm/llvm-project/pull/166066 --- include/swift/Demangling/TypeDecoder.h | 4 +- lib/Basic/Platform.cpp | 41 +++++---- lib/ClangImporter/ClangImporter.cpp | 14 +-- lib/Driver/Driver.cpp | 8 +- lib/Driver/WindowsToolChains.cpp | 4 +- lib/Frontend/CompilerInvocation.cpp | 7 +- lib/Parse/ParseDecl.cpp | 13 +-- lib/PrintAsClang/PrintAsClang.cpp | 2 +- stdlib/include/llvm/ADT/StringSwitch.h | 121 ++++++++++--------------- 9 files changed, 95 insertions(+), 119 deletions(-) diff --git a/include/swift/Demangling/TypeDecoder.h b/include/swift/Demangling/TypeDecoder.h index 77bb3bc6ccd8e..e5811d7ff6fe3 100644 --- a/include/swift/Demangling/TypeDecoder.h +++ b/include/swift/Demangling/TypeDecoder.h @@ -539,8 +539,8 @@ void decodeRequirement( .Case("D", LayoutConstraintKind::NativeClass) .Case("T", LayoutConstraintKind::Trivial) .Case("B", LayoutConstraintKind::BridgeObject) - .Cases("E", "e", LayoutConstraintKind::TrivialOfExactSize) - .Cases("M", "m", LayoutConstraintKind::TrivialOfAtMostSize) + .Cases({"E", "e"}, LayoutConstraintKind::TrivialOfExactSize) + .Cases({"M", "m"}, LayoutConstraintKind::TrivialOfAtMostSize) .Case("S", LayoutConstraintKind::TrivialStride) .Default(std::nullopt); diff --git a/lib/Basic/Platform.cpp b/lib/Basic/Platform.cpp index c7f0bfa2757aa..ee9f2ffeb8633 100644 --- a/lib/Basic/Platform.cpp +++ b/lib/Basic/Platform.cpp @@ -367,18 +367,18 @@ getArchForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) { auto tripleArchName = triple.getArchName(); return llvm::StringSwitch(tripleArchName) - .Cases("arm64", "aarch64", "arm64") - .Cases("arm64_32", "aarch64_32", "arm64_32") - .Cases("x86_64", "amd64", "x86_64") - .Cases("i386", "i486", "i586", "i686", "i786", "i886", "i986", - "i386") - .Cases("unknown", "", "unknown") - // These values are also supported, but are handled by the default case below: - // .Case ("armv7s", "armv7s") - // .Case ("armv7k", "armv7k") - // .Case ("armv7", "armv7") - // .Case ("arm64e", "arm64e") - .Default(tripleArchName); + .Cases({"arm64", "aarch64"}, "arm64") + .Cases({"arm64_32", "aarch64_32"}, "arm64_32") + .Cases({"x86_64", "amd64"}, "x86_64") + .Cases({"i386", "i486", "i586", "i686", "i786", "i886", "i986"}, "i386") + .Cases({"unknown", ""}, "unknown") + // These values are also supported, but are handled by the default case + // below: + // .Case ("armv7s", "armv7s") + // .Case ("armv7k", "armv7k") + // .Case ("armv7", "armv7") + // .Case ("arm64e", "arm64e") + .Default(tripleArchName); } static StringRef @@ -405,20 +405,21 @@ getOSForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) { auto tripleOSNameNoVersion = tripleOSName.take_until(llvm::isDigit); return llvm::StringSwitch(tripleOSNameNoVersion) - .Cases("macos", "macosx", "darwin", "macos") - .Cases("unknown", "", "unknown") - // These values are also supported, but are handled by the default case below: - // .Case ("ios", "ios") - // .Case ("tvos", "tvos") - // .Case ("watchos", "watchos") - .Default(tripleOSNameNoVersion); + .Cases({"macos", "macosx", "darwin"}, "macos") + .Cases({"unknown", ""}, "unknown") + // These values are also supported, but are handled by the default case + // below: + // .Case ("ios", "ios") + // .Case ("tvos", "tvos") + // .Case ("watchos", "watchos") + .Default(tripleOSNameNoVersion); } static std::optional getEnvironmentForAppleTargetSpecificModuleTriple(const llvm::Triple &triple) { auto tripleEnvironment = triple.getEnvironmentName(); return llvm::StringSwitch>(tripleEnvironment) - .Cases("unknown", "", std::nullopt) + .Cases({"unknown", ""}, std::nullopt) // These values are also supported, but are handled by the default case // below: // .Case ("simulator", StringRef("simulator")) diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index c5d9e32c259df..d7846252477ee 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -3452,11 +3452,11 @@ class DarwinLegacyFilterDeclConsumer : public swift::VisibleDeclConsumer { if (!VD->hasName() || VD->getBaseName().isSpecial()) return true; return llvm::StringSwitch(VD->getBaseName().userFacingName()) - .Cases("OSErr", "OSStatus", "OptionBits", false) - .Cases("FourCharCode", "OSType", false) + .Cases({"OSErr", "OSStatus", "OptionBits"}, false) + .Cases({"FourCharCode", "OSType"}, false) .Case("Boolean", false) .Case("kUnknownType", false) - .Cases("UTF32Char", "UniChar", "UTF16Char", "UTF8Char", false) + .Cases({"UTF32Char", "UniChar", "UTF16Char", "UTF8Char"}, false) .Case("ProcessSerialNumber", false) .Default(true); } @@ -3464,7 +3464,7 @@ class DarwinLegacyFilterDeclConsumer : public swift::VisibleDeclConsumer { if (clangModule->Parent && clangModule->Parent->Name == "CarbonCore") { return llvm::StringSwitch(clangModule->Name) - .Cases("BackupCore", "DiskSpaceRecovery", "MacErrors", false) + .Cases({"BackupCore", "DiskSpaceRecovery", "MacErrors"}, false) .Case("UnicodeUtilities", false) .Default(true); } @@ -3474,9 +3474,9 @@ class DarwinLegacyFilterDeclConsumer : public swift::VisibleDeclConsumer { // Note that this is a list of things to /drop/ rather than to /keep/. // We're more likely to see new, modern headers added to OSServices. return llvm::StringSwitch(clangModule->Name) - .Cases("IconStorage", "KeychainCore", "Power", true) - .Cases("SecurityCore", "SystemSound", true) - .Cases("WSMethodInvocation", "WSProtocolHandler", "WSTypes", true) + .Cases({"IconStorage", "KeychainCore", "Power"}, true) + .Cases({"SecurityCore", "SystemSound"}, true) + .Cases({"WSMethodInvocation", "WSProtocolHandler", "WSTypes"}, true) .Default(false); } diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 79a33fe9d25dd..0ec8dab41fa40 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1487,13 +1487,13 @@ void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args, OI.RuntimeVariant = llvm::StringSwitch>( A->getValue()) - .Cases("MD", "MultiThreadedDLL", "shared-ucrt", + .Cases({"MD", "MultiThreadedDLL", "shared-ucrt"}, OutputInfo::MSVCRuntime::MultiThreadedDLL) - .Cases("MDd", "MultiThreadedDebugDLL", "shared-debug-ucrt", + .Cases({"MDd", "MultiThreadedDebugDLL", "shared-debug-ucrt"}, OutputInfo::MSVCRuntime::MultiThreadedDebugDLL) - .Cases("MT", "MultiThreaded", "static-ucrt", + .Cases({"MT", "MultiThreaded", "static-ucrt"}, OutputInfo::MSVCRuntime::MultiThreaded) - .Cases("MTd", "MultiThreadedDebug", "static-debug-ucrt", + .Cases({"MTd", "MultiThreadedDebug", "static-debug-ucrt"}, OutputInfo::MSVCRuntime::MultiThreadedDebug) .Default(std::nullopt); if (!OI.RuntimeVariant) diff --git a/lib/Driver/WindowsToolChains.cpp b/lib/Driver/WindowsToolChains.cpp index a3c58e8e444f9..56ff51ceca017 100644 --- a/lib/Driver/WindowsToolChains.cpp +++ b/lib/Driver/WindowsToolChains.cpp @@ -76,8 +76,8 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job, auto requiresLLD = [&]{ if (const Arg *A = context.Args.getLastArg(options::OPT_use_ld)) { return llvm::StringSwitch(A->getValue()) - .Cases("lld", "lld.exe", "lld-link", "lld-link.exe", true) - .Default(false); + .Cases({"lld", "lld.exe", "lld-link", "lld-link.exe"}, true) + .Default(false); } // Force to use lld for LTO on Windows because we don't support link LTO or // something else except for lld LTO at this time. diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 8cea946f4d2c0..20625ce8c99d5 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -568,9 +568,10 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts, OPT_disable_module_selectors_in_module_interface, false); } else if (auto envValue = ::getenv("SWIFT_MODULE_SELECTORS_IN_INTERFACES")) { - Opts.UseModuleSelectors = llvm::StringSwitch(envValue) - .CasesLower("false", "no", "off", "0", false) - .Default(true); + Opts.UseModuleSelectors = + llvm::StringSwitch(envValue) + .CasesLower({"false", "no", "off", "0"}, false) + .Default(true); } else { // Any heuristics we might add would go here. Opts.UseModuleSelectors = false; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 4fca1635fe94c..b236110f97ff5 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1444,12 +1444,13 @@ bool Parser::parseDifferentiableAttributeArguments( // Parse optional differentiability parameters. // Parse differentiability kind (optional). if (Tok.is(tok::identifier)) { - diffKind = llvm::StringSwitch(Tok.getText()) - .Case("reverse", DifferentiabilityKind::Reverse) - .Cases("wrt", "withRespectTo", DifferentiabilityKind::Normal) - .Case("_linear", DifferentiabilityKind::Linear) - .Case("_forward", DifferentiabilityKind::Forward) - .Default(DifferentiabilityKind::NonDifferentiable); + diffKind = + llvm::StringSwitch(Tok.getText()) + .Case("reverse", DifferentiabilityKind::Reverse) + .Cases({"wrt", "withRespectTo"}, DifferentiabilityKind::Normal) + .Case("_linear", DifferentiabilityKind::Linear) + .Case("_forward", DifferentiabilityKind::Forward) + .Default(DifferentiabilityKind::NonDifferentiable); switch (diffKind) { // Reject unsupported differentiability kinds. diff --git a/lib/PrintAsClang/PrintAsClang.cpp b/lib/PrintAsClang/PrintAsClang.cpp index 87cd3e64cf6bb..eb70d52f93cf8 100644 --- a/lib/PrintAsClang/PrintAsClang.cpp +++ b/lib/PrintAsClang/PrintAsClang.cpp @@ -358,7 +358,7 @@ static void collectClangModuleHeaderIncludes( dir != end && !errorCode; dir.increment(errorCode)) { if (llvm::StringSwitch(llvm::sys::path::extension(dir->path())) - .Cases(".h", ".H", ".hh", ".hpp", true) + .Cases({".h", ".H", ".hh", ".hpp"}, true) .Default(false)) { // Compute path to the header relative to the root of the module diff --git a/stdlib/include/llvm/ADT/StringSwitch.h b/stdlib/include/llvm/ADT/StringSwitch.h index 5da55040bba43..80ee51acdc52e 100644 --- a/stdlib/include/llvm/ADT/StringSwitch.h +++ b/stdlib/include/llvm/ADT/StringSwitch.h @@ -16,6 +16,7 @@ #include "llvm/Support/Compiler.h" #include #include +#include inline namespace __swift { inline namespace __runtime { namespace llvm { @@ -66,9 +67,7 @@ class StringSwitch { // Case-sensitive case matchers StringSwitch &Case(StringLiteral S, T Value) { - if (!Result && Str == S) { - Result = std::move(Value); - } + CaseImpl(Value, S); return *this; } @@ -86,62 +85,14 @@ class StringSwitch { return *this; } - StringSwitch &Cases(StringLiteral S0, StringLiteral S1, T Value) { - return Case(S0, Value).Case(S1, Value); - } - - StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, - T Value) { - return Case(S0, Value).Cases(S1, S2, Value); - } - - StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, - StringLiteral S3, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, Value); - } - - StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, - StringLiteral S3, StringLiteral S4, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, S4, Value); - } - - StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, - StringLiteral S3, StringLiteral S4, StringLiteral S5, + StringSwitch &Cases(std::initializer_list CaseStrings, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, S4, S5, Value); - } - - StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, - StringLiteral S3, StringLiteral S4, StringLiteral S5, - StringLiteral S6, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, Value); - } - - StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, - StringLiteral S3, StringLiteral S4, StringLiteral S5, - StringLiteral S6, StringLiteral S7, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, Value); - } - - StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, - StringLiteral S3, StringLiteral S4, StringLiteral S5, - StringLiteral S6, StringLiteral S7, StringLiteral S8, - T Value) { - return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, Value); - } - - StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, - StringLiteral S3, StringLiteral S4, StringLiteral S5, - StringLiteral S6, StringLiteral S7, StringLiteral S8, - StringLiteral S9, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, S9, Value); + return CasesImpl(Value, CaseStrings); } // Case-insensitive case matchers. StringSwitch &CaseLower(StringLiteral S, T Value) { - if (!Result && Str.equals_insensitive(S)) - Result = std::move(Value); - + CaseLowerImpl(Value, S); return *this; } @@ -159,37 +110,59 @@ class StringSwitch { return *this; } - StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, T Value) { - return CaseLower(S0, Value).CaseLower(S1, Value); - } - - StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, + StringSwitch &CasesLower(std::initializer_list CaseStrings, T Value) { - return CaseLower(S0, Value).CasesLower(S1, S2, Value); + return CasesLowerImpl(Value, CaseStrings); } - StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, - StringLiteral S3, T Value) { - return CaseLower(S0, Value).CasesLower(S1, S2, S3, Value); - } - - StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, - StringLiteral S3, StringLiteral S4, T Value) { - return CaseLower(S0, Value).CasesLower(S1, S2, S3, S4, Value); - } - - [[nodiscard]] - R Default(T Value) { + [[nodiscard]] R Default(T Value) { if (Result) return std::move(*Result); return Value; } - [[nodiscard]] - operator R() { + [[nodiscard]] operator R() { assert(Result && "Fell off the end of a string-switch"); return std::move(*Result); } + +private: + // Returns true when `Str` matches the `S` argument, and stores the result. + bool CaseImpl(T &Value, StringLiteral S) { + if (!Result && Str == S) { + Result = std::move(Value); + return true; + } + return false; + } + + // Returns true when `Str` matches the `S` argument (case-insensitive), and + // stores the result. + bool CaseLowerImpl(T &Value, StringLiteral S) { + if (!Result && Str.equals_insensitive(S)) { + Result = std::move(Value); + return true; + } + return false; + } + + StringSwitch &CasesImpl(T &Value, + std::initializer_list Cases) { + // Stop matching after the string is found. + for (StringLiteral S : Cases) + if (CaseImpl(Value, S)) + break; + return *this; + } + + StringSwitch &CasesLowerImpl(T &Value, + std::initializer_list Cases) { + // Stop matching after the string is found. + for (StringLiteral S : Cases) + if (CaseLowerImpl(Value, S)) + break; + return *this; + } }; } // end namespace llvm