256 changes: 247 additions & 9 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,64 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
return this->emitNE(PtrT, CE);
}

case CK_IntegralComplexToBoolean:
case CK_FloatingComplexToBoolean: {
std::optional<PrimType> ElemT =
classifyComplexElementType(SubExpr->getType());
if (!ElemT)
return false;
// We emit the expression (__real(E) != 0 || __imag(E) != 0)
// for us, that means (bool)E[0] || (bool)E[1]
if (!this->visit(SubExpr))
return false;
if (!this->emitConstUint8(0, CE))
return false;
if (!this->emitArrayElemPtrUint8(CE))
return false;
if (!this->emitLoadPop(*ElemT, CE))
return false;
if (*ElemT == PT_Float) {
if (!this->emitCastFloatingIntegral(PT_Bool, CE))
return false;
} else {
if (!this->emitCast(*ElemT, PT_Bool, CE))
return false;
}

// We now have the bool value of E[0] on the stack.
LabelTy LabelTrue = this->getLabel();
if (!this->jumpTrue(LabelTrue))
return false;

if (!this->emitConstUint8(1, CE))
return false;
if (!this->emitArrayElemPtrPopUint8(CE))
return false;
if (!this->emitLoadPop(*ElemT, CE))
return false;
if (*ElemT == PT_Float) {
if (!this->emitCastFloatingIntegral(PT_Bool, CE))
return false;
} else {
if (!this->emitCast(*ElemT, PT_Bool, CE))
return false;
}
// Leave the boolean value of E[1] on the stack.
LabelTy EndLabel = this->getLabel();
this->jump(EndLabel);

this->emitLabel(LabelTrue);
if (!this->emitPopPtr(CE))
return false;
if (!this->emitConstBool(true, CE))
return false;

this->fallthrough(EndLabel);
this->emitLabel(EndLabel);

return true;
}

case CK_ToVoid:
return discard(SubExpr);

Expand Down Expand Up @@ -258,6 +316,9 @@ bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
if (BO->isLogicalOp())
return this->VisitLogicalBinOp(BO);

if (BO->getType()->isAnyComplexType())
return this->VisitComplexBinOp(BO);

const Expr *LHS = BO->getLHS();
const Expr *RHS = BO->getRHS();

Expand Down Expand Up @@ -500,6 +561,107 @@ bool ByteCodeExprGen<Emitter>::VisitLogicalBinOp(const BinaryOperator *E) {
return true;
}

template <class Emitter>
bool ByteCodeExprGen<Emitter>::VisitComplexBinOp(const BinaryOperator *E) {
// FIXME: We expect a pointer on the stack here.
// we should not do that, but that's part of a bigger rework.
const Expr *LHS = E->getLHS();
const Expr *RHS = E->getRHS();
PrimType LHSElemT = *this->classifyComplexElementType(LHS->getType());
PrimType RHSElemT = *this->classifyComplexElementType(RHS->getType());

unsigned LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false);
unsigned RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false);
unsigned ResultOffset = ~0u;
if (!this->DiscardResult)
ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, true, false);

assert(LHSElemT == RHSElemT);

// Save result pointer in ResultOffset
if (!this->DiscardResult) {
if (!this->emitDupPtr(E))
return false;
if (!this->emitSetLocal(PT_Ptr, ResultOffset, E))
return false;
}

// Evaluate LHS and save value to LHSOffset.
if (!this->visit(LHS))
return false;
if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
return false;

// Same with RHS.
if (!this->visit(RHS))
return false;
if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
return false;

// Now we can get pointers to the LHS and RHS from the offsets above.
BinaryOperatorKind Op = E->getOpcode();
for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
// Result pointer for the store later.
if (!this->DiscardResult) {
if (!this->emitGetLocal(PT_Ptr, ResultOffset, E))
return false;
}

if (!this->emitGetLocal(PT_Ptr, LHSOffset, E))
return false;
if (!this->emitConstUint8(ElemIndex, E))
return false;
if (!this->emitArrayElemPtrPopUint8(E))
return false;
if (!this->emitLoadPop(LHSElemT, E))
return false;

if (!this->emitGetLocal(PT_Ptr, RHSOffset, E))
return false;
if (!this->emitConstUint8(ElemIndex, E))
return false;
if (!this->emitArrayElemPtrPopUint8(E))
return false;
if (!this->emitLoadPop(RHSElemT, E))
return false;

// The actual operation.
switch (Op) {
case BO_Add:
if (LHSElemT == PT_Float) {
if (!this->emitAddf(getRoundingMode(E), E))
return false;
} else {
if (!this->emitAdd(LHSElemT, E))
return false;
}
break;
case BO_Sub:
if (LHSElemT == PT_Float) {
if (!this->emitSubf(getRoundingMode(E), E))
return false;
} else {
if (!this->emitSub(LHSElemT, E))
return false;
}
break;

default:
return false;
}

if (!this->DiscardResult) {
// Initialize array element with the value we just computed.
if (!this->emitInitElemPop(LHSElemT, ElemIndex, E))
return false;
} else {
if (!this->emitPop(LHSElemT, E))
return false;
}
}
return true;
}

template <class Emitter>
bool ByteCodeExprGen<Emitter>::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
QualType QT = E->getType();
Expand Down Expand Up @@ -671,6 +833,32 @@ bool ByteCodeExprGen<Emitter>::VisitInitListExpr(const InitListExpr *E) {
return true;
}

if (T->isAnyComplexType()) {
unsigned NumInits = E->getNumInits();
QualType ElemQT = E->getType()->getAs<ComplexType>()->getElementType();
PrimType ElemT = classifyPrim(ElemQT);
if (NumInits == 0) {
// Zero-initialize both elements.
for (unsigned I = 0; I < 2; ++I) {
if (!this->visitZeroInitializer(ElemT, ElemQT, E))
return false;
if (!this->emitInitElem(ElemT, I, E))
return false;
}
} else if (NumInits == 2) {
unsigned InitIndex = 0;
for (const Expr *Init : E->inits()) {
if (!this->visit(Init))
return false;

if (!this->emitInitElem(ElemT, InitIndex, E))
return false;
++InitIndex;
}
}
return true;
}

return false;
}

Expand Down Expand Up @@ -1647,7 +1835,8 @@ template <class Emitter> bool ByteCodeExprGen<Emitter>::visit(const Expr *E) {
return this->discard(E);

// Create local variable to hold the return value.
if (!E->isGLValue() && !classify(E->getType())) {
if (!E->isGLValue() && !E->getType()->isAnyComplexType() &&
!classify(E->getType())) {
std::optional<unsigned> LocalIndex = allocateLocal(E, /*IsExtended=*/true);
if (!LocalIndex)
return false;
Expand Down Expand Up @@ -1833,6 +2022,9 @@ bool ByteCodeExprGen<Emitter>::dereference(
return Indirect(*T);
}

if (LV->getType()->isAnyComplexType())
return visit(LV);

return false;
}

Expand Down Expand Up @@ -2092,15 +2284,33 @@ const Function *ByteCodeExprGen<Emitter>::getFunction(const FunctionDecl *FD) {
template <class Emitter>
bool ByteCodeExprGen<Emitter>::visitExpr(const Expr *E) {
ExprScope<Emitter> RootScope(this);
if (!visit(E))
return false;

if (E->getType()->isVoidType())
// Void expressions.
if (E->getType()->isVoidType()) {
if (!visit(E))
return false;
return this->emitRetVoid(E);
}

if (std::optional<PrimType> T = classify(E))
// Expressions with a primitive return type.
if (std::optional<PrimType> T = classify(E)) {
if (!visit(E))
return false;
return this->emitRet(*T, E);
return this->emitRetValue(E);
}

// Expressions with a composite return type.
// For us, that means everything we don't
// have a PrimType for.
if (std::optional<unsigned> LocalOffset = this->allocateLocal(E)) {
if (!this->visitLocalInitializer(E, *LocalOffset))
return false;

if (!this->emitGetPtrLocal(*LocalOffset, E))
return false;
return this->emitRetValue(E);
}

return false;
}

/// Toplevel visitDecl().
Expand Down Expand Up @@ -2550,8 +2760,36 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
if (!this->visit(SubExpr))
return false;
return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
case UO_Real: // __real x
case UO_Imag: // __imag x
case UO_Real: { // __real x
assert(!T);
if (!this->visit(SubExpr))
return false;
if (!this->emitConstUint8(0, E))
return false;
if (!this->emitArrayElemPtrPopUint8(E))
return false;

// Since our _Complex implementation does not map to a primitive type,
// we sometimes have to do the lvalue-to-rvalue conversion here manually.
if (!SubExpr->isLValue())
return this->emitLoadPop(classifyPrim(E->getType()), E);
return true;
}
case UO_Imag: { // __imag x
assert(!T);
if (!this->visit(SubExpr))
return false;
if (!this->emitConstUint8(1, E))
return false;
if (!this->emitArrayElemPtrPopUint8(E))
return false;

// Since our _Complex implementation does not map to a primitive type,
// we sometimes have to do the lvalue-to-rvalue conversion here manually.
if (!SubExpr->isLValue())
return this->emitLoadPop(classifyPrim(E->getType()), E);
return true;
}
case UO_Extension:
return this->delegate(SubExpr);
case UO_Coawait:
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/AST/Interp/ByteCodeExprGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
bool VisitBinaryOperator(const BinaryOperator *E);
bool VisitLogicalBinOp(const BinaryOperator *E);
bool VisitPointerArithBinOp(const BinaryOperator *E);
bool VisitComplexBinOp(const BinaryOperator *E);
bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E);
bool VisitCallExpr(const CallExpr *E);
bool VisitBuiltinCallExpr(const CallExpr *E);
Expand Down Expand Up @@ -285,6 +286,14 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
}

bool emitPrimCast(PrimType FromT, PrimType ToT, QualType ToQT, const Expr *E);
std::optional<PrimType> classifyComplexElementType(QualType T) const {
assert(T->isAnyComplexType());

QualType ElemType = T->getAs<ComplexType>()->getElementType();

return this->classify(ElemType);
}

bool emitRecordDestruction(const Descriptor *Desc);
unsigned collectBaseOffset(const RecordType *BaseType,
const RecordType *DerivedType);
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/Interp/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ std::optional<PrimType> Context::classify(QualType T) const {
if (T->isBooleanType())
return PT_Bool;

if (T->isAnyComplexType())
return std::nullopt;

if (T->isSignedIntegerOrEnumerationType()) {
switch (Ctx.getIntWidth(T)) {
case 64:
Expand Down
21 changes: 21 additions & 0 deletions clang/lib/AST/Interp/EvalEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,27 @@ bool EvalEmitter::emitRetValue(const SourceInfo &Info) {
}
return Ok;
}

// Complex types.
if (const auto *CT = Ty->getAs<ComplexType>()) {
QualType ElemTy = CT->getElementType();
std::optional<PrimType> ElemT = Ctx.classify(ElemTy);
assert(ElemT);

if (ElemTy->isIntegerType()) {
INT_TYPE_SWITCH(*ElemT, {
auto V1 = Ptr.atIndex(0).deref<T>();
auto V2 = Ptr.atIndex(1).deref<T>();
Result = APValue(V1.toAPSInt(), V2.toAPSInt());
return true;
});
} else if (ElemTy->isFloatingType()) {
Result = APValue(Ptr.atIndex(0).deref<Floating>().getAPFloat(),
Ptr.atIndex(1).deref<Floating>().getAPFloat());
return true;
}
return false;
}
llvm_unreachable("invalid value to return");
};

Expand Down
19 changes: 11 additions & 8 deletions clang/lib/AST/Interp/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,11 +350,6 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
}

if (!F->isConstexpr()) {
// Don't emit anything if we're checking for a potential constant
// expression. That will happen later when actually executing.
if (S.checkingPotentialConstantExpression())
return false;

const SourceLocation &Loc = S.Current->getLocation(OpPC);
if (S.getLangOpts().CPlusPlus11) {
const FunctionDecl *DiagDecl = F->getDecl();
Expand All @@ -371,13 +366,21 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) {
// FIXME: If DiagDecl is an implicitly-declared special member function
// or an inheriting constructor, we should be much more explicit about why
// it's not constexpr.
if (CD && CD->isInheritingConstructor())
if (CD && CD->isInheritingConstructor()) {
S.FFDiag(Loc, diag::note_constexpr_invalid_inhctor, 1)
<< CD->getInheritedConstructor().getConstructor()->getParent();
else
S.Note(DiagDecl->getLocation(), diag::note_declared_at);
} else {
// Don't emit anything if the function isn't defined and we're checking
// for a constant expression. It might be defined at the point we're
// actually calling it.
if (!DiagDecl->isDefined() && S.checkingPotentialConstantExpression())
return false;

S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1)
<< DiagDecl->isConstexpr() << (bool)CD << DiagDecl;
S.Note(DiagDecl->getLocation(), diag::note_declared_at);
S.Note(DiagDecl->getLocation(), diag::note_declared_at);
}
} else {
S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Mangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) {

// If the label isn't literal, or if this is an alias for an LLVM intrinsic,
// do not add a "\01" prefix.
if (!ALA->getIsLiteralLabel() || ALA->getLabel().startswith("llvm.")) {
if (!ALA->getIsLiteralLabel() || ALA->getLabel().starts_with("llvm.")) {
Out << ALA->getLabel();
return;
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct msvc_hashing_ostream : public llvm::raw_svector_ostream {
: llvm::raw_svector_ostream(Buffer), OS(OS) {}
~msvc_hashing_ostream() override {
StringRef MangledName = str();
bool StartsWithEscape = MangledName.startswith("\01");
bool StartsWithEscape = MangledName.starts_with("\01");
if (StartsWithEscape)
MangledName = MangledName.drop_front(1);
if (MangledName.size() < 4096) {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/PrintfFormatString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
// Set the privacy flag if the privacy annotation in the
// comma-delimited segment is at least as strict as the privacy
// annotations in previous comma-delimited segments.
if (MatchedStr.startswith("mask")) {
if (MatchedStr.starts_with("mask")) {
StringRef MaskType = MatchedStr.substr(sizeof("mask.") - 1);
unsigned Size = MaskType.size();
if (Warn && (Size == 0 || Size > 8))
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/RawCommentList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ RawComment::RawComment(const SourceManager &SourceMgr, SourceRange SR,
Kind = K.first;
IsTrailingComment |= K.second;

IsAlmostTrailingComment = RawText.startswith("//<") ||
RawText.startswith("/*<");
IsAlmostTrailingComment =
RawText.starts_with("//<") || RawText.starts_with("/*<");
} else {
Kind = RCK_Merged;
IsTrailingComment =
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/AST/Stmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -811,11 +811,12 @@ std::string MSAsmStmt::generateAsmString(const ASTContext &C) const {
StringRef Instruction = Pieces[I];
// For vex/vex2/vex3/evex masm style prefix, convert it to att style
// since we don't support masm style prefix in backend.
if (Instruction.startswith("vex "))
if (Instruction.starts_with("vex "))
MSAsmString += '{' + Instruction.substr(0, 3).str() + '}' +
Instruction.substr(3).str();
else if (Instruction.startswith("vex2 ") ||
Instruction.startswith("vex3 ") || Instruction.startswith("evex "))
else if (Instruction.starts_with("vex2 ") ||
Instruction.starts_with("vex3 ") ||
Instruction.starts_with("evex "))
MSAsmString += '{' + Instruction.substr(0, 4).str() + '}' +
Instruction.substr(4).str();
else
Expand Down
12 changes: 6 additions & 6 deletions clang/lib/ASTMatchers/ASTMatchersInternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,11 +480,11 @@ HasNameMatcher::HasNameMatcher(std::vector<std::string> N)

static bool consumeNameSuffix(StringRef &FullName, StringRef Suffix) {
StringRef Name = FullName;
if (!Name.endswith(Suffix))
if (!Name.ends_with(Suffix))
return false;
Name = Name.drop_back(Suffix.size());
if (!Name.empty()) {
if (!Name.endswith("::"))
if (!Name.ends_with("::"))
return false;
Name = Name.drop_back(2);
}
Expand Down Expand Up @@ -530,7 +530,7 @@ class PatternSet {
PatternSet(ArrayRef<std::string> Names) {
Patterns.reserve(Names.size());
for (StringRef Name : Names)
Patterns.push_back({Name, Name.startswith("::")});
Patterns.push_back({Name, Name.starts_with("::")});
}

/// Consumes the name suffix from each pattern in the set and removes the ones
Expand Down Expand Up @@ -652,11 +652,11 @@ bool HasNameMatcher::matchesNodeFullSlow(const NamedDecl &Node) const {
const StringRef FullName = OS.str();

for (const StringRef Pattern : Names) {
if (Pattern.startswith("::")) {
if (Pattern.starts_with("::")) {
if (FullName == Pattern)
return true;
} else if (FullName.endswith(Pattern) &&
FullName.drop_back(Pattern.size()).endswith("::")) {
} else if (FullName.ends_with(Pattern) &&
FullName.drop_back(Pattern.size()).ends_with("::")) {
return true;
}
}
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/ASTMatchers/Dynamic/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,10 @@ class Parser::CodeTokenizer {
break;
++TokenLength;
}
if (TokenLength == 4 && Code.startswith("true")) {
if (TokenLength == 4 && Code.starts_with("true")) {
Result.Kind = TokenInfo::TK_Literal;
Result.Value = true;
} else if (TokenLength == 5 && Code.startswith("false")) {
} else if (TokenLength == 5 && Code.starts_with("false")) {
Result.Kind = TokenInfo::TK_Literal;
Result.Value = false;
} else {
Expand Down Expand Up @@ -737,7 +737,7 @@ bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken,
// Completions minus the prefix.
void Parser::addCompletion(const TokenInfo &CompToken,
const MatcherCompletion& Completion) {
if (StringRef(Completion.TypedText).startswith(CompToken.Text) &&
if (StringRef(Completion.TypedText).starts_with(CompToken.Text) &&
Completion.Specificity > 0) {
Completions.emplace_back(Completion.TypedText.substr(CompToken.Text.size()),
Completion.MatcherDecl, Completion.Specificity);
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Analysis/BodyFarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -726,8 +726,8 @@ Stmt *BodyFarm::getBody(const FunctionDecl *D) {
FF = nullptr;
break;
}
} else if (Name.startswith("OSAtomicCompareAndSwap") ||
Name.startswith("objc_atomicCompareAndSwap")) {
} else if (Name.starts_with("OSAtomicCompareAndSwap") ||
Name.starts_with("objc_atomicCompareAndSwap")) {
FF = create_OSAtomicCompareAndSwap;
} else if (Name == "call_once" && D->getDeclContext()->isStdNamespace()) {
FF = create_call_once;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Analysis/CallGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ bool CallGraph::includeCalleeInGraph(const Decl *D) {
return false;

IdentifierInfo *II = FD->getIdentifier();
if (II && II->getName().startswith("__inline"))
if (II && II->getName().starts_with("__inline"))
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Analysis/CalledOnceCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,7 @@ class CalledOnceChecker : public ConstStmtVisitor<CalledOnceChecker> {
/// Return true if the given name has conventional suffixes.
static bool hasConventionalSuffix(llvm::StringRef Name) {
return llvm::any_of(CONVENTIONAL_SUFFIXES, [Name](llvm::StringRef Suffix) {
return Name.endswith(Suffix);
return Name.ends_with(Suffix);
});
}

Expand Down
11 changes: 5 additions & 6 deletions clang/lib/Analysis/CocoaConventions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ bool cocoa::isRefType(QualType RetTy, StringRef Prefix,
// Recursively walk the typedef stack, allowing typedefs of reference types.
while (const TypedefType *TD = RetTy->getAs<TypedefType>()) {
StringRef TDName = TD->getDecl()->getIdentifier()->getName();
if (TDName.startswith(Prefix) && TDName.endswith("Ref"))
if (TDName.starts_with(Prefix) && TDName.ends_with("Ref"))
return true;
// XPC unfortunately uses CF-style function names, but aren't CF types.
if (TDName.startswith("xpc_"))
if (TDName.starts_with("xpc_"))
return false;
RetTy = TD->getDecl()->getUnderlyingType();
}
Expand All @@ -43,7 +43,7 @@ bool cocoa::isRefType(QualType RetTy, StringRef Prefix,
return false;

// Does the name start with the prefix?
return Name.startswith(Prefix);
return Name.starts_with(Prefix);
}

/// Returns true when the passed-in type is a CF-style reference-counted
Expand Down Expand Up @@ -127,10 +127,9 @@ bool coreFoundation::followsCreateRule(const FunctionDecl *fn) {
// Scan for *lowercase* 'reate' or 'opy', followed by no lowercase
// character.
StringRef suffix = functionName.substr(it - start);
if (suffix.startswith("reate")) {
if (suffix.starts_with("reate")) {
it += 5;
}
else if (suffix.startswith("opy")) {
} else if (suffix.starts_with("opy")) {
it += 3;
} else {
// Keep scanning.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ bool isCheckLikeMethod(llvm::SmallDenseSet<const CXXMethodDecl *> &CheckDecls,
return false;

for (const CXXMethodDecl *M : ParentClass->methods())
if (M->getDeclName().isIdentifier() && M->getName().endswith("Check"))
if (M->getDeclName().isIdentifier() && M->getName().ends_with("Check"))
CheckDecls.insert(M);
}

Expand Down
14 changes: 7 additions & 7 deletions clang/lib/Analysis/RetainSummaryManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ static bool isOSObjectPtr(QualType QT) {
}

static bool isISLObjectRef(QualType Ty) {
return StringRef(Ty.getAsString()).startswith("isl_");
return StringRef(Ty.getAsString()).starts_with("isl_");
}

static bool isOSIteratorSubclass(const Decl *D) {
Expand Down Expand Up @@ -255,13 +255,13 @@ RetainSummaryManager::getSummaryForOSObject(const FunctionDecl *FD,
// TODO: Add support for the slightly common *Matching(table) idiom.
// Cf. IOService::nameMatching() etc. - these function have an unusual
// contract of returning at +0 or +1 depending on their last argument.
if (FName.endswith("Matching")) {
if (FName.ends_with("Matching")) {
return getPersistentStopSummary();
}

// All objects returned with functions *not* starting with 'get',
// or iterators, are returned at +1.
if ((!FName.startswith("get") && !FName.startswith("Get")) ||
if ((!FName.starts_with("get") && !FName.starts_with("Get")) ||
isOSIteratorSubclass(PD)) {
return getOSSummaryCreateRule(FD);
} else {
Expand Down Expand Up @@ -392,9 +392,9 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(
return getPersistentSummary(RetEffect::MakeNoRet(),
ScratchArgs,
ArgEffect(DoNothing), ArgEffect(DoNothing));
} else if (FName.startswith("NSLog")) {
} else if (FName.starts_with("NSLog")) {
return getDoNothingSummary();
} else if (FName.startswith("NS") && FName.contains("Insert")) {
} else if (FName.starts_with("NS") && FName.contains("Insert")) {
// Allowlist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
// be deallocated by NSMapRemove.
ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(StopTracking));
Expand Down Expand Up @@ -453,9 +453,9 @@ const RetainSummary *RetainSummaryManager::getSummaryForObjCOrCFObject(

// Check for release functions, the only kind of functions that we care
// about that don't return a pointer type.
if (FName.startswith("CG") || FName.startswith("CF")) {
if (FName.starts_with("CG") || FName.starts_with("CF")) {
// Test for 'CGCF'.
FName = FName.substr(FName.startswith("CGCF") ? 4 : 2);
FName = FName.substr(FName.starts_with("CGCF") ? 4 : 2);

if (isRelease(FD, FName))
return getUnarySummary(FT, DecRef);
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Basic/Attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
const TargetInfo &Target, const LangOptions &LangOpts) {
StringRef Name = Attr->getName();
// Normalize the attribute name, __foo__ becomes foo.
if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
if (Name.size() >= 4 && Name.starts_with("__") && Name.ends_with("__"))
Name = Name.substr(2, Name.size() - 4);

// Normalize the scope name, but only for gnu and clang attributes.
Expand Down Expand Up @@ -103,8 +103,8 @@ static StringRef normalizeAttrName(const IdentifierInfo *Name,
(NormalizedScopeName.empty() || NormalizedScopeName == "gnu" ||
NormalizedScopeName == "clang"));
StringRef AttrName = Name->getName();
if (ShouldNormalize && AttrName.size() >= 4 && AttrName.startswith("__") &&
AttrName.endswith("__"))
if (ShouldNormalize && AttrName.size() >= 4 && AttrName.starts_with("__") &&
AttrName.ends_with("__"))
AttrName = AttrName.slice(2, AttrName.size() - 2);

return AttrName;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/DiagnosticIDs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -853,5 +853,5 @@ bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const {

bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) {
unsigned cat = getCategoryNumberForDiag(DiagID);
return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC ");
return DiagnosticIDs::getCategoryNameFromID(cat).starts_with("ARC ");
}
4 changes: 2 additions & 2 deletions clang/lib/Basic/IdentifierTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ LLVM_DUMP_METHOD void Selector::dump() const { print(llvm::errs()); }
static bool startsWithWord(StringRef name, StringRef word) {
if (name.size() < word.size()) return false;
return ((name.size() == word.size() || !isLowercase(name[word.size()])) &&
name.startswith(word));
name.starts_with(word));
}

ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) {
Expand Down Expand Up @@ -742,7 +742,7 @@ SelectorTable::constructSetterSelector(IdentifierTable &Idents,

std::string SelectorTable::getPropertyNameFromSetterSelector(Selector Sel) {
StringRef Name = Sel.getNameForSlot(0);
assert(Name.startswith("set") && "invalid setter name");
assert(Name.starts_with("set") && "invalid setter name");
return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str();
}

Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Basic/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ bool Module::isForBuilding(const LangOptions &LangOpts) const {
// for either.
if (!LangOpts.isCompilingModule() && getTopLevelModule()->IsFramework &&
CurrentModule == LangOpts.ModuleName &&
!CurrentModule.endswith("_Private") && TopLevelName.endswith("_Private"))
!CurrentModule.ends_with("_Private") &&
TopLevelName.ends_with("_Private"))
TopLevelName = TopLevelName.drop_back(8);

return TopLevelName == CurrentModule;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Sarif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static std::string fileNameToURI(StringRef Filename) {

// Get the root name to see if it has a URI authority.
StringRef Root = sys::path::root_name(Filename);
if (Root.startswith("//")) {
if (Root.starts_with("//")) {
// There is an authority, so add it to the URI.
Ret += Root.drop_front(2).str();
} else if (!Root.empty()) {
Expand Down
10 changes: 5 additions & 5 deletions clang/lib/Basic/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -551,26 +551,26 @@ ParsedTargetAttr TargetInfo::parseTargetAttr(StringRef Features) const {
// TODO: Support the fpmath option. It will require checking
// overall feature validity for the function with the rest of the
// attributes on the function.
if (Feature.startswith("fpmath="))
if (Feature.starts_with("fpmath="))
continue;

if (Feature.startswith("branch-protection=")) {
if (Feature.starts_with("branch-protection=")) {
Ret.BranchProtection = Feature.split('=').second.trim();
continue;
}

// While we're here iterating check for a different target cpu.
if (Feature.startswith("arch=")) {
if (Feature.starts_with("arch=")) {
if (!Ret.CPU.empty())
Ret.Duplicate = "arch=";
else
Ret.CPU = Feature.split("=").second.trim();
} else if (Feature.startswith("tune=")) {
} else if (Feature.starts_with("tune=")) {
if (!Ret.Tune.empty())
Ret.Duplicate = "tune=";
else
Ret.Tune = Feature.split("=").second.trim();
} else if (Feature.startswith("no-"))
} else if (Feature.starts_with("no-"))
Ret.Features.push_back("-" + Feature.split("-").second.str());
else
Ret.Features.push_back("+" + Feature.str());
Expand Down
16 changes: 8 additions & 8 deletions clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,7 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
else
// Pushing the original feature string to give a sema error later on
// when they get checked.
if (Feature.startswith("no"))
if (Feature.starts_with("no"))
Features.push_back("-" + Feature.drop_front(2).str());
else
Features.push_back("+" + Feature.str());
Expand All @@ -1071,15 +1071,15 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {

for (auto &Feature : AttrFeatures) {
Feature = Feature.trim();
if (Feature.startswith("fpmath="))
if (Feature.starts_with("fpmath="))
continue;

if (Feature.startswith("branch-protection=")) {
if (Feature.starts_with("branch-protection=")) {
Ret.BranchProtection = Feature.split('=').second.trim();
continue;
}

if (Feature.startswith("arch=")) {
if (Feature.starts_with("arch=")) {
if (FoundArch)
Ret.Duplicate = "arch=";
FoundArch = true;
Expand All @@ -1095,7 +1095,7 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
Ret.Features.push_back(AI->ArchFeature.str());
// Add any extra features, after the +
SplitAndAddFeatures(Split.second, Ret.Features);
} else if (Feature.startswith("cpu=")) {
} else if (Feature.starts_with("cpu=")) {
if (!Ret.CPU.empty())
Ret.Duplicate = "cpu=";
else {
Expand All @@ -1106,14 +1106,14 @@ ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
Ret.CPU = Split.first;
SplitAndAddFeatures(Split.second, Ret.Features);
}
} else if (Feature.startswith("tune=")) {
} else if (Feature.starts_with("tune=")) {
if (!Ret.Tune.empty())
Ret.Duplicate = "tune=";
else
Ret.Tune = Feature.split("=").second.trim();
} else if (Feature.startswith("+")) {
} else if (Feature.starts_with("+")) {
SplitAndAddFeatures(Feature, Ret.Features);
} else if (Feature.startswith("no-")) {
} else if (Feature.starts_with("no-")) {
StringRef FeatureName =
llvm::AArch64::getArchExtFeature(Feature.split("-").second);
if (!FeatureName.empty())
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/AMDGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro(Twine("__") + Twine(CanonName) + Twine("__"));
// Emit macros for gfx family e.g. gfx906 -> __GFX9__, gfx1030 -> __GFX10___
if (isAMDGCN(getTriple())) {
assert(CanonName.startswith("gfx") && "Invalid amdgcn canonical name");
assert(CanonName.starts_with("gfx") && "Invalid amdgcn canonical name");
Builder.defineMacro(Twine("__") + Twine(CanonName.drop_back(2).upper()) +
Twine("__"));
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/Mips.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ void MipsTargetInfo::getTargetDefines(const LangOptions &Opts,
else
Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());

if (StringRef(CPU).startswith("octeon"))
if (StringRef(CPU).starts_with("octeon"))
Builder.defineMacro("__OCTEON__");

if (CPU != "mips1") {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/NVPTX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
PTXVersion = 32;
for (const StringRef Feature : Opts.FeaturesAsWritten) {
int PTXV;
if (!Feature.startswith("+ptx") ||
if (!Feature.starts_with("+ptx") ||
Feature.drop_front(4).getAsInteger(10, PTXV))
continue;
PTXVersion = PTXV; // TODO: should it be max(PTXVersion, PTXV)?
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Basic/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,14 +434,14 @@ ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const {
Feature = Feature.trim();
StringRef AttrString = Feature.split("=").second.trim();

if (Feature.startswith("arch=")) {
if (Feature.starts_with("arch=")) {
// Override last features
Ret.Features.clear();
if (FoundArch)
Ret.Duplicate = "arch=";
FoundArch = true;

if (AttrString.startswith("+")) {
if (AttrString.starts_with("+")) {
// EXTENSION like arch=+v,+zbb
SmallVector<StringRef, 1> Exts;
AttrString.split(Exts, ",");
Expand All @@ -461,7 +461,7 @@ ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const {
// full-arch-string like arch=rv64gcv
handleFullArchString(AttrString, Ret.Features);
}
} else if (Feature.startswith("cpu=")) {
} else if (Feature.starts_with("cpu=")) {
if (!Ret.CPU.empty())
Ret.Duplicate = "cpu=";

Expand All @@ -475,7 +475,7 @@ ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const {
handleFullArchString(MarchFromCPU, Ret.Features);
}
}
} else if (Feature.startswith("tune=")) {
} else if (Feature.starts_with("tune=")) {
if (!Ret.Tune.empty())
Ret.Duplicate = "tune=";

Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Basic/Warnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,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 = true;
if (Opt.startswith("no-")) {
if (Opt.starts_with("no-")) {
isPositive = false;
Opt = Opt.substr(3);
}
Expand Down Expand Up @@ -133,7 +133,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
// table. It also has the "specifier" form of -Werror=foo. GCC supports
// the deprecated -Werror-implicit-function-declaration which is used by
// a few projects.
if (Opt.startswith("error")) {
if (Opt.starts_with("error")) {
StringRef Specifier;
if (Opt.size() > 5) { // Specifier must be present.
if (Opt[5] != '=' &&
Expand Down Expand Up @@ -162,7 +162,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
}

// -Wfatal-errors is yet another special case.
if (Opt.startswith("fatal-errors")) {
if (Opt.starts_with("fatal-errors")) {
StringRef Specifier;
if (Opt.size() != 12) {
if ((Opt[12] != '=' && Opt[12] != '-') || Opt.size() == 13) {
Expand Down Expand Up @@ -204,7 +204,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.startswith("no-");
bool IsPositive = !Opt.starts_with("no-");
if (!IsPositive) Opt = Opt.substr(3);

auto Severity = IsPositive ? diag::Severity::Remark
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9985,6 +9985,10 @@ CodeGenFunction::getSVEOverloadTypes(const SVETypeFlags &TypeFlags,
if (TypeFlags.isOverloadCvt())
return {Ops[0]->getType(), Ops.back()->getType()};

if (TypeFlags.isReductionQV() && !ResultType->isScalableTy() &&
ResultType->isVectorTy())
return {ResultType, Ops[1]->getType()};

assert(TypeFlags.isOverloadDefault() && "Unexpected value for overloads");
return {DefaultType};
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5609,7 +5609,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
EmitBlock(Cont);
}
if (CI->getCalledFunction() && CI->getCalledFunction()->hasName() &&
CI->getCalledFunction()->getName().startswith("_Z4sqrt")) {
CI->getCalledFunction()->getName().starts_with("_Z4sqrt")) {
SetSqrtFPAccuracy(CI);
}
if (callOrInvoke)
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,8 @@ void CGDebugInfo::CreateCompileUnit() {
Sysroot = CGM.getHeaderSearchOpts().Sysroot;
auto B = llvm::sys::path::rbegin(Sysroot);
auto E = llvm::sys::path::rend(Sysroot);
auto It = std::find_if(B, E, [](auto SDK) { return SDK.endswith(".sdk"); });
auto It =
std::find_if(B, E, [](auto SDK) { return SDK.ends_with(".sdk"); });
if (It != E)
SDK = *It;
}
Expand Down Expand Up @@ -2885,7 +2886,7 @@ llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
// clang::Module object, but it won't actually be built or imported; it will
// be textual.
if (CreateSkeletonCU && IsRootModule && Mod.getASTFile().empty() && M)
assert(StringRef(M->Name).startswith(CGM.getLangOpts().ModuleName) &&
assert(StringRef(M->Name).starts_with(CGM.getLangOpts().ModuleName) &&
"clang module without ASTFile must be specified by -fmodule-name");

// Return a StringRef to the remapped Path.
Expand Down Expand Up @@ -4249,7 +4250,7 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,

Flags |= llvm::DINode::FlagPrototyped;
}
if (Name.startswith("\01"))
if (Name.starts_with("\01"))
Name = Name.substr(1);

assert((!D || !isa<VarDecl>(D) ||
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/CodeGen/CGException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI) {
if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
// ObjC EH selector entries are always global variables with
// names starting like this.
if (GV->getName().startswith("OBJC_EHTYPE"))
if (GV->getName().starts_with("OBJC_EHTYPE"))
return false;
} else {
// Check if any of the filter values have the ObjC prefix.
Expand All @@ -288,7 +288,7 @@ static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI) {
cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
// ObjC EH selector entries are always global variables with
// names starting like this.
if (GV->getName().startswith("OBJC_EHTYPE"))
if (GV->getName().starts_with("OBJC_EHTYPE"))
return false;
}
}
Expand Down Expand Up @@ -1917,7 +1917,7 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,
const VarDecl *D = cast<VarDecl>(I.first);
if (isa<ImplicitParamDecl>(D) &&
D->getType() == getContext().VoidPtrTy) {
assert(D->getName().startswith("frame_pointer"));
assert(D->getName().starts_with("frame_pointer"));
FramePtrAddrAlloca = cast<llvm::AllocaInst>(I.second.getPointer());
break;
}
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ static Address createReferenceTemporary(CodeGenFunction &CGF,

/// Helper method to check if the underlying ABI is AAPCS
static bool isAAPCS(const TargetInfo &TargetInfo) {
return TargetInfo.getABI().startswith("aapcs");
return TargetInfo.getABI().starts_with("aapcs");
}

LValue CodeGenFunction::
Expand Down Expand Up @@ -3156,7 +3156,7 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
auto SL = E->getFunctionName();
assert(SL != nullptr && "No StringLiteral name in PredefinedExpr");
StringRef FnName = CurFn->getName();
if (FnName.startswith("\01"))
if (FnName.starts_with("\01"))
FnName = FnName.substr(1);
StringRef NameItems[] = {
PredefinedExpr::getIdentKindName(E->getIdentKind()), FnName};
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGObjCMac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1850,7 +1850,7 @@ static bool hasObjCExceptionAttribute(ASTContext &Context,
static llvm::GlobalValue::LinkageTypes
getLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section) {
if (CGM.getTriple().isOSBinFormatMachO() &&
(Section.empty() || Section.startswith("__DATA")))
(Section.empty() || Section.starts_with("__DATA")))
return llvm::GlobalValue::InternalLinkage;
return llvm::GlobalValue::PrivateLinkage;
}
Expand Down Expand Up @@ -6162,7 +6162,7 @@ void CGObjCNonFragileABIMac::AddModuleClassList(
// Section name is obtained by calling GetSectionName, which returns
// sections in the __DATA segment on MachO.
assert((!CGM.getTriple().isOSBinFormatMachO() ||
SectionName.startswith("__DATA")) &&
SectionName.starts_with("__DATA")) &&
"SectionName expected to start with __DATA on MachO");
llvm::GlobalVariable *GV = new llvm::GlobalVariable(
CGM.getModule(), Init->getType(), false,
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ struct CGRecordLowering {

/// Helper function to check if we are targeting AAPCS.
bool isAAPCS() const {
return Context.getTargetInfo().getABI().startswith("aapcs");
return Context.getTargetInfo().getABI().starts_with("aapcs");
}

/// Helper function to check if the target machine is BigEndian.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2548,7 +2548,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
ResultRegQualTys.push_back(QTy);
ResultRegDests.push_back(Dest);

bool IsFlagReg = llvm::StringRef(OutputConstraint).startswith("{@cc");
bool IsFlagReg = llvm::StringRef(OutputConstraint).starts_with("{@cc");
ResultRegIsFlagReg.push_back(IsFlagReg);

llvm::Type *Ty = ConvertTypeForMem(QTy);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,7 @@ CodeGenAction::loadModule(MemoryBufferRef MBRef) {

// Strip off a leading diagnostic code if there is one.
StringRef Msg = Err.getMessage();
if (Msg.startswith("error: "))
if (Msg.starts_with("error: "))
Msg = Msg.substr(7);

unsigned DiagID =
Expand Down
16 changes: 8 additions & 8 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,9 @@ createTargetCodeGenInfo(CodeGenModule &CGM) {
StringRef ABIStr = Target.getABI();
unsigned XLen = Target.getPointerWidth(LangAS::Default);
unsigned ABIFLen = 0;
if (ABIStr.endswith("f"))
if (ABIStr.ends_with("f"))
ABIFLen = 32;
else if (ABIStr.endswith("d"))
else if (ABIStr.ends_with("d"))
ABIFLen = 64;
return createRISCVTargetCodeGenInfo(CGM, XLen, ABIFLen);
}
Expand Down Expand Up @@ -308,9 +308,9 @@ createTargetCodeGenInfo(CodeGenModule &CGM) {
case llvm::Triple::loongarch64: {
StringRef ABIStr = Target.getABI();
unsigned ABIFRLen = 0;
if (ABIStr.endswith("f"))
if (ABIStr.ends_with("f"))
ABIFRLen = 32;
else if (ABIStr.endswith("d"))
else if (ABIStr.ends_with("d"))
ABIFRLen = 64;
return createLoongArchTargetCodeGenInfo(
CGM, Target.getPointerWidth(LangAS::Default), ABIFRLen);
Expand Down Expand Up @@ -1715,7 +1715,7 @@ static void AppendTargetMangling(const CodeGenModule &CGM,
llvm::sort(Info.Features, [&Target](StringRef LHS, StringRef RHS) {
// Multiversioning doesn't allow "no-${feature}", so we can
// only have "+" prefixes here.
assert(LHS.startswith("+") && RHS.startswith("+") &&
assert(LHS.starts_with("+") && RHS.starts_with("+") &&
"Features should always have a prefix.");
return Target.multiVersionSortPriority(LHS.substr(1)) >
Target.multiVersionSortPriority(RHS.substr(1));
Expand Down Expand Up @@ -1769,7 +1769,7 @@ static void AppendTargetClonesMangling(const CodeGenModule &CGM,
} else {
Out << '.';
StringRef FeatureStr = Attr->getFeatureStr(VersionIndex);
if (FeatureStr.startswith("arch="))
if (FeatureStr.starts_with("arch="))
Out << "arch_" << FeatureStr.substr(sizeof("arch=") - 1);
else
Out << FeatureStr;
Expand Down Expand Up @@ -3828,7 +3828,7 @@ namespace {
if (!BuiltinID || !BI.isLibFunction(BuiltinID))
return false;
StringRef BuiltinName = BI.getName(BuiltinID);
if (BuiltinName.startswith("__builtin_") &&
if (BuiltinName.starts_with("__builtin_") &&
Name == BuiltinName.slice(strlen("__builtin_"), StringRef::npos)) {
return true;
}
Expand Down Expand Up @@ -4164,7 +4164,7 @@ void CodeGenModule::emitMultiVersionFunctions() {
Feature.push_back(CurFeat.trim());
}
} else {
if (Version.startswith("arch="))
if (Version.starts_with("arch="))
Architecture = Version.drop_front(sizeof("arch=") - 1);
else if (Version != "default")
Feature.push_back(Version);
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/CoverageMappingGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1623,8 +1623,12 @@ static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
OS << "Gap,";
break;
case CounterMappingRegion::BranchRegion:
case CounterMappingRegion::MCDCBranchRegion:
OS << "Branch,";
break;
case CounterMappingRegion::MCDCDecisionRegion:
OS << "Decision,";
break;
}

OS << "File " << R.FileID << ", " << R.LineStart << ":" << R.ColumnStart
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/CodeGen/Targets/SPIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,14 @@ static llvm::Type *getSPIRVImageType(llvm::LLVMContext &Ctx, StringRef BaseType,

// Choose the dimension of the image--this corresponds to the Dim enum in
// SPIR-V (first integer parameter of OpTypeImage).
if (OpenCLName.startswith("image2d"))
if (OpenCLName.starts_with("image2d"))
IntParams[0] = 1; // 1D
else if (OpenCLName.startswith("image3d"))
else if (OpenCLName.starts_with("image3d"))
IntParams[0] = 2; // 2D
else if (OpenCLName == "image1d_buffer")
IntParams[0] = 5; // Buffer
else
assert(OpenCLName.startswith("image1d") && "Unknown image type");
assert(OpenCLName.starts_with("image1d") && "Unknown image type");

// Set the other integer parameters of OpTypeImage if necessary. Note that the
// OpenCL image types don't provide any information for the Sampled or
Expand Down
12 changes: 6 additions & 6 deletions clang/lib/Driver/Distro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static Distro::DistroType DetectOsRelease(llvm::vfs::FileSystem &VFS) {

// Obviously this can be improved a lot.
for (StringRef Line : Lines)
if (Version == Distro::UnknownDistro && Line.startswith("ID="))
if (Version == Distro::UnknownDistro && Line.starts_with("ID="))
Version = llvm::StringSwitch<Distro::DistroType>(Line.substr(3))
.Case("alpine", Distro::AlpineLinux)
.Case("fedora", Distro::Fedora)
Expand All @@ -60,7 +60,7 @@ static Distro::DistroType DetectLsbRelease(llvm::vfs::FileSystem &VFS) {

for (StringRef Line : Lines)
if (Version == Distro::UnknownDistro &&
Line.startswith("DISTRIB_CODENAME="))
Line.starts_with("DISTRIB_CODENAME="))
Version = llvm::StringSwitch<Distro::DistroType>(Line.substr(17))
.Case("hardy", Distro::UbuntuHardy)
.Case("intrepid", Distro::UbuntuIntrepid)
Expand Down Expand Up @@ -119,10 +119,10 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) {

if (File) {
StringRef Data = File.get()->getBuffer();
if (Data.startswith("Fedora release"))
if (Data.starts_with("Fedora release"))
return Distro::Fedora;
if (Data.startswith("Red Hat Enterprise Linux") ||
Data.startswith("CentOS") || Data.startswith("Scientific Linux")) {
if (Data.starts_with("Red Hat Enterprise Linux") ||
Data.starts_with("CentOS") || Data.starts_with("Scientific Linux")) {
if (Data.contains("release 7"))
return Distro::RHEL7;
else if (Data.contains("release 6"))
Expand Down Expand Up @@ -182,7 +182,7 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) {
SmallVector<StringRef, 8> Lines;
Data.split(Lines, "\n");
for (const StringRef &Line : Lines) {
if (!Line.trim().startswith("VERSION"))
if (!Line.trim().starts_with("VERSION"))
continue;
std::pair<StringRef, StringRef> SplitLine = Line.split('=');
// Old versions have split VERSION and PATCHLEVEL
Expand Down
22 changes: 11 additions & 11 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1451,7 +1451,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
case llvm::Triple::aarch64_32:
if (TC.getTriple().getEnvironmentName().startswith("eabi")) {
if (TC.getTriple().getEnvironmentName().starts_with("eabi")) {
Diag(diag::warn_target_unrecognized_env)
<< TargetTriple
<< (TC.getTriple().getArchName().str() + "-none-elf");
Expand Down Expand Up @@ -1540,7 +1540,7 @@ bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
for (fs::directory_iterator File(CrashDiagDir, EC), FileEnd;
File != FileEnd && !EC; File.increment(EC)) {
StringRef FileName = path::filename(File->path());
if (!FileName.startswith(Name))
if (!FileName.starts_with(Name))
continue;
if (fs::status(File->path(), FileStatus))
continue;
Expand All @@ -1551,7 +1551,7 @@ bool Driver::getCrashDiagnosticFile(StringRef ReproCrashFilename,
// The first line should start with "Process:", otherwise this isn't a real
// .crash file.
StringRef Data = CrashFile.get()->getBuffer();
if (!Data.startswith("Process:"))
if (!Data.starts_with("Process:"))
continue;
// Parse parent process pid line, e.g: "Parent Process: clang-4.0 [79141]"
size_t ParentProcPos = Data.find("Parent Process:");
Expand Down Expand Up @@ -1780,7 +1780,7 @@ void Driver::generateCompilationDiagnostics(
ReproCrashFilename = TempFile;
llvm::sys::path::replace_extension(ReproCrashFilename, ".crash");
}
if (StringRef(TempFile).endswith(".cache")) {
if (StringRef(TempFile).ends_with(".cache")) {
// In some cases (modules) we'll dump extra data to help with reproducing
// the crash into a directory next to the output.
VFS = llvm::sys::path::filename(TempFile);
Expand Down Expand Up @@ -2001,7 +2001,7 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const {
// Distinguish "--autocomplete=-someflag" and "--autocomplete=-someflag,"
// because the latter indicates that the user put space before pushing tab
// which should end up in a file completion.
const bool HasSpace = PassedFlags.endswith(",");
const bool HasSpace = PassedFlags.ends_with(",");

// Parse PassedFlags by "," as all the command-line flags are passed to this
// function separated by ","
Expand Down Expand Up @@ -2041,7 +2041,7 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const {

// When flag ends with '=' and there was no value completion, return empty
// string and fall back to the file autocompletion.
if (SuggestedCompletions.empty() && !Cur.endswith("=")) {
if (SuggestedCompletions.empty() && !Cur.ends_with("=")) {
// If the flag is in the form of "--autocomplete=-foo",
// we were requested to print out all option names that start with "-foo".
// For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only".
Expand All @@ -2053,7 +2053,7 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const {
// TODO: Find a good way to add them to OptTable instead and them remove
// this code.
for (StringRef S : DiagnosticIDs::getDiagnosticFlags())
if (S.startswith(Cur))
if (S.starts_with(Cur))
SuggestedCompletions.push_back(std::string(S));
}

Expand Down Expand Up @@ -2535,7 +2535,7 @@ bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value,
// so we can't downgrade diagnostics for `/GR-` from an error to a warning
// in cc mode. (We can in cl mode because cl.exe itself only warns on
// unknown flags.)
if (IsCLMode() && Ty == types::TY_Object && !Value.startswith("/"))
if (IsCLMode() && Ty == types::TY_Object && !Value.starts_with("/"))
return true;

Diag(clang::diag::err_drv_no_such_file) << Value;
Expand Down Expand Up @@ -6565,7 +6565,7 @@ llvm::StringRef clang::driver::getDriverMode(StringRef ProgName,
getDriverOptTable().getOption(options::OPT_driver_mode).getPrefixedName();
llvm::StringRef Opt;
for (StringRef Arg : Args) {
if (!Arg.startswith(OptName))
if (!Arg.starts_with(OptName))
continue;
Opt = Arg;
}
Expand Down Expand Up @@ -6606,7 +6606,7 @@ llvm::Error driver::expandResponseFiles(SmallVectorImpl<const char *> &Args,
else
Tokenizer = &llvm::cl::TokenizeGNUCommandLine;

if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).startswith("-cc1"))
if (MarkEOLs && Args.size() > 1 && StringRef(Args[1]).starts_with("-cc1"))
MarkEOLs = false;

llvm::cl::ExpansionContext ECtx(Alloc, Tokenizer);
Expand All @@ -6620,7 +6620,7 @@ llvm::Error driver::expandResponseFiles(SmallVectorImpl<const char *> &Args,
// If -cc1 came from a response file, remove the EOL sentinels.
auto FirstArg = llvm::find_if(llvm::drop_begin(Args),
[](const char *A) { return A != nullptr; });
if (FirstArg != Args.end() && StringRef(*FirstArg).startswith("-cc1")) {
if (FirstArg != Args.end() && StringRef(*FirstArg).starts_with("-cc1")) {
// If -cc1 came from a response file, remove the EOL sentinels.
if (MarkEOLs) {
auto newEnd = std::remove(Args.begin(), Args.end(), nullptr);
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Driver/Job.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum,

// These flags are treated as a single argument (e.g., -F<Dir>).
StringRef FlagRef(Flag);
IsInclude = FlagRef.startswith("-F") || FlagRef.startswith("-I");
IsInclude = FlagRef.starts_with("-F") || FlagRef.starts_with("-I");
if (IsInclude)
return !HaveCrashVFS;
if (FlagRef.startswith("-fmodules-cache-path="))
if (FlagRef.starts_with("-fmodules-cache-path="))
return true;

SkipNum = 0;
Expand Down Expand Up @@ -185,8 +185,8 @@ rewriteIncludes(const llvm::ArrayRef<const char *> &Args, size_t Idx,
SmallString<128> NewInc;
if (NumArgs == 1) {
StringRef FlagRef(Args[Idx + NumArgs - 1]);
assert((FlagRef.startswith("-F") || FlagRef.startswith("-I")) &&
"Expecting -I or -F");
assert((FlagRef.starts_with("-F") || FlagRef.starts_with("-I")) &&
"Expecting -I or -F");
StringRef Inc = FlagRef.slice(2, StringRef::npos);
if (getAbsPath(Inc, NewInc)) {
SmallString<128> NewArg(FlagRef.slice(0, 2));
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {

for (const auto &DS : DriverSuffixes) {
StringRef Suffix(DS.Suffix);
if (ProgName.endswith(Suffix)) {
if (ProgName.ends_with(Suffix)) {
Pos = ProgName.size() - Suffix.size();
return &DS;
}
Expand Down Expand Up @@ -345,7 +345,7 @@ static const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) {
// added via -target as implicit first argument.
const DriverSuffix *DS = FindDriverSuffix(ProgName, Pos);

if (!DS && ProgName.endswith(".exe")) {
if (!DS && ProgName.ends_with(".exe")) {
// Try again after stripping the executable suffix:
// clang++.exe -> clang++
ProgName = ProgName.drop_back(StringRef(".exe").size());
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Driver/ToolChains/AIX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,16 @@ static bool hasExportListLinkerOpts(const ArgStringList &CmdArgs) {
for (size_t i = 0, Size = CmdArgs.size(); i < Size; ++i) {
llvm::StringRef ArgString(CmdArgs[i]);

if (ArgString.startswith("-bE:") || ArgString.startswith("-bexport:") ||
if (ArgString.starts_with("-bE:") || ArgString.starts_with("-bexport:") ||
ArgString == "-bexpall" || ArgString == "-bexpfull")
return true;

// If we split -b option, check the next opt.
if (ArgString == "-b" && i + 1 < Size) {
++i;
llvm::StringRef ArgNextString(CmdArgs[i]);
if (ArgNextString.startswith("E:") ||
ArgNextString.startswith("export:") || ArgNextString == "expall" ||
if (ArgNextString.starts_with("E:") ||
ArgNextString.starts_with("export:") || ArgNextString == "expall" ||
ArgNextString == "expfull")
return true;
}
Expand Down
18 changes: 9 additions & 9 deletions clang/lib/Driver/ToolChains/AMDGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ RocmInstallationDetector::findSPACKPackage(const Candidate &Cand,
FileEnd;
File != FileEnd && !EC; File.increment(EC)) {
llvm::StringRef FileName = llvm::sys::path::filename(File->path());
if (FileName.startswith(Prefix)) {
if (FileName.starts_with(Prefix)) {
SubDirs.push_back(FileName);
if (SubDirs.size() > 1)
break;
Expand Down Expand Up @@ -84,13 +84,13 @@ void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) {
!EC && LI != LE; LI = LI.increment(EC)) {
StringRef FilePath = LI->path();
StringRef FileName = llvm::sys::path::filename(FilePath);
if (!FileName.endswith(Suffix))
if (!FileName.ends_with(Suffix))
continue;

StringRef BaseName;
if (FileName.endswith(Suffix2))
if (FileName.ends_with(Suffix2))
BaseName = FileName.drop_back(Suffix2.size());
else if (FileName.endswith(Suffix))
else if (FileName.ends_with(Suffix))
BaseName = FileName.drop_back(Suffix.size());

const StringRef ABIVersionPrefix = "oclc_abi_version_";
Expand Down Expand Up @@ -124,7 +124,7 @@ void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) {
WavefrontSize64.On = FilePath;
} else if (BaseName == "oclc_wavefrontsize64_off") {
WavefrontSize64.Off = FilePath;
} else if (BaseName.startswith(ABIVersionPrefix)) {
} else if (BaseName.starts_with(ABIVersionPrefix)) {
unsigned ABIVersionNumber;
if (BaseName.drop_front(ABIVersionPrefix.size())
.getAsInteger(/*Redex=*/0, ABIVersionNumber))
Expand All @@ -134,7 +134,7 @@ void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) {
// Process all bitcode filenames that look like
// ocl_isa_version_XXX.amdgcn.bc
const StringRef DeviceLibPrefix = "oclc_isa_version_";
if (!BaseName.startswith(DeviceLibPrefix))
if (!BaseName.starts_with(DeviceLibPrefix))
continue;

StringRef IsaVersionNumber =
Expand Down Expand Up @@ -230,7 +230,7 @@ RocmInstallationDetector::getInstallationPathCandidates() {
// <rocm_root>/llvm-amdgpu-<rocm_release_string>-<hash>/bin directory.
// We only consider the parent directory of llvm-amdgpu package as ROCm
// installation candidate for SPACK.
if (ParentName.startswith("llvm-amdgpu-")) {
if (ParentName.starts_with("llvm-amdgpu-")) {
auto SPACKPostfix =
ParentName.drop_front(strlen("llvm-amdgpu-")).split('-');
auto SPACKReleaseStr = SPACKPostfix.first;
Expand All @@ -243,7 +243,7 @@ RocmInstallationDetector::getInstallationPathCandidates() {

// Some versions of the rocm llvm package install to /opt/rocm/llvm/bin
// Some versions of the aomp package install to /opt/rocm/aomp/bin
if (ParentName == "llvm" || ParentName.startswith("aomp"))
if (ParentName == "llvm" || ParentName.starts_with("aomp"))
ParentDir = llvm::sys::path::parent_path(ParentDir);

return Candidate(ParentDir.str(), /*StrictChecking=*/true);
Expand Down Expand Up @@ -292,7 +292,7 @@ RocmInstallationDetector::getInstallationPathCandidates() {
FileEnd;
File != FileEnd && !EC; File.increment(EC)) {
llvm::StringRef FileName = llvm::sys::path::filename(File->path());
if (!FileName.startswith("rocm-"))
if (!FileName.starts_with("rocm-"))
continue;
if (LatestROCm.empty()) {
LatestROCm = FileName.str();
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Driver/ToolChains/Arch/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
if (MtuneLowerCase == "native")
MtuneLowerCase = std::string(llvm::sys::getHostCPUName());
if (MtuneLowerCase == "cyclone" ||
StringRef(MtuneLowerCase).startswith("apple")) {
StringRef(MtuneLowerCase).starts_with("apple")) {
Features.push_back("+zcm");
Features.push_back("+zcz");
}
Expand Down Expand Up @@ -262,7 +262,7 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
for (const auto *A :
Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler))
for (StringRef Value : A->getValues())
if (Value.startswith("-march="))
if (Value.starts_with("-march="))
WaMArch = Value.substr(7);
// Call getAArch64ArchFeaturesFromMarch only if "-Wa,-march=" or
// "-Xassembler -march" is detected. Otherwise it may return false
Expand Down
18 changes: 9 additions & 9 deletions clang/lib/Driver/ToolChains/Arch/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ void arm::getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch,
// Use getValues because -Wa can have multiple arguments
// e.g. -Wa,-mcpu=foo,-mcpu=bar
for (StringRef Value : A->getValues()) {
if (Value.startswith("-mcpu="))
if (Value.starts_with("-mcpu="))
CPU = Value.substr(6);
if (Value.startswith("-march="))
if (Value.starts_with("-march="))
Arch = Value.substr(7);
}
}
Expand Down Expand Up @@ -285,9 +285,9 @@ void arm::setArchNameInTriple(const Driver &D, const ArgList &Args,
// There is no assembler equivalent of -mno-thumb, -marm, or -mno-arm.
if (Value == "-mthumb")
IsThumb = true;
else if (Value.startswith("-march="))
else if (Value.starts_with("-march="))
WaMArch = Value.substr(7);
else if (Value.startswith("-mcpu="))
else if (Value.starts_with("-mcpu="))
WaMCPU = Value.substr(6);
}
}
Expand Down Expand Up @@ -528,13 +528,13 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D,
// We use getValues here because you can have many options per -Wa
// We will keep the last one we find for each of these
for (StringRef Value : A->getValues()) {
if (Value.startswith("-mfpu=")) {
if (Value.starts_with("-mfpu=")) {
WaFPU = std::make_pair(A, Value.substr(6));
} else if (Value.startswith("-mcpu=")) {
} else if (Value.starts_with("-mcpu=")) {
WaCPU = std::make_pair(A, Value.substr(6));
} else if (Value.startswith("-mhwdiv=")) {
} else if (Value.starts_with("-mhwdiv=")) {
WaHDiv = std::make_pair(A, Value.substr(8));
} else if (Value.startswith("-march=")) {
} else if (Value.starts_with("-march=")) {
WaArch = std::make_pair(A, Value.substr(7));
}
}
Expand Down Expand Up @@ -796,7 +796,7 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D,
// Propagate frame-chain model selection
if (Arg *A = Args.getLastArg(options::OPT_mframe_chain)) {
StringRef FrameChainOption = A->getValue();
if (FrameChainOption.startswith("aapcs"))
if (FrameChainOption.starts_with("aapcs"))
Features.push_back("+aapcs-frame-chain");
if (FrameChainOption == "aapcs+leaf")
Features.push_back("+aapcs-frame-chain-leaf");
Expand Down
10 changes: 5 additions & 5 deletions clang/lib/Driver/ToolChains/Arch/X86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,15 +234,15 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
A->claim();

// Skip over "-m".
assert(Name.startswith("m") && "Invalid feature name.");
assert(Name.starts_with("m") && "Invalid feature name.");
Name = Name.substr(1);

bool IsNegative = Name.startswith("no-");
bool IsNegative = Name.starts_with("no-");
if (IsNegative)
Name = Name.substr(3);

#ifndef NDEBUG
assert(Name.startswith("avx10.") && "Invalid AVX10 feature name.");
assert(Name.starts_with("avx10.") && "Invalid AVX10 feature name.");
StringRef Version, Width;
std::tie(Version, Width) = Name.substr(6).split('-');
assert(Version == "1" && "Invalid AVX10 feature name.");
Expand All @@ -260,7 +260,7 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
A->claim();

// Skip over "-m".
assert(Name.startswith("m") && "Invalid feature name.");
assert(Name.starts_with("m") && "Invalid feature name.");
Name = Name.substr(1);

// Replace -mgeneral-regs-only with -x87, -mmx, -sse
Expand All @@ -269,7 +269,7 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
continue;
}

bool IsNegative = Name.startswith("no-");
bool IsNegative = Name.starts_with("no-");
if (A->getOption().matches(options::OPT_mapx_features_EQ) ||
A->getOption().matches(options::OPT_mno_apx_features_EQ)) {

Expand Down
102 changes: 47 additions & 55 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ static void ParseMRecip(const Driver &D, const ArgList &Args,
for (unsigned i = 0; i != NumOptions; ++i) {
StringRef Val = A->getValue(i);

bool IsDisabled = Val.startswith(DisabledPrefixIn);
bool IsDisabled = Val.starts_with(DisabledPrefixIn);
// Ignore the disablement token for string matching.
if (IsDisabled)
Val = Val.substr(1);
Expand Down Expand Up @@ -433,7 +433,7 @@ static void addDebugObjectName(const ArgList &Args, ArgStringList &CmdArgs,
const char *OutputFileName) {
// No need to generate a value for -object-file-name if it was provided.
for (auto *Arg : Args.filtered(options::OPT_Xclang))
if (StringRef(Arg->getValue()).startswith("-object-file-name"))
if (StringRef(Arg->getValue()).starts_with("-object-file-name"))
return;

if (Args.hasArg(options::OPT_object_file_name_EQ))
Expand Down Expand Up @@ -940,7 +940,7 @@ static void handleAMDGPUCodeObjectVersionOptions(const Driver &D,
static bool hasClangPchSignature(const Driver &D, StringRef Path) {
if (llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MemBuf =
D.getVFS().getBufferForFile(Path))
return (*MemBuf)->getBuffer().startswith("CPCH");
return (*MemBuf)->getBuffer().starts_with("CPCH");
return false;
}

Expand Down Expand Up @@ -1715,7 +1715,7 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
Val.equals("256+") || Val.equals("512+") || Val.equals("1024+") ||
Val.equals("2048+")) {
unsigned Bits = 0;
if (Val.endswith("+"))
if (Val.ends_with("+"))
Val = Val.substr(0, Val.size() - 1);
else {
bool Invalid = Val.getAsInteger(10, Bits); (void)Invalid;
Expand Down Expand Up @@ -2503,7 +2503,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
case llvm::Triple::thumbeb:
case llvm::Triple::arm:
case llvm::Triple::armeb:
if (Value.startswith("-mimplicit-it=")) {
if (Value.starts_with("-mimplicit-it=")) {
// Only store the value; the last value set takes effect.
ImplicitIt = Value.split("=").second;
if (CheckARMImplicitITArg(ImplicitIt))
Expand All @@ -2528,12 +2528,12 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
CmdArgs.push_back("-use-tcc-in-div");
continue;
}
if (Value.startswith("-msoft-float")) {
if (Value.starts_with("-msoft-float")) {
CmdArgs.push_back("-target-feature");
CmdArgs.push_back("+soft-float");
continue;
}
if (Value.startswith("-mhard-float")) {
if (Value.starts_with("-mhard-float")) {
CmdArgs.push_back("-target-feature");
CmdArgs.push_back("-soft-float");
continue;
Expand Down Expand Up @@ -2570,8 +2570,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
CmdArgs.push_back("-massembler-no-warn");
} else if (Value == "--noexecstack") {
UseNoExecStack = true;
} else if (Value.startswith("-compress-debug-sections") ||
Value.startswith("--compress-debug-sections") ||
} else if (Value.starts_with("-compress-debug-sections") ||
Value.starts_with("--compress-debug-sections") ||
Value == "-nocompress-debug-sections" ||
Value == "--nocompress-debug-sections") {
CmdArgs.push_back(Value.data());
Expand All @@ -2581,13 +2581,13 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
} else if (Value == "-mrelax-relocations=no" ||
Value == "--mrelax-relocations=no") {
UseRelaxRelocations = false;
} else if (Value.startswith("-I")) {
} else if (Value.starts_with("-I")) {
CmdArgs.push_back(Value.data());
// We need to consume the next argument if the current arg is a plain
// -I. The next arg will be the include directory.
if (Value == "-I")
TakeNextArg = true;
} else if (Value.startswith("-gdwarf-")) {
} else if (Value.starts_with("-gdwarf-")) {
// "-gdwarf-N" options are not cc1as options.
unsigned DwarfVersion = DwarfVersionNum(Value);
if (DwarfVersion == 0) { // Send it onward, and let cc1as complain.
Expand All @@ -2597,30 +2597,30 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
llvm::codegenoptions::DebugInfoConstructor,
DwarfVersion, llvm::DebuggerKind::Default);
}
} else if (Value.startswith("-mcpu") || Value.startswith("-mfpu") ||
Value.startswith("-mhwdiv") || Value.startswith("-march")) {
} else if (Value.starts_with("-mcpu") || Value.starts_with("-mfpu") ||
Value.starts_with("-mhwdiv") || Value.starts_with("-march")) {
// Do nothing, we'll validate it later.
} else if (Value == "-defsym") {
if (A->getNumValues() != 2) {
D.Diag(diag::err_drv_defsym_invalid_format) << Value;
break;
}
const char *S = A->getValue(1);
auto Pair = StringRef(S).split('=');
auto Sym = Pair.first;
auto SVal = Pair.second;

if (Sym.empty() || SVal.empty()) {
D.Diag(diag::err_drv_defsym_invalid_format) << S;
break;
}
int64_t IVal;
if (SVal.getAsInteger(0, IVal)) {
D.Diag(diag::err_drv_defsym_invalid_symval) << SVal;
break;
}
CmdArgs.push_back(Value.data());
TakeNextArg = true;
if (A->getNumValues() != 2) {
D.Diag(diag::err_drv_defsym_invalid_format) << Value;
break;
}
const char *S = A->getValue(1);
auto Pair = StringRef(S).split('=');
auto Sym = Pair.first;
auto SVal = Pair.second;

if (Sym.empty() || SVal.empty()) {
D.Diag(diag::err_drv_defsym_invalid_format) << S;
break;
}
int64_t IVal;
if (SVal.getAsInteger(0, IVal)) {
D.Diag(diag::err_drv_defsym_invalid_symval) << SVal;
break;
}
CmdArgs.push_back(Value.data());
TakeNextArg = true;
} else if (Value == "-fdebug-compilation-dir") {
CmdArgs.push_back("-fdebug-compilation-dir");
TakeNextArg = true;
Expand Down Expand Up @@ -3331,7 +3331,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
// --param ssp-buffer-size=
for (const Arg *A : Args.filtered(options::OPT__param)) {
StringRef Str(A->getValue());
if (Str.startswith("ssp-buffer-size=")) {
if (Str.starts_with("ssp-buffer-size=")) {
if (StackProtectorLevel) {
CmdArgs.push_back("-stack-protector-buffer-size");
// FIXME: Verify the argument is a valid integer.
Expand Down Expand Up @@ -5615,6 +5615,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_auto_import);
}

if (Args.hasFlag(options::OPT_fms_volatile, options::OPT_fno_ms_volatile,
Triple.isX86() && D.IsCLMode()))
CmdArgs.push_back("-fms-volatile");

// Non-PIC code defaults to -fdirect-access-external-data while PIC code
// defaults to -fno-direct-access-external-data. Pass the option if different
// from the default.
Expand Down Expand Up @@ -5882,7 +5886,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
StringRef Val = A->getValue();
if (Triple.isX86() && Triple.isOSBinFormatELF()) {
if (Val != "all" && Val != "labels" && Val != "none" &&
!Val.startswith("list="))
!Val.starts_with("list="))
D.Diag(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
else
Expand Down Expand Up @@ -7947,18 +7951,6 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
CmdArgs.push_back("-P");
}

unsigned VolatileOptionID;
if (getToolChain().getTriple().isX86())
VolatileOptionID = options::OPT__SLASH_volatile_ms;
else
VolatileOptionID = options::OPT__SLASH_volatile_iso;

if (Arg *A = Args.getLastArg(options::OPT__SLASH_volatile_Group))
VolatileOptionID = A->getOption().getID();

if (VolatileOptionID == options::OPT__SLASH_volatile_ms)
CmdArgs.push_back("-fms-volatile");

if (Args.hasFlag(options::OPT__SLASH_Zc_dllexportInlines_,
options::OPT__SLASH_Zc_dllexportInlines,
false)) {
Expand Down Expand Up @@ -8390,14 +8382,14 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
continue;
auto &JArgs = J.getArguments();
for (unsigned I = 0; I < JArgs.size(); ++I) {
if (StringRef(JArgs[I]).startswith("-object-file-name=") &&
if (StringRef(JArgs[I]).starts_with("-object-file-name=") &&
Output.isFilename()) {
ArgStringList NewArgs(JArgs.begin(), JArgs.begin() + I);
addDebugObjectName(Args, NewArgs, DebugCompilationDir,
Output.getFilename());
NewArgs.append(JArgs.begin() + I + 1, JArgs.end());
J.replaceArguments(NewArgs);
break;
ArgStringList NewArgs(JArgs.begin(), JArgs.begin() + I);
addDebugObjectName(Args, NewArgs, DebugCompilationDir,
Output.getFilename());
NewArgs.append(JArgs.begin() + I + 1, JArgs.end());
J.replaceArguments(NewArgs);
break;
}
}
}
Expand Down Expand Up @@ -8661,7 +8653,7 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA,
getTargetFeatures(TC->getDriver(), TC->getTriple(), TCArgs, Features,
false);
llvm::copy_if(Features, std::back_inserter(FeatureArgs),
[](StringRef Arg) { return !Arg.startswith("-target"); });
[](StringRef Arg) { return !Arg.starts_with("-target"); });

if (TC->getTriple().isAMDGPU()) {
for (StringRef Feature : llvm::split(Arch.split(':').second, ':')) {
Expand Down
16 changes: 8 additions & 8 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ void tools::handleTargetFeaturesGroup(const Driver &D,
A->claim();

// Skip over "-m".
assert(Name.startswith("m") && "Invalid feature name.");
assert(Name.starts_with("m") && "Invalid feature name.");
Name = Name.substr(1);

auto Proc = getCPUName(D, Args, Triple);
Expand All @@ -317,7 +317,7 @@ void tools::handleTargetFeaturesGroup(const Driver &D,
continue;
}

bool IsNegative = Name.startswith("no-");
bool IsNegative = Name.starts_with("no-");
if (IsNegative)
Name = Name.substr(3);

Expand Down Expand Up @@ -2336,20 +2336,20 @@ static void GetSDLFromOffloadArchive(
llvm::Triple Triple(D.getTargetTriple());
bool IsMSVC = Triple.isWindowsMSVCEnvironment();
auto Ext = IsMSVC ? ".lib" : ".a";
if (!Lib.startswith(":") && !Lib.startswith("-l")) {
if (!Lib.starts_with(":") && !Lib.starts_with("-l")) {
if (llvm::sys::fs::exists(Lib)) {
ArchiveOfBundles = Lib;
FoundAOB = true;
}
} else {
if (Lib.startswith("-l"))
if (Lib.starts_with("-l"))
Lib = Lib.drop_front(2);
for (auto LPath : LibraryPaths) {
ArchiveOfBundles.clear();
auto LibFile =
(Lib.startswith(":") ? Lib.drop_front()
: IsMSVC ? Lib + Ext : "lib" + Lib + Ext)
.str();
auto LibFile = (Lib.starts_with(":") ? Lib.drop_front()
: IsMSVC ? Lib + Ext
: "lib" + Lib + Ext)
.str();
for (auto Prefix : {"/libdevice/", "/"}) {
auto AOB = Twine(LPath + Prefix + LibFile).str();
if (llvm::sys::fs::exists(AOB)) {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Cuda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ CudaInstallationDetector::CudaInstallationDetector(
// Process all bitcode filenames that look like
// libdevice.compute_XX.YY.bc
const StringRef LibDeviceName = "libdevice.";
if (!(FileName.startswith(LibDeviceName) && FileName.endswith(".bc")))
if (!(FileName.starts_with(LibDeviceName) && FileName.ends_with(".bc")))
continue;
StringRef GpuArch = FileName.slice(
LibDeviceName.size(), FileName.find('.', LibDeviceName.size()));
Expand Down
31 changes: 16 additions & 15 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1010,13 +1010,13 @@ static const char *ArmMachOArchNameCPU(StringRef CPU) {

// FIXME: Make sure this MachO triple mangling is really necessary.
// ARMv5* normalises to ARMv5.
if (Arch.startswith("armv5"))
if (Arch.starts_with("armv5"))
Arch = Arch.substr(0, 5);
// ARMv6*, except ARMv6M, normalises to ARMv6.
else if (Arch.startswith("armv6") && !Arch.endswith("6m"))
else if (Arch.starts_with("armv6") && !Arch.ends_with("6m"))
Arch = Arch.substr(0, 5);
// ARMv7A normalises to ARMv7.
else if (Arch.endswith("v7a"))
else if (Arch.ends_with("v7a"))
Arch = Arch.substr(0, 5);
return Arch.data();
}
Expand Down Expand Up @@ -1319,8 +1319,8 @@ StringRef Darwin::getSDKName(StringRef isysroot) {
auto EndSDK = llvm::sys::path::rend(isysroot);
for (auto IT = BeginSDK; IT != EndSDK; ++IT) {
StringRef SDK = *IT;
if (SDK.endswith(".sdk"))
return SDK.slice(0, SDK.size() - 4);
if (SDK.ends_with(".sdk"))
return SDK.slice(0, SDK.size() - 4);
}
return "";
}
Expand Down Expand Up @@ -1959,22 +1959,23 @@ inferDeploymentTargetFromSDK(DerivedArgList &Args,

auto CreatePlatformFromSDKName =
[&](StringRef SDK) -> std::optional<DarwinPlatform> {
if (SDK.startswith("iPhoneOS") || SDK.startswith("iPhoneSimulator"))
if (SDK.starts_with("iPhoneOS") || SDK.starts_with("iPhoneSimulator"))
return DarwinPlatform::createFromSDK(
Darwin::IPhoneOS, Version,
/*IsSimulator=*/SDK.startswith("iPhoneSimulator"));
else if (SDK.startswith("MacOSX"))
/*IsSimulator=*/SDK.starts_with("iPhoneSimulator"));
else if (SDK.starts_with("MacOSX"))
return DarwinPlatform::createFromSDK(Darwin::MacOS,
getSystemOrSDKMacOSVersion(Version));
else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator"))
else if (SDK.starts_with("WatchOS") || SDK.starts_with("WatchSimulator"))
return DarwinPlatform::createFromSDK(
Darwin::WatchOS, Version,
/*IsSimulator=*/SDK.startswith("WatchSimulator"));
else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator"))
/*IsSimulator=*/SDK.starts_with("WatchSimulator"));
else if (SDK.starts_with("AppleTVOS") ||
SDK.starts_with("AppleTVSimulator"))
return DarwinPlatform::createFromSDK(
Darwin::TvOS, Version,
/*IsSimulator=*/SDK.startswith("AppleTVSimulator"));
else if (SDK.startswith("DriverKit"))
/*IsSimulator=*/SDK.starts_with("AppleTVSimulator"));
else if (SDK.starts_with("DriverKit"))
return DarwinPlatform::createFromSDK(Darwin::DriverKit, Version);
return std::nullopt;
};
Expand Down Expand Up @@ -2339,8 +2340,8 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
if (SDK.size() > 0) {
size_t StartVer = SDK.find_first_of("0123456789");
StringRef SDKName = SDK.slice(0, StartVer);
if (!SDKName.startswith(getPlatformFamily()) &&
!dropSDKNamePrefix(SDKName).startswith(getPlatformFamily()))
if (!SDKName.starts_with(getPlatformFamily()) &&
!dropSDKNamePrefix(SDKName).starts_with(getPlatformFamily()))
getDriver().Diag(diag::warn_incompatible_sysroot)
<< SDKName << getPlatformFamily();
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Flang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void Flang::AddAArch64TargetArgs(const ArgList &Args,
Val.equals("256+") || Val.equals("512+") || Val.equals("1024+") ||
Val.equals("2048+")) {
unsigned Bits = 0;
if (Val.endswith("+"))
if (Val.ends_with("+"))
Val = Val.substr(0, Val.size() - 1);
else {
[[maybe_unused]] bool Invalid = Val.getAsInteger(10, Bits);
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Driver/ToolChains/Gnu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,7 @@ static bool findMipsCsMultilibs(const Multilib::flags_list &Flags,
.FilterOut(NonExistent)
.setIncludeDirsCallback([](const Multilib &M) {
std::vector<std::string> Dirs({"/include"});
if (StringRef(M.includeSuffix()).startswith("/uclibc"))
if (StringRef(M.includeSuffix()).starts_with("/uclibc"))
Dirs.push_back(
"/../../../../mips-linux-gnu/libc/uclibc/usr/include");
else
Expand Down Expand Up @@ -1288,7 +1288,7 @@ static bool findMipsMtiMultilibs(const Multilib::flags_list &Flags,
.FilterOut(NonExistent)
.setIncludeDirsCallback([](const Multilib &M) {
std::vector<std::string> Dirs({"/include"});
if (StringRef(M.includeSuffix()).startswith("/uclibc"))
if (StringRef(M.includeSuffix()).starts_with("/uclibc"))
Dirs.push_back("/../../../../sysroot/uclibc/usr/include");
else
Dirs.push_back("/../../../../sysroot/usr/include");
Expand Down Expand Up @@ -3055,7 +3055,7 @@ void Generic_GCC::AddMultilibPaths(const Driver &D,
// the cross. Note that GCC does include some of these directories in some
// configurations but this seems somewhere between questionable and simply
// a bug.
if (StringRef(LibPath).startswith(SysRoot))
if (StringRef(LibPath).starts_with(SysRoot))
addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);
}
}
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Driver/ToolChains/Hexagon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ static void handleHVXTargetFeatures(const Driver &D, const ArgList &Args,
auto makeFeature = [&Args](Twine T, bool Enable) -> StringRef {
const std::string &S = T.str();
StringRef Opt(S);
if (Opt.endswith("="))
if (Opt.ends_with("="))
Opt = Opt.drop_back(1);
if (Opt.startswith("mno-"))
if (Opt.starts_with("mno-"))
Opt = Opt.drop_front(4);
else if (Opt.startswith("m"))
else if (Opt.starts_with("m"))
Opt = Opt.drop_front(1);
return Args.MakeArgString(Twine(Enable ? "+" : "-") + Twine(Opt));
};
Expand Down Expand Up @@ -801,7 +801,7 @@ StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
CpuArg = A;

StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU();
if (CPU.startswith("hexagon"))
if (CPU.starts_with("hexagon"))
return CPU.substr(sizeof("hexagon") - 1);
return CPU;
}
4 changes: 2 additions & 2 deletions clang/lib/Driver/ToolChains/Hurd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
// those searched.
// FIXME: It's not clear whether we should use the driver's installed
// directory ('Dir' below) or the ResourceDir.
if (StringRef(D.Dir).startswith(SysRoot)) {
if (StringRef(D.Dir).starts_with(SysRoot)) {
addPathIfExists(D, D.Dir + "/../lib/" + MultiarchTriple, Paths);
addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
}
Expand All @@ -110,7 +110,7 @@ Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
// searched.
// FIXME: It's not clear whether we should use the driver's installed
// directory ('Dir' below) or the ResourceDir.
if (StringRef(D.Dir).startswith(SysRoot))
if (StringRef(D.Dir).starts_with(SysRoot))
addPathIfExists(D, D.Dir + "/../lib", Paths);

addPathIfExists(D, SysRoot + "/lib", Paths);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/MSP430.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ void MSP430ToolChain::addClangTargetOptions(const ArgList &DriverArgs,
return;

const StringRef MCU = MCUArg->getValue();
if (MCU.startswith("msp430i")) {
if (MCU.starts_with("msp430i")) {
// 'i' should be in lower case as it's defined in TI MSP430-GCC headers
CC1Args.push_back(DriverArgs.MakeArgString(
"-D__MSP430i" + MCU.drop_front(7).upper() + "__"));
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/MSVC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (A.getOption().matches(options::OPT_l)) {
StringRef Lib = A.getValue();
const char *LinkLibArg;
if (Lib.endswith(".lib"))
if (Lib.ends_with(".lib"))
LinkLibArg = Args.MakeArgString(Lib);
else
LinkLibArg = Args.MakeArgString(Lib + ".lib");
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Driver/ToolChains/MinGW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ void tools::MinGW::Linker::AddLibGCC(const ArgList &Args,
CmdArgs.push_back("-lmoldname");
CmdArgs.push_back("-lmingwex");
for (auto Lib : Args.getAllArgValues(options::OPT_l))
if (StringRef(Lib).startswith("msvcr") ||
StringRef(Lib).startswith("ucrt") ||
StringRef(Lib).startswith("crtdll"))
if (StringRef(Lib).starts_with("msvcr") ||
StringRef(Lib).starts_with("ucrt") ||
StringRef(Lib).starts_with("crtdll"))
return;
CmdArgs.push_back("-lmsvcrt");
}
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Driver/ToolChains/PPCLinux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ static bool GlibcSupportsFloat128(const std::string &Linker) {

// Since glibc 2.34, the installed .so file is not symlink anymore. But we can
// still safely assume it's newer than 2.32.
if (LinkerName.startswith("ld64.so"))
if (LinkerName.starts_with("ld64.so"))
return true;

if (!LinkerName.startswith("ld-2."))
if (!LinkerName.starts_with("ld-2."))
return false;
unsigned Minor = (LinkerName[5] - '0') * 10 + (LinkerName[6] - '0');
if (Minor < 32)
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Solaris.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ Solaris::Solaris(const Driver &D, const llvm::Triple &Triple,

// If we are currently running Clang inside of the requested system root,
// add its parent library path to those searched.
if (StringRef(D.Dir).startswith(D.SysRoot))
if (StringRef(D.Dir).starts_with(D.SysRoot))
addPathIfExists(D, D.Dir + "/../lib", Paths);

addPathIfExists(D, D.SysRoot + "/usr/lib" + LibSuffix, Paths);
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Driver/ToolChains/WebAssembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,

for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
StringRef Opt = A->getValue(0);
if (Opt.startswith("-emscripten-cxx-exceptions-allowed")) {
if (Opt.starts_with("-emscripten-cxx-exceptions-allowed")) {
// '-mllvm -emscripten-cxx-exceptions-allowed' should be used with
// '-mllvm -enable-emscripten-cxx-exceptions'
bool EmEHArgExists = false;
Expand All @@ -355,7 +355,7 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
}
}

if (Opt.startswith("-wasm-enable-sjlj")) {
if (Opt.starts_with("-wasm-enable-sjlj")) {
// '-mllvm -wasm-enable-sjlj' is not compatible with
// '-mno-exception-handling'
if (DriverArgs.hasFlag(options::OPT_mno_exception_handing,
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Edit/Commit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ bool Commit::canReplaceText(SourceLocation loc, StringRef text,
return false;

Len = text.size();
return file.substr(Offs.getOffset()).startswith(text);
return file.substr(Offs.getOffset()).starts_with(text);
}

bool Commit::isAtStartOfMacroExpansion(SourceLocation loc,
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Edit/RewriteObjCFoundationAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ static bool getLiteralInfo(SourceRange literalRange,

struct Suff {
static bool has(StringRef suff, StringRef &text) {
if (text.endswith(suff)) {
if (text.ends_with(suff)) {
text = text.substr(0, text.size()-suff.size());
return true;
}
Expand Down Expand Up @@ -739,9 +739,9 @@ static bool getLiteralInfo(SourceRange literalRange,
Info.F = UpperF ? "F" : "f";

Info.Hex = Info.Octal = false;
if (text.startswith("0x"))
if (text.starts_with("0x"))
Info.Hex = true;
else if (!isFloat && !isIntZero && text.startswith("0"))
else if (!isFloat && !isIntZero && text.starts_with("0"))
Info.Octal = true;

SourceLocation B = literalRange.getBegin();
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ std::optional<std::string> getRelativeIncludeName(const CompilerInstance &CI,
// Special case Apple .sdk folders since the search path is typically a
// symlink like `iPhoneSimulator14.5.sdk` while the file is instead
// located in `iPhoneSimulator.sdk` (the real folder).
if (NI->endswith(".sdk") && DI->endswith(".sdk")) {
if (NI->ends_with(".sdk") && DI->ends_with(".sdk")) {
StringRef NBasename = path::stem(*NI);
StringRef DBasename = path::stem(*DI);
if (DBasename.startswith(NBasename))
if (DBasename.starts_with(NBasename))
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ bool SymbolGraphSerializer::shouldSkip(const APIRecord &Record) const {

// Filter out symbols prefixed with an underscored as they are understood to
// be symbols clients should not use.
if (Record.Name.startswith("_"))
if (Record.Name.starts_with("_"))
return true;

return false;
Expand Down
44 changes: 22 additions & 22 deletions clang/lib/Format/BreakableToken.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static StringRef getLineCommentIndentPrefix(StringRef Comment,
}));

for (StringRef KnownPrefix : KnownPrefixes) {
if (Comment.startswith(KnownPrefix)) {
if (Comment.starts_with(KnownPrefix)) {
const auto PrefixLength =
Comment.find_first_not_of(' ', KnownPrefix.size());
return Comment.substr(0, PrefixLength);
Expand Down Expand Up @@ -220,8 +220,8 @@ bool switchesFormatting(const FormatToken &Token) {
assert((Token.is(TT_BlockComment) || Token.is(TT_LineComment)) &&
"formatting regions are switched by comment tokens");
StringRef Content = Token.TokenText.substr(2).ltrim();
return Content.startswith("clang-format on") ||
Content.startswith("clang-format off");
return Content.starts_with("clang-format on") ||
Content.starts_with("clang-format off");
}

unsigned
Expand Down Expand Up @@ -271,7 +271,7 @@ BreakableStringLiteral::BreakableStringLiteral(
: BreakableToken(Tok, InPPDirective, Encoding, Style),
StartColumn(StartColumn), Prefix(Prefix), Postfix(Postfix),
UnbreakableTailLength(UnbreakableTailLength) {
assert(Tok.TokenText.startswith(Prefix) && Tok.TokenText.endswith(Postfix));
assert(Tok.TokenText.starts_with(Prefix) && Tok.TokenText.ends_with(Postfix));
Line = Tok.TokenText.substr(
Prefix.size(), Tok.TokenText.size() - Prefix.size() - Postfix.size());
}
Expand Down Expand Up @@ -454,7 +454,7 @@ static bool mayReflowContent(StringRef Content) {
bool hasSpecialMeaningPrefix = false;
for (StringRef Prefix :
{"@", "TODO", "FIXME", "XXX", "-# ", "- ", "+ ", "* "}) {
if (Content.startswith(Prefix)) {
if (Content.starts_with(Prefix)) {
hasSpecialMeaningPrefix = true;
break;
}
Expand All @@ -471,7 +471,7 @@ static bool mayReflowContent(StringRef Content) {
// characters and either the first or second character must be
// non-punctuation.
return Content.size() >= 2 && !hasSpecialMeaningPrefix &&
!Content.endswith("\\") &&
!Content.ends_with("\\") &&
// Note that this is UTF-8 safe, since if isPunctuation(Content[0]) is
// true, then the first code point must be 1 byte long.
(!isPunctuation(Content[0]) || !isPunctuation(Content[1]));
Expand All @@ -488,7 +488,7 @@ BreakableBlockComment::BreakableBlockComment(
"block comment section must start with a block comment");

StringRef TokenText(Tok.TokenText);
assert(TokenText.startswith("/*") && TokenText.endswith("*/"));
assert(TokenText.starts_with("/*") && TokenText.ends_with("*/"));
TokenText.substr(2, TokenText.size() - 4)
.split(Lines, UseCRLF ? "\r\n" : "\n");

Expand All @@ -511,7 +511,7 @@ BreakableBlockComment::BreakableBlockComment(
// /*
// ** blah blah blah
// */
if (Lines.size() >= 2 && Content[1].startswith("**") &&
if (Lines.size() >= 2 && Content[1].starts_with("**") &&
static_cast<unsigned>(ContentColumn[1]) == StartColumn) {
DecorationColumn = StartColumn;
}
Expand All @@ -531,10 +531,10 @@ BreakableBlockComment::BreakableBlockComment(
// If the last line is empty, the closing "*/" will have a star.
if (Text.empty())
break;
} else if (!Text.empty() && Decoration.startswith(Text)) {
} else if (!Text.empty() && Decoration.starts_with(Text)) {
continue;
}
while (!Text.startswith(Decoration))
while (!Text.starts_with(Decoration))
Decoration = Decoration.drop_back(1);
}

Expand Down Expand Up @@ -562,13 +562,13 @@ BreakableBlockComment::BreakableBlockComment(
// The last line excludes the star if LastLineNeedsDecoration is false.
// For all other lines, adjust the line to exclude the star and
// (optionally) the first whitespace.
unsigned DecorationSize = Decoration.startswith(Content[i])
unsigned DecorationSize = Decoration.starts_with(Content[i])
? Content[i].size()
: Decoration.size();
if (DecorationSize)
ContentColumn[i] = DecorationColumn + DecorationSize;
Content[i] = Content[i].substr(DecorationSize);
if (!Decoration.startswith(Content[i])) {
if (!Decoration.starts_with(Content[i])) {
IndentAtLineBreak =
std::min<int>(IndentAtLineBreak, std::max(0, ContentColumn[i]));
}
Expand All @@ -577,10 +577,10 @@ BreakableBlockComment::BreakableBlockComment(

// Detect a multiline jsdoc comment and set DelimitersOnNewline in that case.
if (Style.isJavaScript() || Style.Language == FormatStyle::LK_Java) {
if ((Lines[0] == "*" || Lines[0].startswith("* ")) && Lines.size() > 1) {
if ((Lines[0] == "*" || Lines[0].starts_with("* ")) && Lines.size() > 1) {
// This is a multiline jsdoc comment.
DelimitersOnNewline = true;
} else if (Lines[0].startswith("* ") && Lines.size() == 1) {
} else if (Lines[0].starts_with("* ") && Lines.size() == 1) {
// Detect a long single-line comment, like:
// /** long long long */
// Below, '2' is the width of '*/'.
Expand Down Expand Up @@ -612,7 +612,7 @@ BreakableToken::Split BreakableBlockComment::getSplit(
return Split(StringRef::npos, 0);
return getCommentSplit(Content[LineIndex].substr(TailOffset),
ContentStartColumn, ColumnLimit, Style.TabWidth,
Encoding, Style, Decoration.endswith("*"));
Encoding, Style, Decoration.ends_with("*"));
}

void BreakableBlockComment::adjustWhitespace(unsigned LineIndex,
Expand All @@ -623,7 +623,7 @@ void BreakableBlockComment::adjustWhitespace(unsigned LineIndex,
// trimming the trailing whitespace. The backslash will be re-added later when
// inserting a line break.
size_t EndOfPreviousLine = Lines[LineIndex - 1].size();
if (InPPDirective && Lines[LineIndex - 1].endswith("\\"))
if (InPPDirective && Lines[LineIndex - 1].ends_with("\\"))
--EndOfPreviousLine;

// Calculate the end of the non-whitespace text in the previous line.
Expand Down Expand Up @@ -672,7 +672,7 @@ unsigned BreakableBlockComment::getRemainingLength(unsigned LineIndex,
// We never need a decoration when breaking just the trailing "*/" postfix.
bool HasRemainingText = Offset < Content[LineIndex].size();
if (!HasRemainingText) {
bool HasDecoration = Lines[LineIndex].ltrim().startswith(Decoration);
bool HasDecoration = Lines[LineIndex].ltrim().starts_with(Decoration);
if (HasDecoration)
LineLength -= Decoration.size();
}
Expand Down Expand Up @@ -700,7 +700,7 @@ unsigned BreakableBlockComment::getContentIndent(unsigned LineIndex) const {
// /** line 0 */
// is "* line 0", so we need to skip over the decoration in that case.
StringRef ContentWithNoDecoration = Content[LineIndex];
if (LineIndex == 0 && ContentWithNoDecoration.startswith("*"))
if (LineIndex == 0 && ContentWithNoDecoration.starts_with("*"))
ContentWithNoDecoration = ContentWithNoDecoration.substr(1).ltrim(Blanks);
StringRef FirstWord = ContentWithNoDecoration.substr(
0, ContentWithNoDecoration.find_first_of(Blanks));
Expand Down Expand Up @@ -853,7 +853,7 @@ bool BreakableBlockComment::mayReflow(
// Content[LineIndex] may exclude the indent after the '*' decoration. In that
// case, we compute the start of the comment pragma manually.
StringRef IndentContent = Content[LineIndex];
if (Lines[LineIndex].ltrim(Blanks).startswith("*"))
if (Lines[LineIndex].ltrim(Blanks).starts_with("*"))
IndentContent = Lines[LineIndex].ltrim(Blanks).substr(1);
return LineIndex > 0 && !CommentPragmasRegex.match(IndentContent) &&
mayReflowContent(Content[LineIndex]) && !Tok.Finalized &&
Expand All @@ -876,7 +876,7 @@ BreakableLineCommentSection::BreakableLineCommentSection(
CurrentTok = CurrentTok->Next) {
LastLineTok = LineTok;
StringRef TokenText(CurrentTok->TokenText);
assert((TokenText.startswith("//") || TokenText.startswith("#")) &&
assert((TokenText.starts_with("//") || TokenText.starts_with("#")) &&
"unsupported line comment prefix, '//' and '#' are supported");
size_t FirstLineIndex = Lines.size();
TokenText.split(Lines, "\n");
Expand Down Expand Up @@ -913,7 +913,7 @@ BreakableLineCommentSection::BreakableLineCommentSection(
// #########
// # section
// #########
if (FirstCommentChar == '#' && !TokenText.startswith("#"))
if (FirstCommentChar == '#' && !TokenText.starts_with("#"))
return false;
return FirstCommentChar == '\\' || isPunctuation(FirstCommentChar) ||
isHorizontalWhitespace(FirstCommentChar);
Expand Down Expand Up @@ -1152,7 +1152,7 @@ bool BreakableLineCommentSection::mayReflow(
// Line comments have the indent as part of the prefix, so we need to
// recompute the start of the line.
StringRef IndentContent = Content[LineIndex];
if (Lines[LineIndex].startswith("//"))
if (Lines[LineIndex].starts_with("//"))
IndentContent = Lines[LineIndex].substr(2);
// FIXME: Decide whether we want to reflow non-regular indents:
// Currently, we only reflow when the OriginalPrefix[LineIndex] matches the
Expand Down
33 changes: 18 additions & 15 deletions clang/lib/Format/ContinuationIndenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ static bool opensProtoMessageField(const FormatToken &LessTok,
// string. For example, the delimiter of R"deli(cont)deli" is deli.
static std::optional<StringRef> getRawStringDelimiter(StringRef TokenText) {
if (TokenText.size() < 5 // The smallest raw string possible is 'R"()"'.
|| !TokenText.startswith("R\"") || !TokenText.endswith("\"")) {
|| !TokenText.starts_with("R\"") || !TokenText.ends_with("\"")) {
return std::nullopt;
}

Expand All @@ -177,7 +177,7 @@ static std::optional<StringRef> getRawStringDelimiter(StringRef TokenText) {
size_t RParenPos = TokenText.size() - Delimiter.size() - 2;
if (TokenText[RParenPos] != ')')
return std::nullopt;
if (!TokenText.substr(RParenPos + 1).startswith(Delimiter))
if (!TokenText.substr(RParenPos + 1).starts_with(Delimiter))
return std::nullopt;
return Delimiter;
}
Expand Down Expand Up @@ -608,7 +608,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {

if (Current.is(tok::lessless) &&
((Previous.is(tok::identifier) && Previous.TokenText == "endl") ||
(Previous.Tok.isLiteral() && (Previous.TokenText.endswith("\\n\"") ||
(Previous.Tok.isLiteral() && (Previous.TokenText.ends_with("\\n\"") ||
Previous.TokenText == "\'\\n\'")))) {
return true;
}
Expand Down Expand Up @@ -2293,12 +2293,13 @@ ContinuationIndenter::createBreakableToken(const FormatToken &Current,
if (Style.isVerilog() || Style.Language == FormatStyle::LK_Java ||
Style.isJavaScript() || Style.isCSharp()) {
BreakableStringLiteralUsingOperators::QuoteStyleType QuoteStyle;
if (Style.isJavaScript() && Text.startswith("'") && Text.endswith("'")) {
if (Style.isJavaScript() && Text.starts_with("'") &&
Text.ends_with("'")) {
QuoteStyle = BreakableStringLiteralUsingOperators::SingleQuotes;
} else if (Style.isCSharp() && Text.startswith("@\"") &&
Text.endswith("\"")) {
} else if (Style.isCSharp() && Text.starts_with("@\"") &&
Text.ends_with("\"")) {
QuoteStyle = BreakableStringLiteralUsingOperators::AtDoubleQuotes;
} else if (Text.startswith("\"") && Text.endswith("\"")) {
} else if (Text.starts_with("\"") && Text.ends_with("\"")) {
QuoteStyle = BreakableStringLiteralUsingOperators::DoubleQuotes;
} else {
return nullptr;
Expand All @@ -2315,12 +2316,14 @@ ContinuationIndenter::createBreakableToken(const FormatToken &Current,
// FIXME: Store Prefix and Suffix (or PrefixLength and SuffixLength to
// reduce the overhead) for each FormatToken, which is a string, so that we
// don't run multiple checks here on the hot path.
if ((Text.endswith(Postfix = "\"") &&
(Text.startswith(Prefix = "@\"") || Text.startswith(Prefix = "\"") ||
Text.startswith(Prefix = "u\"") || Text.startswith(Prefix = "U\"") ||
Text.startswith(Prefix = "u8\"") ||
Text.startswith(Prefix = "L\""))) ||
(Text.startswith(Prefix = "_T(\"") && Text.endswith(Postfix = "\")"))) {
if ((Text.ends_with(Postfix = "\"") &&
(Text.starts_with(Prefix = "@\"") || Text.starts_with(Prefix = "\"") ||
Text.starts_with(Prefix = "u\"") ||
Text.starts_with(Prefix = "U\"") ||
Text.starts_with(Prefix = "u8\"") ||
Text.starts_with(Prefix = "L\""))) ||
(Text.starts_with(Prefix = "_T(\"") &&
Text.ends_with(Postfix = "\")"))) {
return std::make_unique<BreakableStringLiteral>(
Current, StartColumn, Prefix, Postfix, UnbreakableTailLength,
State.Line->InPPDirective, Encoding, Style);
Expand All @@ -2342,7 +2345,7 @@ ContinuationIndenter::createBreakableToken(const FormatToken &Current,
bool RegularComments = [&]() {
for (const FormatToken *T = &Current; T && T->is(TT_LineComment);
T = T->Next) {
if (!(T->TokenText.startswith("//") || T->TokenText.startswith("#")))
if (!(T->TokenText.starts_with("//") || T->TokenText.starts_with("#")))
return false;
}
return true;
Expand Down Expand Up @@ -2754,7 +2757,7 @@ bool ContinuationIndenter::nextIsMultilineString(const LineState &State) {
// We never consider raw string literals "multiline" for the purpose of
// AlwaysBreakBeforeMultilineStrings implementation as they are special-cased
// (see TokenAnnotator::mustBreakBefore().
if (Current.TokenText.startswith("R\""))
if (Current.TokenText.starts_with("R\""))
return false;
if (Current.IsMultiline)
return true;
Expand Down
Loading