[clang-tidy] Use StringRef::{starts,ends}_with (NFC)

This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.

I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
This commit is contained in:
Kazu Hirata 2023-12-13 23:11:05 -08:00
parent 88d319a29f
commit 76bbbcb41b
33 changed files with 69 additions and 67 deletions

View File

@ -390,7 +390,7 @@ static CheckersList getAnalyzerCheckersAndPackages(ClangTidyContext &Context,
for (StringRef CheckName : RegisteredCheckers) {
std::string ClangTidyCheckName((AnalyzerCheckNamePrefix + CheckName).str());
if (CheckName.startswith("core") ||
if (CheckName.starts_with("core") ||
Context.isCheckEnabled(ClangTidyCheckName)) {
List.emplace_back(std::string(CheckName), true);
}
@ -541,7 +541,7 @@ runClangTidy(clang::tidy::ClangTidyContext &Context,
CommandLineArguments AdjustedArgs = Args;
if (Opts.ExtraArgsBefore) {
auto I = AdjustedArgs.begin();
if (I != AdjustedArgs.end() && !StringRef(*I).startswith("-"))
if (I != AdjustedArgs.end() && !StringRef(*I).starts_with("-"))
++I; // Skip compiler binary name, if it is there.
AdjustedArgs.insert(I, Opts.ExtraArgsBefore->begin(),
Opts.ExtraArgsBefore->end());

View File

@ -62,7 +62,7 @@ protected:
// appending the check name to the message in ClangTidyContext::diag and
// using getCustomDiagID.
std::string CheckNameInMessage = " [" + Error.DiagnosticName + "]";
if (Message.endswith(CheckNameInMessage))
if (Message.ends_with(CheckNameInMessage))
Message = Message.substr(0, Message.size() - CheckNameInMessage.size());
auto TidyMessage =
@ -457,7 +457,7 @@ bool ClangTidyDiagnosticConsumer::passesLineFilter(StringRef FileName,
if (Context.getGlobalOptions().LineFilter.empty())
return true;
for (const FileFilter &Filter : Context.getGlobalOptions().LineFilter) {
if (FileName.endswith(Filter.Name)) {
if (FileName.ends_with(Filter.Name)) {
if (Filter.LineRanges.empty())
return true;
for (const FileFilter::LineRange &Range : Filter.LineRanges) {

View File

@ -23,10 +23,10 @@ public:
/// Records that a given file entry is needed for replaying callbacks.
void addNecessaryFile(FileEntryRef File) {
// Don't record modulemap files because it breaks same file detection.
if (!(File.getName().endswith("module.modulemap") ||
File.getName().endswith("module.private.modulemap") ||
File.getName().endswith("module.map") ||
File.getName().endswith("module_private.map")))
if (!(File.getName().ends_with("module.modulemap") ||
File.getName().ends_with("module.private.modulemap") ||
File.getName().ends_with("module.map") ||
File.getName().ends_with("module_private.map")))
FilesToRecord.insert(File);
}

View File

@ -16,7 +16,7 @@ namespace clang::tidy {
// from the GlobList.
static bool consumeNegativeIndicator(StringRef &GlobList) {
GlobList = GlobList.trim();
if (GlobList.startswith("-")) {
if (GlobList.starts_with("-")) {
GlobList = GlobList.substr(1);
return true;
}

View File

@ -52,7 +52,7 @@ AST_POLYMORPHIC_MATCHER(
"profiling", "random", "status", "strings", "synchronization",
"time", "types", "utility"};
return llvm::any_of(AbseilLibraries, [&](const char *Library) {
return Path.startswith(Library);
return Path.starts_with(Library);
});
}

View File

@ -27,7 +27,7 @@ std::optional<std::string> makeCharacterLiteral(const StringLiteral *Literal,
assert(Literal->getCharByteWidth() == 1 &&
"StrSplit doesn't support wide char");
std::string Result = clang::tooling::fixit::getText(*Literal, Context).str();
bool IsRawStringLiteral = StringRef(Result).startswith(R"(R")");
bool IsRawStringLiteral = StringRef(Result).starts_with(R"(R")");
// Since raw string literal might contain unescaped non-printable characters,
// we normalize them using `StringLiteral::outputString`.
if (IsRawStringLiteral) {

View File

@ -185,7 +185,7 @@ static bool sameName(StringRef InComment, StringRef InDecl, bool StrictMode) {
static bool looksLikeExpectMethod(const CXXMethodDecl *Expect) {
return Expect != nullptr && Expect->getLocation().isMacroID() &&
Expect->getNameInfo().getName().isIdentifier() &&
Expect->getName().startswith("gmock_");
Expect->getName().starts_with("gmock_");
}
static bool areMockAndExpectMethods(const CXXMethodDecl *Mock,
const CXXMethodDecl *Expect) {

View File

@ -1550,7 +1550,7 @@ static bool isIgnoredParameter(const TheCheck &Check, const ParmVarDecl *Node) {
if (!NodeTypeName.empty()) {
if (llvm::any_of(Check.IgnoredParameterTypeSuffixes,
[NodeTypeName](StringRef E) {
return !E.empty() && NodeTypeName.endswith(E);
return !E.empty() && NodeTypeName.ends_with(E);
})) {
LLVM_DEBUG(llvm::dbgs() << "\tType suffix ignored.\n");
return true;

View File

@ -385,7 +385,7 @@ static bool isDestExprFix(const MatchFinder::MatchResult &Result,
std::string TempTyStr = Dest->getType().getAsString();
StringRef TyStr = TempTyStr;
if (TyStr.startswith("char") || TyStr.startswith("wchar_t"))
if (TyStr.starts_with("char") || TyStr.starts_with("wchar_t"))
return false;
Diag << FixItHint::CreateInsertion(Dest->getBeginLoc(), "(char *)");
@ -721,8 +721,8 @@ void NotNullTerminatedResultCheck::registerMatchers(MatchFinder *Finder) {
// Try to match with 'wchar_t' based function calls.
std::string WcharHandlerFuncName =
"::" + (CC.Name.startswith("mem") ? "w" + CC.Name.str()
: "wcs" + CC.Name.substr(3).str());
"::" + (CC.Name.starts_with("mem") ? "w" + CC.Name.str()
: "wcs" + CC.Name.substr(3).str());
return allOf(callee(functionDecl(
hasAnyName(CharHandlerFuncName, WcharHandlerFuncName))),
@ -820,13 +820,13 @@ void NotNullTerminatedResultCheck::check(
}
StringRef Name = FunctionExpr->getDirectCallee()->getName();
if (Name.startswith("mem") || Name.startswith("wmem"))
if (Name.starts_with("mem") || Name.starts_with("wmem"))
memoryHandlerFunctionFix(Name, Result);
else if (Name == "strerror_s")
strerror_sFix(Result);
else if (Name.endswith("ncmp"))
else if (Name.ends_with("ncmp"))
ncmpFix(Name, Result);
else if (Name.endswith("xfrm"))
else if (Name.ends_with("xfrm"))
xfrmFix(Name, Result);
}
@ -835,7 +835,7 @@ void NotNullTerminatedResultCheck::memoryHandlerFunctionFix(
if (isCorrectGivenLength(Result))
return;
if (Name.endswith("chr")) {
if (Name.ends_with("chr")) {
memchrFix(Name, Result);
return;
}
@ -849,13 +849,13 @@ void NotNullTerminatedResultCheck::memoryHandlerFunctionFix(
"the result from calling '%0' is not null-terminated")
<< Name;
if (Name.endswith("cpy")) {
if (Name.ends_with("cpy")) {
memcpyFix(Name, Result, Diag);
} else if (Name.endswith("cpy_s")) {
} else if (Name.ends_with("cpy_s")) {
memcpy_sFix(Name, Result, Diag);
} else if (Name.endswith("move")) {
} else if (Name.ends_with("move")) {
memmoveFix(Name, Result, Diag);
} else if (Name.endswith("move_s")) {
} else if (Name.ends_with("move_s")) {
isDestCapacityFix(Result, Diag);
lengthArgHandle(LengthHandleKind::Increase, Result, Diag);
}

View File

@ -81,7 +81,7 @@ static bool hasReservedDoubleUnderscore(StringRef Name,
const LangOptions &LangOpts) {
if (LangOpts.CPlusPlus)
return Name.contains("__");
return Name.startswith("__");
return Name.starts_with("__");
}
static std::optional<std::string>

View File

@ -282,7 +282,7 @@ bool isStandardFunction(const FunctionDecl *FD) {
/// and every other statement that is declared in file ExprCXX.h.
bool isCXXOnlyStmt(const Stmt *S) {
StringRef Name = S->getStmtClassName();
if (Name.startswith("CXX"))
if (Name.starts_with("CXX"))
return true;
// Check for all other class names in ExprCXX.h that have no 'CXX' prefix.
return isa<ArrayTypeTraitExpr, BuiltinBitCastExpr, CUDAKernelCallExpr,

View File

@ -148,14 +148,15 @@ void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) {
return;
// Ignore code in .c files and headers included from them, even if they are
// compiled as C++.
if (getCurrentMainFile().endswith(".c"))
if (getCurrentMainFile().ends_with(".c"))
return;
SourceManager &SM = *Result.SourceManager;
// Ignore code in .c files #included in other files (which shouldn't be done,
// but people still do this for test and other purposes).
if (SM.getFilename(SM.getSpellingLoc(CastExpr->getBeginLoc())).endswith(".c"))
if (SM.getFilename(SM.getSpellingLoc(CastExpr->getBeginLoc()))
.ends_with(".c"))
return;
// Leave type spelling exactly as it was (unlike

View File

@ -66,7 +66,7 @@ public:
// recent enough version of Google Test.
llvm::StringRef FileName = PP->getSourceManager().getFilename(
MD->getMacroInfo()->getDefinitionLoc());
ReplacementFound = FileName.endswith("gtest/gtest-typed-test.h") &&
ReplacementFound = FileName.ends_with("gtest/gtest-typed-test.h") &&
PP->getSpelling(MacroNameTok) == "TYPED_TEST_SUITE";
}
}
@ -102,7 +102,7 @@ private:
llvm::StringRef FileName = PP->getSourceManager().getFilename(
MD.getMacroInfo()->getDefinitionLoc());
if (!FileName.endswith("gtest/gtest-typed-test.h"))
if (!FileName.ends_with("gtest/gtest-typed-test.h"))
return;
DiagnosticBuilder Diag = Check->diag(Loc, RenameCaseToSuiteMessage);

View File

@ -40,7 +40,7 @@ void UsingNamespaceDirectiveCheck::check(
bool UsingNamespaceDirectiveCheck::isStdLiteralsNamespace(
const NamespaceDecl *NS) {
if (!NS->getName().endswith("literals"))
if (!NS->getName().ends_with("literals"))
return false;
const auto *Parent = dyn_cast_or_null<NamespaceDecl>(NS->getParent());

View File

@ -54,11 +54,11 @@ std::string LLVMHeaderGuardCheck::getHeaderGuard(StringRef Filename,
std::replace(Guard.begin(), Guard.end(), '-', '_');
// The prevalent style in clang is LLVM_CLANG_FOO_BAR_H
if (StringRef(Guard).startswith("clang"))
if (StringRef(Guard).starts_with("clang"))
Guard = "LLVM_" + Guard;
// The prevalent style in flang is FORTRAN_FOO_BAR_H
if (StringRef(Guard).startswith("flang"))
if (StringRef(Guard).starts_with("flang"))
Guard = "FORTRAN" + Guard.substr(sizeof("flang") - 1);
return StringRef(Guard).upper();

View File

@ -61,13 +61,13 @@ static int getPriority(StringRef Filename, bool IsAngled, bool IsMainModule) {
return 0;
// LLVM and clang headers are in the penultimate position.
if (Filename.startswith("llvm/") || Filename.startswith("llvm-c/") ||
Filename.startswith("clang/") || Filename.startswith("clang-c/"))
if (Filename.starts_with("llvm/") || Filename.starts_with("llvm-c/") ||
Filename.starts_with("clang/") || Filename.starts_with("clang-c/"))
return 2;
// Put these between system and llvm headers to be consistent with LLVM
// clang-format style.
if (Filename.startswith("gtest/") || Filename.startswith("gmock/"))
if (Filename.starts_with("gtest/") || Filename.starts_with("gmock/"))
return 3;
// System headers are sorted to the end.

View File

@ -27,7 +27,7 @@ int main(int argc, char *argv[]) {
std::vector<std::pair<llvm::UTF32, SmallVector<llvm::UTF32>>> Entries;
SmallVector<StringRef> Values;
for (StringRef Line : Lines) {
if (Line.startswith("#"))
if (Line.starts_with("#"))
continue;
Values.clear();

View File

@ -180,7 +180,7 @@ void IncludeCleanerCheck::check(const MatchFinder::MatchResult &Result) {
// Since most private -> public mappings happen in a verbatim way, we
// check textually here. This might go wrong in presence of symlinks or
// header mappings. But that's not different than rest of the places.
if (getCurrentMainFile().endswith(PHeader))
if (getCurrentMainFile().ends_with(PHeader))
continue;
}
auto StdHeader = tooling::stdlib::Header::named(

View File

@ -1285,7 +1285,7 @@ void RedundantExpressionCheck::check(const MatchFinder::MatchResult &Result) {
const auto Diag = diag(Op->getExprLoc(), Message);
for (const auto &KeyValue : Result.Nodes.getMap()) {
if (StringRef(KeyValue.first).startswith("duplicate"))
if (StringRef(KeyValue.first).starts_with("duplicate"))
Diag << KeyValue.second.getSourceRange();
}
}

View File

@ -849,14 +849,14 @@ std::string VariableNamer::createIndexName() {
ContainerName = TheContainer->getName();
size_t Len = ContainerName.size();
if (Len > 1 && ContainerName.endswith(Style == NS_UpperCase ? "S" : "s")) {
if (Len > 1 && ContainerName.ends_with(Style == NS_UpperCase ? "S" : "s")) {
IteratorName = std::string(ContainerName.substr(0, Len - 1));
// E.g.: (auto thing : things)
if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName())
return IteratorName;
}
if (Len > 2 && ContainerName.endswith(Style == NS_UpperCase ? "S_" : "s_")) {
if (Len > 2 && ContainerName.ends_with(Style == NS_UpperCase ? "S_" : "s_")) {
IteratorName = std::string(ContainerName.substr(0, Len - 2));
// E.g.: (auto thing : things_)
if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName())

View File

@ -83,7 +83,7 @@ void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) {
StringRef ContainerText = Lexer::getSourceText(
CharSourceRange::getTokenRange(MatchedDecl->getSourceRange()),
*Result.SourceManager, getLangOpts());
if (ContainerText.startswith("std::"))
if (ContainerText.starts_with("std::"))
NewName = "std::" + NewName;
Diag << FixItHint::CreateRemoval(MatchedDecl->getSourceRange());

View File

@ -41,11 +41,11 @@ AST_MATCHER_P(NamedDecl, hasAnyNameIgnoringTemplates, std::vector<StringRef>,
// FullNameTrimmed matches any of the given Names.
const StringRef FullNameTrimmedRef = FullNameTrimmed;
for (const StringRef Pattern : Names) {
if (Pattern.startswith("::")) {
if (Pattern.starts_with("::")) {
if (FullNameTrimmed == Pattern)
return true;
} else if (FullNameTrimmedRef.endswith(Pattern) &&
FullNameTrimmedRef.drop_back(Pattern.size()).endswith("::")) {
} else if (FullNameTrimmedRef.ends_with(Pattern) &&
FullNameTrimmedRef.drop_back(Pattern.size()).ends_with("::")) {
return true;
}
}

View File

@ -20,7 +20,7 @@ static bool doesNoDiscardMacroExist(ASTContext &Context,
const llvm::StringRef &MacroId) {
// Don't check for the Macro existence if we are using an attribute
// either a C++17 standard attribute or pre C++17 syntax
if (MacroId.startswith("[[") || MacroId.startswith("__attribute__"))
if (MacroId.starts_with("[[") || MacroId.starts_with("__attribute__"))
return true;
// Otherwise look up the macro name in the context to see if its defined.

View File

@ -62,7 +62,7 @@ public:
// Parse the extra command line args.
// FIXME: This is very limited at the moment.
for (StringRef Arg : Args)
if (Arg.startswith("-checks="))
if (Arg.starts_with("-checks="))
OverrideOptions.Checks = std::string(Arg.substr(strlen("-checks=")));
auto Options = std::make_unique<FileOptionsProvider>(

View File

@ -59,17 +59,17 @@ static StringRef trySuggestX86(StringRef Name) {
return {};
// [simd.alg]
if (Name.startswith("max_"))
if (Name.starts_with("max_"))
return "$simd::max";
if (Name.startswith("min_"))
if (Name.starts_with("min_"))
return "$simd::min";
// [simd.binary]
if (Name.startswith("add_"))
if (Name.starts_with("add_"))
return "operator+ on $simd objects";
if (Name.startswith("sub_"))
if (Name.starts_with("sub_"))
return "operator- on $simd objects";
if (Name.startswith("mul_"))
if (Name.starts_with("mul_"))
return "operator* on $simd objects";
return {};

View File

@ -79,7 +79,7 @@ static SourceLocation findEndLocation(const Stmt &S, const SourceManager &SM,
SourceRange TokRange(Loc, TokEndLoc);
StringRef Comment = Lexer::getSourceText(
CharSourceRange::getTokenRange(TokRange), SM, Context->getLangOpts());
if (Comment.startswith("/*") && Comment.contains('\n')) {
if (Comment.starts_with("/*") && Comment.contains('\n')) {
// Multi-line block comment, insert brace before.
break;
}

View File

@ -889,7 +889,7 @@ bool IdentifierNamingCheck::matchesStyle(
// Ensure the name doesn't have any extra underscores beyond those specified
// in the prefix and suffix.
if (Name.startswith("_") || Name.endswith("_"))
if (Name.starts_with("_") || Name.ends_with("_"))
return false;
if (Style.Case && !Matchers[static_cast<size_t>(*Style.Case)].match(Name))

View File

@ -235,7 +235,7 @@ createIsolatedDecls(llvm::ArrayRef<StringRef> Snippets) {
for (std::size_t I = 1; I < Snippets.size(); ++I)
Decls[I - 1] = Twine(Snippets[0])
.concat(Snippets[0].endswith(" ") ? "" : " ")
.concat(Snippets[0].ends_with(" ") ? "" : " ")
.concat(Snippets[I].ltrim())
.concat(";")
.str();

View File

@ -160,7 +160,7 @@ void NamespaceCommentCheck::check(const MatchFinder::MatchResult &Result) {
}
// Otherwise we need to fix the comment.
NeedLineBreak = Comment.startswith("/*");
NeedLineBreak = Comment.starts_with("/*");
OldCommentRange =
SourceRange(AfterRBrace, Loc.getLocWithOffset(Tok.getLength()));
Message =
@ -168,7 +168,7 @@ void NamespaceCommentCheck::check(const MatchFinder::MatchResult &Result) {
"%0 ends with a comment that refers to a wrong namespace '") +
NamespaceNameInComment + "'")
.str();
} else if (Comment.startswith("//")) {
} else if (Comment.starts_with("//")) {
// Assume that this is an unrecognized form of a namespace closing line
// comment. Replace it.
NeedLineBreak = false;

View File

@ -85,7 +85,7 @@ void StaticAccessedThroughInstanceCheck::check(
return;
// Do not warn for CUDA built-in variables.
if (StringRef(BaseTypeName).startswith("__cuda_builtin_"))
if (StringRef(BaseTypeName).starts_with("__cuda_builtin_"))
return;
SourceLocation MemberExprStartLoc = MemberExpression->getBeginLoc();

View File

@ -462,7 +462,7 @@ static bool verifyChecks(const StringSet<> &AllChecks, StringRef CheckGlob,
if (Cur.empty())
continue;
Cur.consume_front("-");
if (Cur.startswith("clang-diagnostic"))
if (Cur.starts_with("clang-diagnostic"))
continue;
if (Cur.contains('*')) {
SmallString<128> RegexText("^");

View File

@ -19,7 +19,7 @@ namespace {
StringRef removeFirstSuffix(StringRef Str, ArrayRef<const char *> Suffixes) {
for (StringRef Suffix : Suffixes) {
if (Str.endswith(Suffix)) {
if (Str.ends_with(Suffix)) {
return Str.substr(0, Str.size() - Suffix.size());
}
}
@ -73,12 +73,12 @@ determineIncludeKind(StringRef CanonicalFile, StringRef IncludeFile,
if (IsAngled) {
// If the system include (<foo>) ends with ".h", then it is a normal C-style
// include. Otherwise assume it is a C++-style extensionless include.
return IncludeFile.endswith(".h") ? IncludeSorter::IK_CSystemInclude
: IncludeSorter::IK_CXXSystemInclude;
return IncludeFile.ends_with(".h") ? IncludeSorter::IK_CSystemInclude
: IncludeSorter::IK_CXXSystemInclude;
}
StringRef CanonicalInclude = makeCanonicalName(IncludeFile, Style);
if (CanonicalFile.endswith(CanonicalInclude)
|| CanonicalInclude.endswith(CanonicalFile)) {
if (CanonicalFile.ends_with(CanonicalInclude) ||
CanonicalInclude.ends_with(CanonicalFile)) {
return IncludeSorter::IK_MainTUInclude;
}
if ((Style == IncludeSorter::IS_Google) ||
@ -95,8 +95,9 @@ determineIncludeKind(StringRef CanonicalFile, StringRef IncludeFile,
}
}
if (Style == IncludeSorter::IS_Google_ObjC) {
if (IncludeFile.endswith(".generated.h") ||
IncludeFile.endswith(".proto.h") || IncludeFile.endswith(".pbobjc.h")) {
if (IncludeFile.ends_with(".generated.h") ||
IncludeFile.ends_with(".proto.h") ||
IncludeFile.ends_with(".pbobjc.h")) {
return IncludeSorter::IK_GeneratedInclude;
}
}

View File

@ -120,7 +120,7 @@ private:
private:
MatchMode determineMatchMode(llvm::StringRef Regex) {
if (Regex.startswith(":") || Regex.startswith("^:")) {
if (Regex.starts_with(":") || Regex.starts_with("^:")) {
return MatchMode::MatchFullyQualified;
}
return Regex.contains(":") ? MatchMode::MatchQualified