[lld] 8d85c96 - [lld] StringRef::{starts, ends}with => {starts, ends}_with. NFC

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 5 14:36:25 PDT 2023


Author: Fangrui Song
Date: 2023-06-05T14:36:19-07:00
New Revision: 8d85c96e0e3a058ae82930cf6767d9a1c8cc7c1d

URL: https://github.com/llvm/llvm-project/commit/8d85c96e0e3a058ae82930cf6767d9a1c8cc7c1d
DIFF: https://github.com/llvm/llvm-project/commit/8d85c96e0e3a058ae82930cf6767d9a1c8cc7c1d.diff

LOG: [lld] StringRef::{starts,ends}with => {starts,ends}_with. NFC

The latter form is now preferred to be similar to C++20 starts_with.
This replacement also removes one function call when startswith is not inlined.

Added: 
    

Modified: 
    lld/COFF/Chunks.cpp
    lld/COFF/Chunks.h
    lld/COFF/Driver.cpp
    lld/COFF/DriverUtils.cpp
    lld/COFF/ICF.cpp
    lld/COFF/InputFiles.cpp
    lld/COFF/MinGW.cpp
    lld/COFF/PDB.cpp
    lld/COFF/SymbolTable.cpp
    lld/COFF/Writer.cpp
    lld/Common/Args.cpp
    lld/Common/Reproduce.cpp
    lld/Common/Strings.cpp
    lld/ELF/AArch64ErrataFix.cpp
    lld/ELF/ARMErrataFix.cpp
    lld/ELF/Driver.cpp
    lld/ELF/DriverUtils.cpp
    lld/ELF/ICF.cpp
    lld/ELF/InputFiles.cpp
    lld/ELF/InputSection.cpp
    lld/ELF/InputSection.h
    lld/ELF/LTO.cpp
    lld/ELF/MarkLive.cpp
    lld/ELF/OutputSections.cpp
    lld/ELF/Relocations.cpp
    lld/ELF/ScriptLexer.cpp
    lld/ELF/ScriptParser.cpp
    lld/ELF/SyntheticSections.cpp
    lld/ELF/Writer.cpp
    lld/MachO/Arch/ARM64Common.cpp
    lld/MachO/Arch/X86_64.cpp
    lld/MachO/Driver.cpp
    lld/MachO/DriverUtils.cpp
    lld/MachO/InputFiles.cpp
    lld/MachO/InputSection.cpp
    lld/MachO/ObjC.cpp
    lld/MachO/SymbolTable.cpp
    lld/MachO/Symbols.h
    lld/MachO/SyntheticSections.cpp
    lld/MachO/Writer.cpp
    lld/MinGW/Driver.cpp
    lld/wasm/Driver.cpp
    lld/wasm/InputChunks.cpp
    lld/wasm/InputFiles.cpp
    lld/wasm/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index 8ffe79f139ff0..44a23a43d5f57 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -703,7 +703,7 @@ ArrayRef<uint8_t> SectionChunk::consumeDebugMagic(ArrayRef<uint8_t> data,
   if (data.size() < 4)
     fatal("the section is too short: " + sectionName);
 
-  if (!sectionName.startswith(".debug$"))
+  if (!sectionName.starts_with(".debug$"))
     fatal("invalid section: " + sectionName);
 
   uint32_t magic = support::endian::read32le(data.data());

diff  --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index 9d9e73870ccb5..3d605e6ab10c8 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -261,12 +261,12 @@ class SectionChunk final : public Chunk {
   // True if this is a codeview debug info chunk. These will not be laid out in
   // the image. Instead they will end up in the PDB, if one is requested.
   bool isCodeView() const {
-    return getSectionName() == ".debug" || getSectionName().startswith(".debug$");
+    return getSectionName() == ".debug" || getSectionName().starts_with(".debug$");
   }
 
   // True if this is a DWARF debug info or exception handling chunk.
   bool isDWARF() const {
-    return getSectionName().startswith(".debug_") || getSectionName() == ".eh_frame";
+    return getSectionName().starts_with(".debug_") || getSectionName() == ".eh_frame";
   }
 
   // Allow iteration over the bodies of this chunk's relocated symbols.

diff  --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index cbfad98cb812e..9c479709db8aa 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -113,12 +113,12 @@ static std::string getOutputPath(StringRef path, bool isDll, bool isDriver) {
 
 // Returns true if S matches /crtend.?\.o$/.
 static bool isCrtend(StringRef s) {
-  if (!s.endswith(".o"))
+  if (!s.ends_with(".o"))
     return false;
   s = s.drop_back(2);
-  if (s.endswith("crtend"))
+  if (s.ends_with("crtend"))
     return true;
-  return !s.empty() && s.drop_back().endswith("crtend");
+  return !s.empty() && s.drop_back().ends_with("crtend");
 }
 
 // ErrorOr is not default constructible, so it cannot be used as the type
@@ -354,7 +354,7 @@ void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
 }
 
 bool LinkerDriver::isDecorated(StringRef sym) {
-  return sym.startswith("@") || sym.contains("@@") || sym.startswith("?") ||
+  return sym.starts_with("@") || sym.contains("@@") || sym.starts_with("?") ||
          (!ctx.config.mingw && sym.contains('@'));
 }
 
@@ -1085,7 +1085,7 @@ bool LinkerDriver::run() {
 void LinkerDriver::parseOrderFile(StringRef arg) {
   // For some reason, the MSVC linker requires a filename to be
   // preceded by "@".
-  if (!arg.startswith("@")) {
+  if (!arg.starts_with("@")) {
     error("malformed /order option: '@' missing");
     return;
   }
@@ -1778,7 +1778,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
         doGC = true;
       } else if (s == "noref") {
         doGC = false;
-      } else if (s == "icf" || s.startswith("icf=")) {
+      } else if (s == "icf" || s.starts_with("icf=")) {
         icfLevel = ICFLevel::All;
       } else if (s == "safeicf") {
         icfLevel = ICFLevel::Safe;

diff  --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp
index e09bb7421547d..0f4af4def670c 100644
--- a/lld/COFF/DriverUtils.cpp
+++ b/lld/COFF/DriverUtils.cpp
@@ -322,7 +322,7 @@ void LinkerDriver::parseSwaprun(StringRef arg) {
     else
       error("/swaprun: invalid argument: " + swaprun);
     // To catch trailing commas, e.g. `/spawrun:cd,`
-    if (newArg.empty() && arg.endswith(","))
+    if (newArg.empty() && arg.ends_with(","))
       error("/swaprun: missing argument");
     arg = newArg;
   } while (!arg.empty());
@@ -592,7 +592,7 @@ Export LinkerDriver::parseExport(StringRef arg) {
       e.isPrivate = true;
       continue;
     }
-    if (tok.startswith("@")) {
+    if (tok.starts_with("@")) {
       int32_t ord;
       if (tok.substr(1).getAsInteger(0, ord))
         goto err;
@@ -616,9 +616,9 @@ static StringRef undecorate(COFFLinkerContext &ctx, StringRef sym) {
   // as-is with the leading underscore (with type IMPORT_NAME).
   // In MinGW mode, a decorated stdcall function gets the underscore
   // removed, just like normal cdecl functions.
-  if (sym.startswith("_") && sym.contains('@') && !ctx.config.mingw)
+  if (sym.starts_with("_") && sym.contains('@') && !ctx.config.mingw)
     return sym;
-  return sym.startswith("_") ? sym.substr(1) : sym;
+  return sym.starts_with("_") ? sym.substr(1) : sym;
 }
 
 // Convert stdcall/fastcall style symbols into unsuffixed symbols,
@@ -628,8 +628,8 @@ static StringRef killAt(StringRef sym, bool prefix) {
     return sym;
   // Strip any trailing stdcall suffix
   sym = sym.substr(0, sym.find('@', 1));
-  if (!sym.startswith("@")) {
-    if (prefix && !sym.startswith("_"))
+  if (!sym.starts_with("@")) {
+    if (prefix && !sym.starts_with("_"))
       return saver().save("_" + sym);
     return sym;
   }

diff  --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp
index 7ece725313d00..0abd0aa3f1966 100644
--- a/lld/COFF/ICF.cpp
+++ b/lld/COFF/ICF.cpp
@@ -93,7 +93,7 @@ bool ICF::isEligible(SectionChunk *c) {
     return true;
 
   // So are vtables.
-  if (c->sym && c->sym->getName().startswith("??_7"))
+  if (c->sym && c->sym->getName().starts_with("??_7"))
     return true;
 
   // Anything else not in an address-significance table is eligible.
@@ -132,7 +132,7 @@ bool ICF::assocEquals(const SectionChunk *a, const SectionChunk *b) {
   // debug info and CFGuard metadata.
   auto considerForICF = [](const SectionChunk &assoc) {
     StringRef Name = assoc.getSectionName();
-    return !(Name.startswith(".debug") || Name == ".gfids$y" ||
+    return !(Name.starts_with(".debug") || Name == ".gfids$y" ||
              Name == ".giats$y" || Name == ".gljmp$y");
   };
   auto ra = make_filter_range(a->children(), considerForICF);

diff  --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 5654b63ede61d..541837a7fceca 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -237,7 +237,7 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNumber,
   // and then write it to a separate .pdb file.
 
   // Ignore DWARF debug info unless /debug is given.
-  if (!ctx.config.debug && name.startswith(".debug_"))
+  if (!ctx.config.debug && name.starts_with(".debug_"))
     return nullptr;
 
   if (sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
@@ -261,12 +261,12 @@ SectionChunk *ObjFile::readSection(uint32_t sectionNumber,
   else if (name == ".sxdata")
     sxDataChunks.push_back(c);
   else if (ctx.config.tailMerge && sec->NumberOfRelocations == 0 &&
-           name == ".rdata" && leaderName.startswith("??_C@"))
+           name == ".rdata" && leaderName.starts_with("??_C@"))
     // COFF sections that look like string literal sections (i.e. no
     // relocations, in .rdata, leader symbol name matches the MSVC name mangling
     // for string literals) are subject to string tail merging.
     MergeChunk::addSection(ctx, c);
-  else if (name == ".rsrc" || name.startswith(".rsrc$"))
+  else if (name == ".rsrc" || name.starts_with(".rsrc$"))
     resourceChunks.push_back(c);
   else
     chunks.push_back(c);
@@ -366,7 +366,7 @@ Symbol *ObjFile::createRegular(COFFSymbolRef sym) {
     // everything should be fine. If something actually refers to the symbol
     // (e.g. the undefined weak alias), linking will fail due to undefined
     // references at the end.
-    if (ctx.config.mingw && name.startswith(".weak."))
+    if (ctx.config.mingw && name.starts_with(".weak."))
       return nullptr;
     return ctx.symtab.addUndefined(name, this, false);
   }

diff  --git a/lld/COFF/MinGW.cpp b/lld/COFF/MinGW.cpp
index 2b403635b478e..53e146bb8600b 100644
--- a/lld/COFF/MinGW.cpp
+++ b/lld/COFF/MinGW.cpp
@@ -144,10 +144,10 @@ bool AutoExporter::shouldExport(Defined *sym) const {
     return false;
 
   for (StringRef prefix : excludeSymbolPrefixes.keys())
-    if (sym->getName().startswith(prefix))
+    if (sym->getName().starts_with(prefix))
       return false;
   for (StringRef suffix : excludeSymbolSuffixes.keys())
-    if (sym->getName().endswith(suffix))
+    if (sym->getName().ends_with(suffix))
       return false;
 
   // If a corresponding __imp_ symbol exists and is defined, don't export it.

diff  --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index 8ca74ebc661ea..5aa81c1fd03bb 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -1213,8 +1213,8 @@ void PDBLinker::addPublicsToPDB() {
         // Drop the '_' prefix for x86.
         if (ctx.config.machine == I386)
           name = name.drop_front(1);
-        if (name.startswith("__profd_") || name.startswith("__profc_") ||
-            name.startswith("__covrec_")) {
+        if (name.starts_with("__profd_") || name.starts_with("__profc_") ||
+            name.starts_with("__covrec_")) {
           return;
         }
       }
@@ -1469,7 +1469,7 @@ static void addLinkerModuleCoffGroup(PartialSection *sec,
   // Somehow .idata sections & sections groups in the debug symbol stream have
   // the "write" flag set. However the section header for the corresponding
   // .idata section doesn't have it.
-  if (cgs.Name.startswith(".idata"))
+  if (cgs.Name.starts_with(".idata"))
     cgs.Characteristics |= llvm::COFF::IMAGE_SCN_MEM_WRITE;
 
   mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(

diff  --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index 16d03754cc699..b7217d14391a2 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -317,7 +317,7 @@ void SymbolTable::loadMinGWSymbols() {
     }
 
     if (ctx.config.autoImport) {
-      if (name.startswith("__imp_"))
+      if (name.starts_with("__imp_"))
         continue;
       // If we have an undefined symbol, but we have a lazy symbol we could
       // load, load it.
@@ -333,7 +333,7 @@ void SymbolTable::loadMinGWSymbols() {
 }
 
 Defined *SymbolTable::impSymbol(StringRef name) {
-  if (name.startswith("__imp_"))
+  if (name.starts_with("__imp_"))
     return nullptr;
   return dyn_cast_or_null<Defined>(find(("__imp_" + name).str()));
 }
@@ -456,7 +456,7 @@ void SymbolTable::reportUnresolvable() {
     if (undef->getWeakAlias())
       continue;
     StringRef name = undef->getName();
-    if (name.startswith("__imp_")) {
+    if (name.starts_with("__imp_")) {
       Symbol *imp = find(name.substr(strlen("__imp_")));
       if (imp && isa<Defined>(imp))
         continue;
@@ -504,7 +504,7 @@ void SymbolTable::resolveRemainingUndefines() {
 
     // If we can resolve a symbol by removing __imp_ prefix, do that.
     // This odd rule is for compatibility with MSVC linker.
-    if (name.startswith("__imp_")) {
+    if (name.starts_with("__imp_")) {
       Symbol *imp = find(name.substr(strlen("__imp_")));
       if (imp && isa<Defined>(imp)) {
         auto *d = cast<Defined>(imp);
@@ -816,9 +816,9 @@ std::vector<Symbol *> SymbolTable::getSymsWithPrefix(StringRef prefix) {
   std::vector<Symbol *> syms;
   for (auto pair : symMap) {
     StringRef name = pair.first.val();
-    if (name.startswith(prefix) || name.startswith(prefix.drop_front()) ||
-        name.drop_front().startswith(prefix) ||
-        name.drop_front().startswith(prefix.drop_front())) {
+    if (name.starts_with(prefix) || name.starts_with(prefix.drop_front()) ||
+        name.drop_front().starts_with(prefix) ||
+        name.drop_front().starts_with(prefix.drop_front())) {
       syms.push_back(pair.second);
     }
   }
@@ -846,7 +846,7 @@ Symbol *SymbolTable::findMangle(StringRef name) {
   auto findByPrefix = [&syms](const Twine &t) -> Symbol * {
     std::string prefix = t.str();
     for (auto *s : syms)
-      if (s->getName().startswith(prefix))
+      if (s->getName().starts_with(prefix))
         return s;
     return nullptr;
   };
@@ -855,7 +855,7 @@ Symbol *SymbolTable::findMangle(StringRef name) {
   if (ctx.config.machine != I386)
     return findByPrefix("?" + name + "@@Y");
 
-  if (!name.startswith("_"))
+  if (!name.starts_with("_"))
     return nullptr;
   // Search for x86 stdcall function.
   if (Symbol *s = findByPrefix(name + "@"))

diff  --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 6498cfef27592..dc38e88aa2400 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -736,7 +736,7 @@ void Writer::fixPartialSectionChars(StringRef name, uint32_t chars) {
     PartialSection *pSec = it.second;
     StringRef curName = pSec->name;
     if (!curName.consume_front(name) ||
-        (!curName.empty() && !curName.startswith("$")))
+        (!curName.empty() && !curName.starts_with("$")))
       continue;
     if (pSec->characteristics == chars)
       continue;
@@ -769,7 +769,7 @@ bool Writer::fixGnuImportChunks() {
   // with alphabetical ordering of the object files within a library.
   for (auto it : partialSections) {
     PartialSection *pSec = it.second;
-    if (!pSec->name.startswith(".idata"))
+    if (!pSec->name.starts_with(".idata"))
       continue;
 
     if (!pSec->chunks.empty())
@@ -857,9 +857,9 @@ static bool shouldStripSectionSuffix(SectionChunk *sc, StringRef name,
     return false;
   if (!sc || !sc->isCOMDAT())
     return false;
-  return name.startswith(".text$") || name.startswith(".data$") ||
-         name.startswith(".rdata$") || name.startswith(".pdata$") ||
-         name.startswith(".xdata$") || name.startswith(".eh_frame$");
+  return name.starts_with(".text$") || name.starts_with(".data$") ||
+         name.starts_with(".rdata$") || name.starts_with(".pdata$") ||
+         name.starts_with(".xdata$") || name.starts_with(".eh_frame$");
 }
 
 void Writer::sortSections() {
@@ -924,7 +924,7 @@ void Writer::createSections() {
     if (shouldStripSectionSuffix(sc, name, ctx.config.mingw))
       name = name.split('$').first;
 
-    if (name.startswith(".tls"))
+    if (name.starts_with(".tls"))
       tlsAlignment = std::max(tlsAlignment, c->getAlignment());
 
     PartialSection *pSec = createPartialSection(name,
@@ -985,7 +985,7 @@ void Writer::createSections() {
       // Move discardable sections named .debug_ to the end, after other
       // discardable sections. Stripping only removes the sections named
       // .debug_* - thus try to avoid leaving holes after stripping.
-      if (s->name.startswith(".debug_"))
+      if (s->name.starts_with(".debug_"))
         return 3;
       return 2;
     }
@@ -1143,7 +1143,7 @@ void Writer::createExportTable() {
   }
   // Warn on exported deleting destructor.
   for (auto e : ctx.config.exports)
-    if (e.sym && e.sym->getName().startswith("??_G"))
+    if (e.sym && e.sym->getName().starts_with("??_G"))
       warn("export of deleting dtor: " + toString(ctx, *e.sym));
 }
 

diff  --git a/lld/Common/Args.cpp b/lld/Common/Args.cpp
index d0249fef856f1..48c934df3a2c9 100644
--- a/lld/Common/Args.cpp
+++ b/lld/Common/Args.cpp
@@ -31,7 +31,7 @@ static int64_t getInteger(opt::InputArgList &args, unsigned key,
 
   int64_t v;
   StringRef s = a->getValue();
-  if (base == 16 && (s.startswith("0x") || s.startswith("0X")))
+  if (base == 16 && (s.starts_with("0x") || s.starts_with("0X")))
     s = s.drop_front(2);
   if (to_integer(s, v, base))
     return v;

diff  --git a/lld/Common/Reproduce.cpp b/lld/Common/Reproduce.cpp
index 017f53df05a4c..6488549f6bff3 100644
--- a/lld/Common/Reproduce.cpp
+++ b/lld/Common/Reproduce.cpp
@@ -32,9 +32,9 @@ std::string lld::relativeToRoot(StringRef path) {
   // of the result.
   SmallString<128> res;
   StringRef root = path::root_name(abs);
-  if (root.endswith(":"))
+  if (root.ends_with(":"))
     res = root.drop_back();
-  else if (root.startswith("//"))
+  else if (root.starts_with("//"))
     res = root.substr(2);
 
   path::append(res, path::relative_path(abs));

diff  --git a/lld/Common/Strings.cpp b/lld/Common/Strings.cpp
index 31397b75b2952..0dddc77de0df5 100644
--- a/lld/Common/Strings.cpp
+++ b/lld/Common/Strings.cpp
@@ -19,8 +19,8 @@ using namespace llvm;
 using namespace lld;
 
 SingleStringMatcher::SingleStringMatcher(StringRef Pattern) {
-  if (Pattern.size() > 2 && Pattern.startswith("\"") &&
-      Pattern.endswith("\"")) {
+  if (Pattern.size() > 2 && Pattern.starts_with("\"") &&
+      Pattern.ends_with("\"")) {
     ExactMatch = true;
     ExactPattern = Pattern.substr(1, Pattern.size() - 2);
   } else {

diff  --git a/lld/ELF/AArch64ErrataFix.cpp b/lld/ELF/AArch64ErrataFix.cpp
index 6ec7e338cd47f..99088e6857ef2 100644
--- a/lld/ELF/AArch64ErrataFix.cpp
+++ b/lld/ELF/AArch64ErrataFix.cpp
@@ -432,10 +432,10 @@ void AArch64Err843419Patcher::init() {
   // [Symbol Value, End of section). The type, code or data, is determined by
   // the mapping symbol name, $x for code, $d for data.
   auto isCodeMapSymbol = [](const Symbol *b) {
-    return b->getName() == "$x" || b->getName().startswith("$x.");
+    return b->getName() == "$x" || b->getName().starts_with("$x.");
   };
   auto isDataMapSymbol = [](const Symbol *b) {
-    return b->getName() == "$d" || b->getName().startswith("$d.");
+    return b->getName() == "$d" || b->getName().starts_with("$d.");
   };
 
   // Collect mapping symbols for every executable InputSection.

diff  --git a/lld/ELF/ARMErrataFix.cpp b/lld/ELF/ARMErrataFix.cpp
index 9fbff869397cf..cb9ff9ca22aae 100644
--- a/lld/ELF/ARMErrataFix.cpp
+++ b/lld/ELF/ARMErrataFix.cpp
@@ -317,13 +317,13 @@ void ARMErr657417Patcher::init() {
   // [Symbol Value, End of section). The type, code or data, is determined by
   // the mapping symbol name, $a for Arm code, $t for Thumb code, $d for data.
   auto isArmMapSymbol = [](const Symbol *s) {
-    return s->getName() == "$a" || s->getName().startswith("$a.");
+    return s->getName() == "$a" || s->getName().starts_with("$a.");
   };
   auto isThumbMapSymbol = [](const Symbol *s) {
-    return s->getName() == "$t" || s->getName().startswith("$t.");
+    return s->getName() == "$t" || s->getName().starts_with("$t.");
   };
   auto isDataMapSymbol = [](const Symbol *s) {
-    return s->getName() == "$d" || s->getName().startswith("$d.");
+    return s->getName() == "$d" || s->getName().starts_with("$d.");
   };
 
   // Collect mapping symbols for every executable InputSection.

diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 6325995da2b3b..db5e9bc5ab04b 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -152,7 +152,7 @@ bool elf::link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
 static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef emul) {
   uint8_t osabi = 0;
   StringRef s = emul;
-  if (s.endswith("_fbsd")) {
+  if (s.ends_with("_fbsd")) {
     s = s.drop_back(5);
     osabi = ELFOSABI_FREEBSD;
   }
@@ -529,11 +529,11 @@ constexpr const char *knownZFlags[] = {
 
 static bool isKnownZFlag(StringRef s) {
   return llvm::is_contained(knownZFlags, s) ||
-         s.startswith("common-page-size=") || s.startswith("bti-report=") ||
-         s.startswith("cet-report=") ||
-         s.startswith("dead-reloc-in-nonalloc=") ||
-         s.startswith("max-page-size=") || s.startswith("stack-size=") ||
-         s.startswith("start-stop-visibility=");
+         s.starts_with("common-page-size=") || s.starts_with("bti-report=") ||
+         s.starts_with("cet-report=") ||
+         s.starts_with("dead-reloc-in-nonalloc=") ||
+         s.starts_with("max-page-size=") || s.starts_with("stack-size=") ||
+         s.starts_with("start-stop-visibility=");
 }
 
 // Report a warning for an unknown -z option.
@@ -713,7 +713,7 @@ static bool isOutputFormatBinary(opt::InputArgList &args) {
   StringRef s = args.getLastArgValue(OPT_oformat, "elf");
   if (s == "binary")
     return true;
-  if (!s.startswith("elf"))
+  if (!s.starts_with("elf"))
     error("unknown --oformat value: " + s);
   return false;
 }
@@ -797,7 +797,7 @@ static StripPolicy getStrip(opt::InputArgList &args) {
 static uint64_t parseSectionAddress(StringRef s, opt::InputArgList &args,
                                     const opt::Arg &arg) {
   uint64_t va = 0;
-  if (s.startswith("0x"))
+  if (s.starts_with("0x"))
     s = s.drop_front(2);
   if (!to_integer(s, va, 16))
     error("invalid argument: " + arg.getAsString(args));
@@ -862,7 +862,7 @@ getBuildId(opt::InputArgList &args) {
     return {BuildIdKind::Sha1, {}};
   if (s == "uuid")
     return {BuildIdKind::Uuid, {}};
-  if (s.startswith("0x"))
+  if (s.starts_with("0x"))
     return {BuildIdKind::Hexstring, parseHex(s.substr(2))};
 
   if (s != "none")
@@ -1442,7 +1442,7 @@ static void readConfigs(opt::InputArgList &args) {
   // unsupported LLVMgold.so option and error.
   for (opt::Arg *arg : args.filtered(OPT_plugin_opt_eq)) {
     StringRef v(arg->getValue());
-    if (!v.endswith("lto-wrapper") && !v.endswith("lto-wrapper.exe"))
+    if (!v.ends_with("lto-wrapper") && !v.ends_with("lto-wrapper.exe"))
       error(arg->getSpelling() + ": unknown plugin option '" + arg->getValue() +
             "'");
   }
@@ -1497,7 +1497,7 @@ static void readConfigs(opt::InputArgList &args) {
     std::tie(config->ekind, config->emachine, config->osabi) =
         parseEmulation(s);
     config->mipsN32Abi =
-        (s.startswith("elf32btsmipn32") || s.startswith("elf32ltsmipn32"));
+        (s.starts_with("elf32btsmipn32") || s.starts_with("elf32ltsmipn32"));
     config->emulation = s;
   }
 

diff  --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index 50e9f509bcb47..5e3f6d1459d8e 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -214,7 +214,7 @@ std::string elf::createResponseFile(const opt::InputArgList &args) {
 static std::optional<std::string> findFile(StringRef path1,
                                            const Twine &path2) {
   SmallString<128> s;
-  if (path1.startswith("="))
+  if (path1.starts_with("="))
     path::append(s, config->sysroot, path1.substr(1), path2);
   else
     path::append(s, path1, path2);
@@ -247,7 +247,7 @@ std::optional<std::string> elf::searchLibraryBaseName(StringRef name) {
 // This is for -l<namespec>.
 std::optional<std::string> elf::searchLibrary(StringRef name) {
   llvm::TimeTraceScope timeScope("Locate library", name);
-  if (name.startswith(":"))
+  if (name.starts_with(":"))
     return findFromSearchPaths(name.substr(1));
   return searchLibraryBaseName(name);
 }

diff  --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index c2b0ce9b12b9f..841011c97a6cf 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -165,7 +165,7 @@ static bool isEligible(InputSection *s) {
   // Don't merge writable sections. .data.rel.ro sections are marked as writable
   // but are semantically read-only.
   if ((s->flags & SHF_WRITE) && s->name != ".data.rel.ro" &&
-      !s->name.startswith(".data.rel.ro."))
+      !s->name.starts_with(".data.rel.ro."))
     return false;
 
   // SHF_LINK_ORDER sections are ICF'd as a unit with their dependent sections,

diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 311e2c9a9e54f..5f24af5a9c6f5 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -76,7 +76,7 @@ static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) {
       fatal(archiveName + "(" + filename + "): " + msg);
   };
 
-  if (!mb.getBuffer().startswith(ElfMagic))
+  if (!mb.getBuffer().starts_with(ElfMagic))
     report("not an ELF file");
   if (endian != ELFDATA2LSB && endian != ELFDATA2MSB)
     report("corrupted ELF file: invalid data encoding");
@@ -192,7 +192,7 @@ std::optional<MemoryBufferRef> elf::readFile(StringRef path) {
 
   // The --chroot option changes our virtual root directory.
   // This is useful when you are dealing with files created by --reproduce.
-  if (!config->chroot.empty() && path.startswith("/"))
+  if (!config->chroot.empty() && path.starts_with("/"))
     path = saver().save(config->chroot + path);
 
   bool remapped = false;
@@ -959,7 +959,7 @@ template <class ELFT>
 InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
                                                     const Elf_Shdr &sec,
                                                     StringRef name) {
-  if (name.startswith(".n")) {
+  if (name.starts_with(".n")) {
     // The GNU linker uses .note.GNU-stack section as a marker indicating
     // that the code in the object file does not expect that the stack is
     // executable (in terms of NX bit). If all input files have the marker,

diff  --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 3057cedb4bdcb..6ad468f707688 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -1040,7 +1040,7 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf,
 
   for (Relocation &rel : relocs()) {
     // Ignore calls into the split-stack api.
-    if (rel.sym->getName().startswith("__morestack")) {
+    if (rel.sym->getName().starts_with("__morestack")) {
       if (rel.sym->getName().equals("__morestack"))
         morestackCalls.push_back(&rel);
       continue;

diff  --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 143384b3ba7bc..36ec0d0c0e912 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -426,7 +426,7 @@ class SyntheticSection : public InputSection {
 
 inline bool isDebugSection(const InputSectionBase &sec) {
   return (sec.flags & llvm::ELF::SHF_ALLOC) == 0 &&
-         sec.name.startswith(".debug");
+         sec.name.starts_with(".debug");
 }
 
 // The set of TOC entries (.toc + addend) for which we should not apply

diff  --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index f16abc188b76f..9d927b0ecfda9 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -217,7 +217,7 @@ BitcodeCompiler::BitcodeCompiler() {
       continue;
     StringRef s = sym->getName();
     for (StringRef prefix : {"__start_", "__stop_"})
-      if (s.startswith(prefix))
+      if (s.starts_with(prefix))
         usedStartStop.insert(s.substr(prefix.size()));
   }
 }

diff  --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index f6665e339d1d4..7db7d1c257d46 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -174,8 +174,8 @@ static bool isReserved(InputSectionBase *sec) {
     // .init_array.N (https://github.com/rust-lang/rust/issues/92181) for a
     // while.
     StringRef s = sec->name;
-    return s == ".init" || s == ".fini" || s.startswith(".init_array") ||
-           s == ".jcr" || s.startswith(".ctors") || s.startswith(".dtors");
+    return s == ".init" || s == ".fini" || s.starts_with(".init_array") ||
+           s == ".jcr" || s.starts_with(".ctors") || s.starts_with(".dtors");
   }
 }
 
@@ -285,7 +285,7 @@ template <class ELFT> void MarkLive<ELFT>::run() {
     // script KEEP command.
     if (isReserved(sec) || script->shouldKeep(sec)) {
       enqueue(sec, 0);
-    } else if ((!config->zStartStopGC || sec->name.startswith("__libc_")) &&
+    } else if ((!config->zStartStopGC || sec->name.starts_with("__libc_")) &&
                isValidCIdentifier(sec->name)) {
       // As a workaround for glibc libc.a before 2.34
       // (https://sourceware.org/PR27492), retain __libc_atexit and similar

diff  --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index d45f6abd810f0..05f9cdc20fd29 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -331,7 +331,7 @@ template <class ELFT> void OutputSection::maybeCompress() {
 
   // Compress only DWARF debug sections.
   if (config->compressDebugSections == DebugCompressionType::None ||
-      (flags & SHF_ALLOC) || !name.startswith(".debug_") || size == 0)
+      (flags & SHF_ALLOC) || !name.starts_with(".debug_") || size == 0)
     return;
 
   llvm::TimeTraceScope timeScope("Compress debug sections");
@@ -669,7 +669,7 @@ int elf::getPriority(StringRef s) {
     return 65536;
   int v = 65536;
   if (to_integer(s.substr(pos + 1), v, 10) &&
-      (pos == 6 && (s.startswith(".ctors") || s.startswith(".dtors"))))
+      (pos == 6 && (s.starts_with(".ctors") || s.starts_with(".dtors"))))
     v = 65535 - v;
   return v;
 }

diff  --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 2f7fcd664c6a5..90f9b8582d52e 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -110,7 +110,7 @@ void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
   if (rel.sym && !rel.sym->isSection())
     hint += getDefinedLocation(*rel.sym);
 
-  if (errPlace.isec && errPlace.isec->name.startswith(".debug"))
+  if (errPlace.isec && errPlace.isec->name.starts_with(".debug"))
     hint += "; consider recompiling with -fdebug-types-section to reduce size "
             "of debug sections";
 
@@ -656,7 +656,7 @@ static const Symbol *getAlternativeSpelling(const Undefined &sym,
 
   // The reference may be a mangled name while the definition is not. Suggest a
   // missing extern "C".
-  if (name.startswith("_Z")) {
+  if (name.starts_with("_Z")) {
     std::string buf = name.str();
     llvm::ItaniumPartialDemangler d;
     if (!d.partialDemangle(buf.c_str()))
@@ -758,12 +758,12 @@ static void reportUndefinedSymbol(const UndefinedDiag &undef,
     }
   }
 
-  if (sym.getName().startswith("_ZTV"))
+  if (sym.getName().starts_with("_ZTV"))
     msg +=
         "\n>>> the vtable symbol may be undefined because the class is missing "
         "its key function (see https://lld.llvm.org/missingkeyfunction)";
   if (config->gcSections && config->zStartStopGC &&
-      sym.getName().startswith("__start_")) {
+      sym.getName().starts_with("__start_")) {
     msg += "\n>>> the encapsulation symbol needs to be retained under "
            "--gc-sections properly; consider -z nostart-stop-gc "
            "(see https://lld.llvm.org/ELF/start-stop-gc)";

diff  --git a/lld/ELF/ScriptLexer.cpp b/lld/ELF/ScriptLexer.cpp
index e0a8ed7121a87..a10927666dcdb 100644
--- a/lld/ELF/ScriptLexer.cpp
+++ b/lld/ELF/ScriptLexer.cpp
@@ -120,7 +120,7 @@ void ScriptLexer::tokenize(MemoryBufferRef mb) {
     // because, in a glob match context, only unquoted tokens are interpreted
     // as glob patterns. Double-quoted tokens are literal patterns in that
     // context.
-    if (s.startswith("\"")) {
+    if (s.starts_with("\"")) {
       size_t e = s.find("\"", 1);
       if (e == StringRef::npos) {
         StringRef filename = mb.getBufferIdentifier();
@@ -135,7 +135,7 @@ void ScriptLexer::tokenize(MemoryBufferRef mb) {
     }
 
     // Some operators form separate tokens.
-    if (s.startswith("<<=") || s.startswith(">>=")) {
+    if (s.starts_with("<<=") || s.starts_with(">>=")) {
       vec.push_back(s.substr(0, 3));
       s = s.substr(3);
       continue;
@@ -167,7 +167,7 @@ void ScriptLexer::tokenize(MemoryBufferRef mb) {
 // Skip leading whitespace characters or comments.
 StringRef ScriptLexer::skipSpace(StringRef s) {
   for (;;) {
-    if (s.startswith("/*")) {
+    if (s.starts_with("/*")) {
       size_t e = s.find("*/", 2);
       if (e == StringRef::npos) {
         setError("unclosed comment in a linker script");
@@ -176,7 +176,7 @@ StringRef ScriptLexer::skipSpace(StringRef s) {
       s = s.substr(e + 2);
       continue;
     }
-    if (s.startswith("#")) {
+    if (s.starts_with("#")) {
       size_t e = s.find('\n', 1);
       if (e == StringRef::npos)
         e = s.size() - 1;
@@ -199,7 +199,7 @@ static std::vector<StringRef> tokenizeExpr(StringRef s) {
   StringRef ops = "!~*/+-<>?:="; // List of operators
 
   // Quoted strings are literal strings, so we don't want to split it.
-  if (s.startswith("\""))
+  if (s.starts_with("\""))
     return {s};
 
   // Split S with operators as separators.
@@ -219,9 +219,9 @@ static std::vector<StringRef> tokenizeExpr(StringRef s) {
 
     // Get the operator as a token.
     // Keep !=, ==, >=, <=, << and >> operators as a single tokens.
-    if (s.substr(e).startswith("!=") || s.substr(e).startswith("==") ||
-        s.substr(e).startswith(">=") || s.substr(e).startswith("<=") ||
-        s.substr(e).startswith("<<") || s.substr(e).startswith(">>")) {
+    if (s.substr(e).starts_with("!=") || s.substr(e).starts_with("==") ||
+        s.substr(e).starts_with(">=") || s.substr(e).starts_with("<=") ||
+        s.substr(e).starts_with("<<") || s.substr(e).starts_with(">>")) {
       ret.push_back(s.substr(e, 2));
       s = s.substr(e + 2);
     } else {

diff  --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index dea5ce6435e2a..a4fb0f7c6e17c 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -145,7 +145,7 @@ class ScriptParser final : ScriptLexer {
 } // namespace
 
 static StringRef unquote(StringRef s) {
-  if (s.startswith("\""))
+  if (s.starts_with("\""))
     return s.substr(1, s.size() - 2);
   return s;
 }
@@ -290,7 +290,7 @@ void ScriptParser::readDefsym(StringRef name) {
 }
 
 void ScriptParser::addFile(StringRef s) {
-  if (isUnderSysroot && s.startswith("/")) {
+  if (isUnderSysroot && s.starts_with("/")) {
     SmallString<128> pathData;
     StringRef path = (config->sysroot + s).toStringRef(pathData);
     if (sys::fs::exists(path))
@@ -300,17 +300,17 @@ void ScriptParser::addFile(StringRef s) {
     return;
   }
 
-  if (s.startswith("/")) {
+  if (s.starts_with("/")) {
     // Case 1: s is an absolute path. Just open it.
     ctx.driver.addFile(s, /*withLOption=*/false);
-  } else if (s.startswith("=")) {
+  } else if (s.starts_with("=")) {
     // Case 2: relative to the sysroot.
     if (config->sysroot.empty())
       ctx.driver.addFile(s.substr(1), /*withLOption=*/false);
     else
       ctx.driver.addFile(saver().save(config->sysroot + "/" + s.substr(1)),
                          /*withLOption=*/false);
-  } else if (s.startswith("-l")) {
+  } else if (s.starts_with("-l")) {
     // Case 3: search in the list of library paths.
     ctx.driver.addLibrary(s.substr(2));
   } else {
@@ -628,7 +628,7 @@ void ScriptParser::readTarget() {
   StringRef tok = unquote(next());
   expect(")");
 
-  if (tok.startswith("elf"))
+  if (tok.starts_with("elf"))
     config->formatBinary = false;
   else if (tok == "binary")
     config->formatBinary = true;
@@ -836,7 +836,7 @@ bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, Stri
       // The value is a recognized literal SHT_*.
       cmd->type = it->second;
       skip();
-    } else if (value.startswith("SHT_")) {
+    } else if (value.starts_with("SHT_")) {
       setError("unknown section type " + value);
     } else {
       // Otherwise, read an expression.
@@ -983,7 +983,7 @@ OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
 
   osec->phdrs = readOutputSectionPhdrs();
 
-  if (peek() == "=" || peek().startswith("=")) {
+  if (peek() == "=" || peek().starts_with("=")) {
     inExpr = true;
     consume("=");
     osec->filler = readFill();
@@ -1043,7 +1043,7 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
   size_t oldPos = pos;
   SymbolAssignment *cmd = nullptr;
   const StringRef op = peek();
-  if (op.startswith("=")) {
+  if (op.starts_with("=")) {
     // Support = followed by an expression without whitespace.
     SaveAndRestore saved(inExpr, true);
     cmd = readSymbolAssignment(tok);
@@ -1529,7 +1529,7 @@ Expr ScriptParser::readPrimary() {
     return [=] { return *val; };
 
   // Tok is a symbol name.
-  if (tok.startswith("\""))
+  if (tok.starts_with("\""))
     tok = unquote(tok);
   else if (!isValidSymbolName(tok))
     setError("malformed number: " + tok);
@@ -1553,7 +1553,7 @@ Expr ScriptParser::readParenExpr() {
 
 SmallVector<StringRef, 0> ScriptParser::readOutputSectionPhdrs() {
   SmallVector<StringRef, 0> phdrs;
-  while (!errorCount() && peek().startswith(":")) {
+  while (!errorCount() && peek().starts_with(":")) {
     StringRef tok = next();
     phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1));
   }
@@ -1680,7 +1680,7 @@ SmallVector<SymbolVersion, 0> ScriptParser::readVersionExtern() {
   while (!errorCount() && peek() != "}") {
     StringRef tok = next();
     ret.push_back(
-        {unquote(tok), isCXX, !tok.startswith("\"") && hasWildcard(tok)});
+        {unquote(tok), isCXX, !tok.starts_with("\"") && hasWildcard(tok)});
     if (consume("}"))
       return ret;
     expect(";");

diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 88534d216ad53..48f30123dcc00 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -3154,7 +3154,7 @@ template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
     verneeds.emplace_back();
     Verneed &vn = verneeds.back();
     vn.nameStrTab = getPartition().dynStrTab->addString(f->soName);
-    bool isLibc = config->relrGlibc && f->soName.startswith("libc.so.");
+    bool isLibc = config->relrGlibc && f->soName.starts_with("libc.so.");
     bool isGlibc2 = false;
     for (unsigned i = 0; i != f->vernauxs.size(); ++i) {
       if (f->vernauxs[i] == 0)
@@ -3162,7 +3162,7 @@ template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
       auto *verdef =
           reinterpret_cast<const typename ELFT::Verdef *>(f->verdefs[i]);
       StringRef ver(f->getStringTable().data() + verdef->getAux()->vda_name);
-      if (isLibc && ver.startswith("GLIBC_2."))
+      if (isLibc && ver.starts_with("GLIBC_2."))
         isGlibc2 = true;
       vn.vernauxs.push_back({verdef->vd_hash, f->vernauxs[i],
                              getPartition().dynStrTab->addString(ver)});

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index f68d4f4c34ae4..2a369acd4e4f7 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -657,7 +657,7 @@ static bool shouldKeepInSymtab(const Defined &sym) {
   // * --discard-locals is used.
   // * The symbol is in a SHF_MERGE section, which is normally the reason for
   //   the assembler keeping the .L symbol.
-  if (sym.getName().startswith(".L") &&
+  if (sym.getName().starts_with(".L") &&
       (config->discard == DiscardPolicy::Locals ||
        (sym.section && (sym.section->flags & SHF_MERGE))))
     return false;

diff  --git a/lld/MachO/Arch/ARM64Common.cpp b/lld/MachO/Arch/ARM64Common.cpp
index 45cf0eac3c47c..d90a37fe8c659 100644
--- a/lld/MachO/Arch/ARM64Common.cpp
+++ b/lld/MachO/Arch/ARM64Common.cpp
@@ -117,10 +117,10 @@ void ARM64Common::handleDtraceReloc(const Symbol *sym, const Reloc &r,
   if (config->outputType == MH_OBJECT)
     return;
 
-  if (sym->getName().startswith("___dtrace_probe")) {
+  if (sym->getName().starts_with("___dtrace_probe")) {
     // change call site to a NOP
     write32le(loc, 0xD503201F);
-  } else if (sym->getName().startswith("___dtrace_isenabled")) {
+  } else if (sym->getName().starts_with("___dtrace_isenabled")) {
     // change call site to 'MOVZ X0,0'
     write32le(loc, 0xD2800000);
   } else {

diff  --git a/lld/MachO/Arch/X86_64.cpp b/lld/MachO/Arch/X86_64.cpp
index 048702f129009..a0d4e1a28a14a 100644
--- a/lld/MachO/Arch/X86_64.cpp
+++ b/lld/MachO/Arch/X86_64.cpp
@@ -231,11 +231,11 @@ void X86_64::handleDtraceReloc(const Symbol *sym, const Reloc &r,
   if (config->outputType == MH_OBJECT)
     return;
 
-  if (sym->getName().startswith("___dtrace_probe")) {
+  if (sym->getName().starts_with("___dtrace_probe")) {
     // change call site to a NOP
     loc[-1] = 0x90;
     write32le(loc, 0x00401F0F);
-  } else if (sym->getName().startswith("___dtrace_isenabled")) {
+  } else if (sym->getName().starts_with("___dtrace_isenabled")) {
     // change call site to a clear eax
     loc[-1] = 0x33;
     write32le(loc, 0x909090C0);

diff  --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index ddd786e36bfc2..87664b5c2ede3 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -308,7 +308,7 @@ static InputFile *addFile(StringRef path, LoadType loadType,
 
     bool isLCLinkerForceLoad = loadType == LoadType::LCLinkerOption &&
                                config->forceLoadSwift &&
-                               path::filename(path).startswith("libswift");
+                               path::filename(path).starts_with("libswift");
     if ((isCommandLineLoad && config->allLoad) ||
         loadType == LoadType::CommandLineForce || isLCLinkerForceLoad) {
       if (std::optional<MemoryBufferRef> buffer = readFile(path)) {
@@ -336,7 +336,7 @@ static InputFile *addFile(StringRef path, LoadType loadType,
       }
     } else if (isCommandLineLoad && config->forceLoadObjC) {
       for (const object::Archive::Symbol &sym : file->getArchive().symbols())
-        if (sym.getName().startswith(objc::klass))
+        if (sym.getName().starts_with(objc::klass))
           file->fetch(sym);
 
       // TODO: no need to look for ObjC sections for a given archive member if
@@ -391,7 +391,7 @@ static InputFile *addFile(StringRef path, LoadType loadType,
     if ((isa<ObjFile>(newFile) || isa<BitcodeFile>(newFile)) && newFile->lazy &&
         config->forceLoadObjC) {
       for (Symbol *sym : newFile->symbols)
-        if (sym && sym->getName().startswith(objc::klass)) {
+        if (sym && sym->getName().starts_with(objc::klass)) {
           extract(*newFile, "-ObjC");
           break;
         }
@@ -934,7 +934,7 @@ static std::vector<SectionAlign> parseSectAlign(const opt::InputArgList &args) {
     StringRef segName = arg->getValue(0);
     StringRef sectName = arg->getValue(1);
     StringRef alignStr = arg->getValue(2);
-    if (alignStr.startswith("0x") || alignStr.startswith("0X"))
+    if (alignStr.starts_with("0x") || alignStr.starts_with("0X"))
       alignStr = alignStr.drop_front(2);
     uint32_t align;
     if (alignStr.getAsInteger(16, align)) {
@@ -1253,7 +1253,7 @@ static void addSynthenticMethnames() {
   const int prefixLength = ObjCStubsSection::symbolPrefix.size();
   for (Symbol *sym : symtab->getSymbols())
     if (isa<Undefined>(sym))
-      if (sym->getName().startswith(ObjCStubsSection::symbolPrefix))
+      if (sym->getName().starts_with(ObjCStubsSection::symbolPrefix))
         os << sym->getName().drop_front(prefixLength) << '\0';
 
   if (data.empty())
@@ -1480,7 +1480,7 @@ bool macho::link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
       StringRef sep = sys::path::get_separator();
       // real_path removes trailing slashes as part of the normalization, but
       // these are meaningful for our text based stripping
-      if (config->osoPrefix.equals(".") || config->osoPrefix.endswith(sep))
+      if (config->osoPrefix.equals(".") || config->osoPrefix.ends_with(sep))
         expanded += sep;
       config->osoPrefix = saver().save(expanded.str());
     }

diff  --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp
index d1f8ec28cbb55..b0be96f3592c4 100644
--- a/lld/MachO/DriverUtils.cpp
+++ b/lld/MachO/DriverUtils.cpp
@@ -275,7 +275,7 @@ macho::findPathCombination(const Twine &name,
 }
 
 StringRef macho::rerootPath(StringRef path) {
-  if (!path::is_absolute(path, path::Style::posix) || path.endswith(".o"))
+  if (!path::is_absolute(path, path::Style::posix) || path.ends_with(".o"))
     return path;
 
   if (std::optional<StringRef> rerootedPath =

diff  --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index c66679100d4e6..c89f6f4722dcc 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -90,7 +90,7 @@ std::string lld::toString(const InputFile *f) {
 
   // Multiple dylibs can be defined in one .tbd file.
   if (const auto *dylibFile = dyn_cast<DylibFile>(f))
-    if (f->getName().endswith(".tbd"))
+    if (f->getName().ends_with(".tbd"))
       return (f->getName() + "(" + dylibFile->installName + ")").str();
 
   if (f->archiveName.empty())
@@ -1541,7 +1541,7 @@ static DylibFile *findDylib(StringRef path, DylibFile *umbrella,
     StringRef stem = path::stem(path);
     SmallString<128> frameworkName;
     path::append(frameworkName, path::Style::posix, stem + ".framework", stem);
-    bool isFramework = path.endswith(frameworkName);
+    bool isFramework = path.ends_with(frameworkName);
     if (isFramework) {
       for (StringRef dir : config->frameworkSearchPaths) {
         SmallString<128> candidate = dir;
@@ -1580,7 +1580,7 @@ static DylibFile *findDylib(StringRef path, DylibFile *umbrella,
     path::remove_filename(newPath);
     path::append(newPath, path);
     path = newPath;
-  } else if (path.startswith("@rpath/")) {
+  } else if (path.starts_with("@rpath/")) {
     for (StringRef rpath : umbrella->rpaths) {
       newPath.clear();
       if (rpath.consume_front("@loader_path/")) {
@@ -1949,7 +1949,7 @@ DylibFile *DylibFile::getSyntheticDylib(StringRef installName,
 // name, compatibility version or hide/add symbols) for specific target
 // versions.
 bool DylibFile::handleLDSymbol(StringRef originalName) {
-  if (!originalName.startswith("$ld$"))
+  if (!originalName.starts_with("$ld$"))
     return false;
 
   StringRef action;
@@ -2059,7 +2059,7 @@ void DylibFile::handleLDInstallNameSymbol(StringRef name,
 void DylibFile::handleLDHideSymbol(StringRef name, StringRef originalName) {
   StringRef symbolName;
   bool shouldHide = true;
-  if (name.startswith("os")) {
+  if (name.starts_with("os")) {
     // If it's hidden based on versions.
     name = name.drop_front(2);
     StringRef minVersion;

diff  --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp
index ff5a15067adcd..eb1c51cdf8ec8 100644
--- a/lld/MachO/InputSection.cpp
+++ b/lld/MachO/InputSection.cpp
@@ -197,7 +197,7 @@ void ConcatInputSection::writeTo(uint8_t *buf) {
           !referentSym->isInGot())
         target->relaxGotLoad(loc, r.type);
       // For dtrace symbols, do not handle them as normal undefined symbols
-      if (referentSym->getName().startswith("___dtrace_")) {
+      if (referentSym->getName().starts_with("___dtrace_")) {
         // Change dtrace call site to pre-defined instructions
         target->handleDtraceReloc(referentSym, r, loc);
         continue;

diff  --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp
index ebdfebf332cc2..7e8cec026d2f7 100644
--- a/lld/MachO/ObjC.cpp
+++ b/lld/MachO/ObjC.cpp
@@ -43,7 +43,7 @@ template <class LP> static bool objectHasObjCSection(MemoryBufferRef mb) {
       if ((segname == segment_names::data &&
            sectname == section_names::objcCatList) ||
           (segname == segment_names::text &&
-           sectname.startswith(section_names::swift))) {
+           sectname.starts_with(section_names::swift))) {
         return true;
       }
     }

diff  --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp
index 7d2e758cfbeff..283edf24ab067 100644
--- a/lld/MachO/SymbolTable.cpp
+++ b/lld/MachO/SymbolTable.cpp
@@ -385,7 +385,7 @@ static bool recoverFromUndefinedSymbol(const Undefined &sym) {
   }
 
   // Leave dtrace symbols, since we will handle them when we do the relocation
-  if (name.startswith("___dtrace_"))
+  if (name.starts_with("___dtrace_"))
     return true;
 
   // Handle -U.
@@ -530,7 +530,7 @@ static const Symbol *getAlternativeSpelling(const Undefined &sym,
 
   // The reference may be a mangled name while the definition is not. Suggest a
   // missing extern "C".
-  if (name.startswith("__Z")) {
+  if (name.starts_with("__Z")) {
     std::string buf = name.str();
     llvm::ItaniumPartialDemangler d;
     if (!d.partialDemangle(buf.c_str()))

diff  --git a/lld/MachO/Symbols.h b/lld/MachO/Symbols.h
index 8fdc60c3d9fac..88efc7a18c768 100644
--- a/lld/MachO/Symbols.h
+++ b/lld/MachO/Symbols.h
@@ -386,7 +386,7 @@ inline bool needsBinding(const Symbol *sym) {
 // Symbols with `l` or `L` as a prefix are linker-private and never appear in
 // the output.
 inline bool isPrivateLabel(StringRef name) {
-  return name.startswith("l") || name.startswith("L");
+  return name.starts_with("l") || name.starts_with("L");
 }
 } // namespace macho
 

diff  --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index f7cad7345fc86..03084576955e2 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -813,7 +813,7 @@ ObjCStubsSection::ObjCStubsSection()
 }
 
 void ObjCStubsSection::addEntry(Symbol *sym) {
-  assert(sym->getName().startswith(symbolPrefix) && "not an objc stub");
+  assert(sym->getName().starts_with(symbolPrefix) && "not an objc stub");
   StringRef methname = sym->getName().drop_front(symbolPrefix.size());
   offsets.push_back(
       in.objcMethnameSection->getStringOffset(methname).outSecOff);

diff  --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 68b22bf10c354..d2d4adf6a2bbc 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -731,7 +731,7 @@ void Writer::scanSymbols() {
       dysym->getFile()->refState =
           std::max(dysym->getFile()->refState, dysym->getRefState());
     } else if (isa<Undefined>(sym)) {
-      if (sym->getName().startswith(ObjCStubsSection::symbolPrefix))
+      if (sym->getName().starts_with(ObjCStubsSection::symbolPrefix))
         in.objcStubs->addEntry(sym);
     }
   }

diff  --git a/lld/MinGW/Driver.cpp b/lld/MinGW/Driver.cpp
index f00f50a76e31c..c5a32c3a90bb8 100644
--- a/lld/MinGW/Driver.cpp
+++ b/lld/MinGW/Driver.cpp
@@ -127,7 +127,7 @@ static std::optional<std::string> findFile(StringRef path1,
 // This is for -lfoo. We'll look for libfoo.dll.a or libfoo.a from search paths.
 static std::string
 searchLibrary(StringRef name, ArrayRef<StringRef> searchPaths, bool bStatic) {
-  if (name.startswith(":")) {
+  if (name.starts_with(":")) {
     for (StringRef dir : searchPaths)
       if (std::optional<std::string> s = findFile(dir, name.substr(1)))
         return *s;
@@ -204,7 +204,7 @@ bool mingw::link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
 
   if (auto *a = args.getLastArg(OPT_entry)) {
     StringRef s = a->getValue();
-    if (args.getLastArgValue(OPT_m) == "i386pe" && s.startswith("_"))
+    if (args.getLastArgValue(OPT_m) == "i386pe" && s.starts_with("_"))
       add("-entry:" + s.substr(1));
     else
       add("-entry:" + s);

diff  --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index baca9395f5b0e..dcb76886d3a43 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -314,7 +314,7 @@ static std::optional<std::string> searchLibraryBaseName(StringRef name) {
 
 // This is for -l<namespec>.
 static std::optional<std::string> searchLibrary(StringRef name) {
-  if (name.startswith(":"))
+  if (name.starts_with(":"))
     return findFromSearchPaths(name.substr(1));
   return searchLibraryBaseName(name);
 }
@@ -409,7 +409,7 @@ getBuildId(opt::InputArgList &args) {
     return {BuildIdKind::Sha1, {}};
   if (s == "uuid")
     return {BuildIdKind::Uuid, {}};
-  if (s.startswith("0x"))
+  if (s.starts_with("0x"))
     return {BuildIdKind::Hexstring, parseHex(s.substr(2))};
 
   if (s != "none")
@@ -1073,7 +1073,7 @@ static void splitSections() {
 
 static bool isKnownZFlag(StringRef s) {
   // For now, we only support a very limited set of -z flags
-  return s.startswith("stack-size=");
+  return s.starts_with("stack-size=");
 }
 
 // Report a warning for an unknown -z option.

diff  --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp
index 09437939e1b90..8eda56a61d1e8 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -521,7 +521,7 @@ uint64_t InputSection::getTombstoneForSection(StringRef name) {
   // meaning of -1 so we use -2.
   // Returning 0 means there is no tombstone value for this section, and relocation
   // will just use the addend.
-  if (!name.startswith(".debug_"))
+  if (!name.starts_with(".debug_"))
     return 0;
   if (name.equals(".debug_ranges") || name.equals(".debug_loc"))
     return UINT64_C(-2);

diff  --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index fef5604572178..bd174c8656692 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -487,7 +487,7 @@ void ObjFile::parse(bool ignoreComdats) {
     // relied on the naming convention.  To maintain compat with such objects
     // we still imply the TLS flag based on the name of the segment.
     if (!seg->isTLS() &&
-        (seg->name.startswith(".tdata") || seg->name.startswith(".tbss")))
+        (seg->name.starts_with(".tdata") || seg->name.starts_with(".tbss")))
       seg->flags |= WASM_SEG_FLAG_TLS;
     segments.emplace_back(seg);
   }
@@ -705,7 +705,7 @@ void StubFile::parse() {
     }
 
     // Lines starting with # are considered comments
-    if (line.startswith("#"))
+    if (line.starts_with("#"))
       continue;
 
     StringRef sym;

diff  --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 2ec8848b26d11..7b33a944962a6 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -141,7 +141,7 @@ void Writer::calculateCustomSections() {
       // These custom sections are known the linker and synthesized rather than
       // blindly copied.
       if (name == "linking" || name == "name" || name == "producers" ||
-          name == "target_features" || name.startswith("reloc."))
+          name == "target_features" || name.starts_with("reloc."))
         continue;
       // These custom sections are generated by `clang -fembed-bitcode`.
       // These are used by the rust toolchain to ship LTO data along with
@@ -150,7 +150,7 @@ void Writer::calculateCustomSections() {
       if (name == ".llvmbc" || name == ".llvmcmd")
         continue;
       // Strip debug section in that option was specified.
-      if (stripDebug && name.startswith(".debug_"))
+      if (stripDebug && name.starts_with(".debug_"))
         continue;
       // Otherwise include custom sections by default and concatenate their
       // contents.
@@ -992,13 +992,13 @@ static StringRef getOutputDataSegmentName(const InputChunk &seg) {
     return ".tdata";
   if (!config->mergeDataSegments)
     return seg.name;
-  if (seg.name.startswith(".text."))
+  if (seg.name.starts_with(".text."))
     return ".text";
-  if (seg.name.startswith(".data."))
+  if (seg.name.starts_with(".data."))
     return ".data";
-  if (seg.name.startswith(".bss."))
+  if (seg.name.starts_with(".bss."))
     return ".bss";
-  if (seg.name.startswith(".rodata."))
+  if (seg.name.starts_with(".rodata."))
     return ".rodata";
   return seg.name;
 }
@@ -1008,7 +1008,7 @@ OutputSegment *Writer::createOutputSegment(StringRef name) {
   OutputSegment *s = make<OutputSegment>(name);
   if (config->sharedMemory)
     s->initFlags = WASM_DATA_SEGMENT_IS_PASSIVE;
-  if (!config->relocatable && name.startswith(".bss"))
+  if (!config->relocatable && name.starts_with(".bss"))
     s->isBss = true;
   segments.push_back(s);
   return s;


        


More information about the llvm-commits mailing list