aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Basic
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-01-24 19:17:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-19 21:24:44 +0000
commitab50317e96e57dee5b3ff4ad3f16f205b2a3359e (patch)
tree4b1f388eb6a07e574417aaacecd3ec4a83550718 /contrib/llvm-project/clang/lib/Basic
parent412542983a5ba62902141a8a7e155cceb9196a66 (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/Basic')
-rw-r--r--contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/Basic/FileManager.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp27
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h17
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp4
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h6
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp1
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp93
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h12
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h6
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp11
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Warnings.cpp3
13 files changed, 98 insertions, 88 deletions
diff --git a/contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp b/contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp
index 182d0a2fa4d8..79d715305ef2 100644
--- a/contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp
@@ -27,6 +27,8 @@ void CodeGenOptions::resetNonModularOptions(StringRef ModuleFormat) {
#define ENUM_DEBUGOPT(Name, Type, Bits, Default)
#define CODEGENOPT(Name, Bits, Default) Name = Default;
#define ENUM_CODEGENOPT(Name, Type, Bits, Default) set##Name(Default);
+// Do not reset AST affecting code generation options.
+#define AFFECTING_VALUE_CODEGENOPT(Name, Bits, Default)
#include "clang/Basic/CodeGenOptions.def"
// Next reset all debug options that can always be reset, because they never
diff --git a/contrib/llvm-project/clang/lib/Basic/FileManager.cpp b/contrib/llvm-project/clang/lib/Basic/FileManager.cpp
index d16626b10652..974c8c22598f 100644
--- a/contrib/llvm-project/clang/lib/Basic/FileManager.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/FileManager.cpp
@@ -532,7 +532,7 @@ void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) {
// misleading. We need to clean up the interface here.
makeAbsolutePath(AbsPath);
llvm::sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true);
- UFE->RealPathName = std::string(AbsPath.str());
+ UFE->RealPathName = std::string(AbsPath);
}
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets.cpp b/contrib/llvm-project/clang/lib/Basic/Targets.cpp
index ea002bb464fc..e3283510c6aa 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets.cpp
@@ -644,6 +644,8 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
return std::make_unique<PS4OSTargetInfo<X86_64TargetInfo>>(Triple, Opts);
case llvm::Triple::PS5:
return std::make_unique<PS5OSTargetInfo<X86_64TargetInfo>>(Triple, Opts);
+ case llvm::Triple::Hurd:
+ return std::make_unique<HurdTargetInfo<X86_64TargetInfo>>(Triple, Opts);
default:
return std::make_unique<X86_64TargetInfo>(Triple, Opts);
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp
index 9ebaf4d40cd7..d47181bfca4f 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp
@@ -622,9 +622,8 @@ AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const {
if (Name == "default")
return 0;
- for (const auto &E : llvm::AArch64::Extensions)
- if (Name == E.Name)
- return E.FmvPriority;
+ if (auto Ext = llvm::AArch64::parseArchExtension(Name))
+ return Ext->FmvPriority;
return 0;
}
@@ -634,24 +633,19 @@ unsigned AArch64TargetInfo::multiVersionFeatureCost() const {
}
bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const {
- auto F = llvm::find_if(llvm::AArch64::Extensions, [&](const auto &E) {
- return Name == E.Name && !E.DependentFeatures.empty();
- });
- return F != std::end(llvm::AArch64::Extensions);
+ if (auto Ext = llvm::AArch64::parseArchExtension(Name))
+ return !Ext->DependentFeatures.empty();
+ return false;
}
StringRef AArch64TargetInfo::getFeatureDependencies(StringRef Name) const {
- auto F = llvm::find_if(llvm::AArch64::Extensions,
- [&](const auto &E) { return Name == E.Name; });
- return F != std::end(llvm::AArch64::Extensions) ? F->DependentFeatures
- : StringRef();
+ if (auto Ext = llvm::AArch64::parseArchExtension(Name))
+ return Ext->DependentFeatures;
+ return StringRef();
}
bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
- for (const auto &E : llvm::AArch64::Extensions)
- if (FeatureStr == E.Name)
- return true;
- return false;
+ return llvm::AArch64::parseArchExtension(FeatureStr).has_value();
}
bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
@@ -1093,8 +1087,7 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
FoundArch = true;
std::pair<StringRef, StringRef> Split =
Feature.split("=").second.trim().split("+");
- const std::optional<llvm::AArch64::ArchInfo> AI =
- llvm::AArch64::parseArch(Split.first);
+ const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Split.first);
// Parse the architecture version, adding the required features to
// Ret.Features.
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h b/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h
index 1819ba544ccf..90a1516ecdd2 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h
@@ -169,10 +169,8 @@ public:
}
bool HasLeftParen = false;
- if (S.front() == '{') {
+ if (S.consume_front("{"))
HasLeftParen = true;
- S = S.drop_front();
- }
if (S.empty())
return false;
if (S.front() != 'v' && S.front() != 's' && S.front() != 'a') {
@@ -199,29 +197,24 @@ public:
return true;
}
bool HasLeftBracket = false;
- if (!S.empty() && S.front() == '[') {
+ if (S.consume_front("["))
HasLeftBracket = true;
- S = S.drop_front();
- }
unsigned long long N;
if (S.empty() || consumeUnsignedInteger(S, 10, N))
return false;
- if (!S.empty() && S.front() == ':') {
+ if (S.consume_front(":")) {
if (!HasLeftBracket)
return false;
- S = S.drop_front();
unsigned long long M;
if (consumeUnsignedInteger(S, 10, M) || N >= M)
return false;
}
if (HasLeftBracket) {
- if (S.empty() || S.front() != ']')
+ if (!S.consume_front("]"))
return false;
- S = S.drop_front();
}
- if (S.empty() || S.front() != '}')
+ if (!S.consume_front("}"))
return false;
- S = S.drop_front();
if (!S.empty())
return false;
// Found {vn}, {sn}, {an}, {v[n]}, {s[n]}, {a[n]}, {v[n:m]}, {s[n:m]}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
index a72bd42bad41..55b71557452f 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
@@ -227,6 +227,8 @@ StringRef ARMTargetInfo::getCPUAttr() const {
return "9_3A";
case llvm::ARM::ArchKind::ARMV9_4A:
return "9_4A";
+ case llvm::ARM::ArchKind::ARMV9_5A:
+ return "9_5A";
case llvm::ARM::ArchKind::ARMV8MBaseline:
return "8M_BASE";
case llvm::ARM::ArchKind::ARMV8MMainline:
@@ -889,6 +891,7 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
case llvm::ARM::ArchKind::ARMV9_2A:
case llvm::ARM::ArchKind::ARMV9_3A:
case llvm::ARM::ArchKind::ARMV9_4A:
+ case llvm::ARM::ArchKind::ARMV9_5A:
// Filter __arm_cdp, __arm_ldcl, __arm_stcl in arm_acle.h
FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B3;
break;
@@ -1057,6 +1060,7 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
case llvm::ARM::ArchKind::ARMV9_2A:
case llvm::ARM::ArchKind::ARMV9_3A:
case llvm::ARM::ArchKind::ARMV9_4A:
+ case llvm::ARM::ArchKind::ARMV9_5A:
getTargetDefinesARMV83A(Opts, Builder);
break;
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h
index 342af4bbc42b..4366c1149e40 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h
@@ -74,7 +74,8 @@ public:
this->TLSSupported = !Triple.isOSVersionLT(3);
} else if (Triple.isDriverKit()) {
// No TLS on DriverKit.
- }
+ } else if (Triple.isXROS())
+ this->TLSSupported = true;
this->MCountName = "\01mcount";
}
@@ -109,6 +110,9 @@ public:
case llvm::Triple::WatchOS: // Earliest supporting version is 5.0.0.
MinVersion = llvm::VersionTuple(5U);
break;
+ case llvm::Triple::XROS:
+ MinVersion = llvm::VersionTuple(0);
+ break;
default:
// Conservatively return 8 bytes if OS is unknown.
return 64;
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp
index 045c273f03c7..41935abfb65d 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp
@@ -212,6 +212,7 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
Builder.defineMacro("__darn_32", "__builtin_darn_32");
Builder.defineMacro("__darn_raw", "__builtin_darn_raw");
Builder.defineMacro("__dcbf", "__builtin_dcbf");
+ Builder.defineMacro("__fence", "__builtin_ppc_fence");
Builder.defineMacro("__fmadd", "__builtin_fma");
Builder.defineMacro("__fmadds", "__builtin_fmaf");
Builder.defineMacro("__abs", "__builtin_abs");
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
index fb312b6cf26e..c71b2e9eeb6c 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
@@ -154,7 +154,7 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
else
Builder.defineMacro("__riscv_float_abi_soft");
- if (ABIName == "ilp32e")
+ if (ABIName == "ilp32e" || ABIName == "lp64e")
Builder.defineMacro("__riscv_abi_rve");
Builder.defineMacro("__riscv_arch_test");
@@ -214,6 +214,13 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__riscv_misaligned_fast");
else
Builder.defineMacro("__riscv_misaligned_avoid");
+
+ if (ISAInfo->hasExtension("e")) {
+ if (Is64Bit)
+ Builder.defineMacro("__riscv_64e");
+ else
+ Builder.defineMacro("__riscv_32e");
+ }
}
static constexpr Builtin::Info BuiltinInfo[] = {
@@ -234,39 +241,6 @@ ArrayRef<Builtin::Info> RISCVTargetInfo::getTargetBuiltins() const {
clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
-static std::vector<std::string>
-collectNonISAExtFeature(ArrayRef<std::string> FeaturesNeedOverride, int XLen) {
- std::vector<std::string> NonISAExtFeatureVec;
-
- auto IsNonISAExtFeature = [](const std::string &Feature) {
- assert(Feature.size() > 1 && (Feature[0] == '+' || Feature[0] == '-'));
- StringRef Ext = StringRef(Feature).drop_front(); // drop the +/-
- return !llvm::RISCVISAInfo::isSupportedExtensionFeature(Ext);
- };
- llvm::copy_if(FeaturesNeedOverride, std::back_inserter(NonISAExtFeatureVec),
- IsNonISAExtFeature);
-
- return NonISAExtFeatureVec;
-}
-
-static std::vector<std::string>
-resolveTargetAttrOverride(const std::vector<std::string> &FeaturesVec,
- int XLen) {
- auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride");
- if (I == FeaturesVec.end())
- return FeaturesVec;
-
- ArrayRef<std::string> FeaturesNeedOverride(&*FeaturesVec.begin(), &*I);
- std::vector<std::string> NonISAExtFeature =
- collectNonISAExtFeature(FeaturesNeedOverride, XLen);
-
- std::vector<std::string> ResolvedFeature(++I, FeaturesVec.end());
- ResolvedFeature.insert(ResolvedFeature.end(), NonISAExtFeature.begin(),
- NonISAExtFeature.end());
-
- return ResolvedFeature;
-}
-
bool RISCVTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
const std::vector<std::string> &FeaturesVec) const {
@@ -280,10 +254,27 @@ bool RISCVTargetInfo::initFeatureMap(
Features["32bit"] = true;
}
- std::vector<std::string> NewFeaturesVec =
- resolveTargetAttrOverride(FeaturesVec, XLen);
+ // If a target attribute specified a full arch string, override all the ISA
+ // extension target features.
+ const auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride");
+ if (I != FeaturesVec.end()) {
+ std::vector<std::string> OverrideFeatures(std::next(I), FeaturesVec.end());
+
+ // Add back any non ISA extension features, e.g. +relax.
+ auto IsNonISAExtFeature = [](StringRef Feature) {
+ assert(Feature.size() > 1 && (Feature[0] == '+' || Feature[0] == '-'));
+ StringRef Ext = Feature.substr(1); // drop the +/-
+ return !llvm::RISCVISAInfo::isSupportedExtensionFeature(Ext);
+ };
+ llvm::copy_if(llvm::make_range(FeaturesVec.begin(), I),
+ std::back_inserter(OverrideFeatures), IsNonISAExtFeature);
- auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, NewFeaturesVec);
+ return TargetInfo::initFeatureMap(Features, Diags, CPU, OverrideFeatures);
+ }
+
+ // Otherwise, parse the features and add any implied extensions.
+ std::vector<std::string> AllFeatures = FeaturesVec;
+ auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec);
if (!ParseResult) {
std::string Buffer;
llvm::raw_string_ostream OutputErrMsg(Buffer);
@@ -294,21 +285,9 @@ bool RISCVTargetInfo::initFeatureMap(
return false;
}
- // RISCVISAInfo makes implications for ISA features
- std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatures();
-
- // parseFeatures normalizes the feature set by dropping any explicit
- // negatives, and non-extension features. We need to preserve the later
- // for correctness and want to preserve the former for consistency.
- for (auto &Feature : NewFeaturesVec) {
- StringRef ExtName = Feature;
- assert(ExtName.size() > 1 && (ExtName[0] == '+' || ExtName[0] == '-'));
- ExtName = ExtName.drop_front(1); // Drop '+' or '-'
- if (!llvm::is_contained(ImpliedFeatures, ("+" + ExtName).str()) &&
- !llvm::is_contained(ImpliedFeatures, ("-" + ExtName).str()))
- ImpliedFeatures.push_back(Feature);
- }
- return TargetInfo::initFeatureMap(Features, Diags, CPU, ImpliedFeatures);
+ // Append all features, not just new ones, so we override any negatives.
+ llvm::append_range(AllFeatures, (*ParseResult)->toFeatures());
+ return TargetInfo::initFeatureMap(Features, Diags, CPU, AllFeatures);
}
std::optional<std::pair<unsigned, unsigned>>
@@ -378,6 +357,11 @@ bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
if (llvm::is_contained(Features, "+experimental"))
HasExperimental = true;
+ if (ABI == "ilp32e" && ISAInfo->hasExtension("d")) {
+ Diags.Report(diag::err_invalid_feature_combination)
+ << "ILP32E cannot be used with the D ISA extension";
+ return false;
+ }
return true;
}
@@ -412,7 +396,10 @@ static void handleFullArchString(StringRef FullArchStr,
// Forward the invalid FullArchStr.
Features.push_back("+" + FullArchStr.str());
} else {
- std::vector<std::string> FeatStrings = (*RII)->toFeatures();
+ // Append a full list of features, including any negative extensions so that
+ // we override the CPU's features.
+ std::vector<std::string> FeatStrings =
+ (*RII)->toFeatures(/* AddAllExtensions */ true);
Features.insert(Features.end(), FeatStrings.begin(), FeatStrings.end());
}
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h
index f98c88cd45f8..bfbdafb682c8 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h
@@ -132,6 +132,12 @@ public:
}
bool setABI(const std::string &Name) override {
+ if (Name == "ilp32e") {
+ ABI = Name;
+ resetDataLayout("e-m:e-p:32:32-i64:64-n32-S32");
+ return true;
+ }
+
if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") {
ABI = Name;
return true;
@@ -156,6 +162,12 @@ public:
}
bool setABI(const std::string &Name) override {
+ if (Name == "lp64e") {
+ ABI = Name;
+ resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S64");
+ return true;
+ }
+
if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") {
ABI = Name;
return true;
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h
index 9ab2b7c60936..fa4a3bb1c82e 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h
@@ -17,6 +17,7 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/VersionTuple.h"
#include "llvm/TargetParser/Triple.h"
#include <optional>
@@ -301,8 +302,9 @@ public:
: BaseSPIRVTargetInfo(Triple, Opts) {
assert(Triple.getArch() == llvm::Triple::spirv &&
"Invalid architecture for Logical SPIR-V.");
- assert(Triple.getOS() == llvm::Triple::ShaderModel &&
- "Logical SPIR-V requires a valid ShaderModel.");
+ assert(Triple.getOS() == llvm::Triple::Vulkan &&
+ Triple.getVulkanVersion() != llvm::VersionTuple(0) &&
+ "Logical SPIR-V requires a valid Vulkan environment.");
assert(Triple.getEnvironment() >= llvm::Triple::Pixel &&
Triple.getEnvironment() <= llvm::Triple::Amplification &&
"Logical SPIR-V environment must be a valid shader stage.");
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp
index 64e281b888a9..a68b662d9401 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp
@@ -1418,6 +1418,14 @@ bool X86TargetInfo::validateAsmConstraint(
case 'O':
Info.setRequiresImmediate(0, 127);
return true;
+ case 'W':
+ switch (*++Name) {
+ default:
+ return false;
+ case 's':
+ Info.setAllowsRegister();
+ return true;
+ }
// Register constraints.
case 'Y': // 'Y' is the first character for several 2-character constraints.
// Shift the pointer to the second character of the constraint.
@@ -1715,6 +1723,9 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {
return std::string("{st}");
case 'u': // second from top of floating point stack.
return std::string("{st(1)}"); // second from top of floating point stack.
+ case 'W':
+ assert(Constraint[1] == 's');
+ return '^' + std::string(Constraint++, 2);
case 'Y':
switch (Constraint[1]) {
default:
diff --git a/contrib/llvm-project/clang/lib/Basic/Warnings.cpp b/contrib/llvm-project/clang/lib/Basic/Warnings.cpp
index 92954cab6fb0..5a5ac5556338 100644
--- a/contrib/llvm-project/clang/lib/Basic/Warnings.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Warnings.cpp
@@ -199,8 +199,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
// Check to see if this warning starts with "no-", if so, this is a
// negative form of the option.
- bool IsPositive = !Opt.starts_with("no-");
- if (!IsPositive) Opt = Opt.substr(3);
+ bool IsPositive = !Opt.consume_front("no-");
auto Severity = IsPositive ? diag::Severity::Remark
: diag::Severity::Ignored;