compilerplugins/clang/bufferadd.cxx               |    3 ++-
 compilerplugins/clang/casttovoid.cxx              |    9 +++++----
 compilerplugins/clang/checkconfigmacros.cxx       |    3 ++-
 compilerplugins/clang/compat.hxx                  |   17 +++++++++++++++++
 compilerplugins/clang/consttobool.cxx             |    7 ++++---
 compilerplugins/clang/cstylecast.cxx              |    9 ++++-----
 compilerplugins/clang/dynexcspec.cxx              |    5 +++--
 compilerplugins/clang/fakebool.cxx                |    8 ++++----
 compilerplugins/clang/fieldcanbelocal.cxx         |    6 +++---
 compilerplugins/clang/finalclasses.cxx            |    6 ++++--
 compilerplugins/clang/literaltoboolconversion.cxx |    7 +++----
 compilerplugins/clang/mergeclasses.cxx            |    7 ++++---
 compilerplugins/clang/nullptr.cxx                 |    7 +++----
 compilerplugins/clang/overridevirtual.cxx         |    5 +++--
 compilerplugins/clang/plugin.cxx                  |   11 +++++------
 compilerplugins/clang/pluginhandler.cxx           |    9 +++++----
 compilerplugins/clang/redundantinline.cxx         |    4 ++--
 compilerplugins/clang/reservedid.cxx              |    5 +++--
 compilerplugins/clang/salcall.cxx                 |   14 +++++++-------
 compilerplugins/clang/sharedvisitor/analyzer.cxx  |   11 ++++++-----
 compilerplugins/clang/simplifypointertobool.cxx   |    5 +++--
 compilerplugins/clang/singlevalfields.cxx         |    2 +-
 compilerplugins/clang/stringadd.cxx               |    3 ++-
 compilerplugins/clang/stringconstant.cxx          |    8 ++++----
 compilerplugins/clang/unusedfields.cxx            |    6 +++---
 compilerplugins/clang/xmlimport.cxx               |    4 +++-
 26 files changed, 105 insertions(+), 76 deletions(-)

New commits:
commit d2c54902102ab9ee40cca16ae21f1bf3ad7c4066
Author:     Stephan Bergmann <[email protected]>
AuthorDate: Mon Dec 18 15:15:09 2023 +0100
Commit:     Stephan Bergmann <[email protected]>
CommitDate: Mon Dec 18 17:40:26 2023 +0100

    -Werror,-Wdeprecated-declarations
    
    > compilerplugins/clang/casttovoid.cxx:452:18: error: 'endswith' is 
deprecated: Use ends_with instead [-Werror,-Wdeprecated-declarations]
    >                 .endswith(".h"));
    >                  ^~~~~~~~
    >                  ends_with
    > ~/llvm/inst/include/llvm/ADT/StringRef.h:276:19: note: 'endswith' has 
been explicitly marked deprecated here
    >     [[nodiscard]] LLVM_DEPRECATED(
    >                   ^
    
    etc. after
    
<https://github.com/llvm/llvm-project/commit/5ac12951b4e9bbfcc5791282d0961ec2b65575e9>
    "[ADT] Deprecate StringRef::{starts,ends}with (#75491)" on Clang 18 trunk, 
where
    
<https://github.com/llvm/llvm-project/commit/1b97645e56bf321b06d1353024339958b64fd242>
    "[ADT] Introduce StringRef::{starts,ends}_width{,_insensitive}" had been 
added
    towards Clang 16
    
    Change-Id: Icb3e43b7d6be6f877815285913d846f766eddebf
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160919
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <[email protected]>

diff --git a/compilerplugins/clang/bufferadd.cxx 
b/compilerplugins/clang/bufferadd.cxx
index 7b3eaf7e416e..06f3a2b02733 100644
--- a/compilerplugins/clang/bufferadd.cxx
+++ b/compilerplugins/clang/bufferadd.cxx
@@ -15,6 +15,7 @@
 
 #include "plugin.hxx"
 #include "check.hxx"
+#include "compat.hxx"
 #include "config_clang.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/StmtVisitor.h"
@@ -344,7 +345,7 @@ bool BufferAdd::isSideEffectFree(Expr const* expr)
                     if (isSideEffectFree(callExpr->getArg(0)))
                         return true;
                 // allowlist some known-safe methods
-                if (name.endswith("ResId") || name == "GetXMLToken")
+                if (compat::ends_with(name, "ResId") || name == "GetXMLToken")
                     if (isSideEffectFree(callExpr->getArg(0)))
                         return true;
             }
diff --git a/compilerplugins/clang/casttovoid.cxx 
b/compilerplugins/clang/casttovoid.cxx
index c02cf6887365..87c2f4852aac 100644
--- a/compilerplugins/clang/casttovoid.cxx
+++ b/compilerplugins/clang/casttovoid.cxx
@@ -15,6 +15,7 @@
 #include "clang/AST/Attr.h"
 
 #include "check.hxx"
+#include "compat.hxx"
 #include "plugin.hxx"
 
 namespace {
@@ -446,10 +447,10 @@ private:
 
     bool isFromCIncludeFile(SourceLocation spellingLocation) const {
         return !compiler.getSourceManager().isInMainFile(spellingLocation)
-            && (StringRef(
-                    
compiler.getSourceManager().getPresumedLoc(spellingLocation)
-                    .getFilename())
-                .endswith(".h"));
+            && compat::ends_with(
+                StringRef(
+                    
compiler.getSourceManager().getPresumedLoc(spellingLocation).getFilename()),
+                ".h");
     }
 
     bool isSharedCAndCppCode(VarDecl const * decl) const {
diff --git a/compilerplugins/clang/checkconfigmacros.cxx 
b/compilerplugins/clang/checkconfigmacros.cxx
index aea60ed561b5..4bed4c82502c 100644
--- a/compilerplugins/clang/checkconfigmacros.cxx
+++ b/compilerplugins/clang/checkconfigmacros.cxx
@@ -12,6 +12,7 @@
 #include <memory>
 #include <set>
 
+#include "compat.hxx"
 #include "plugin.hxx"
 
 #include "config_clang.h"
@@ -71,7 +72,7 @@ void CheckConfigMacros::MacroDefined( const Token& 
macroToken, const MacroDirect
 //        fprintf(stderr,"DEF: %s %s\n", 
macroToken.getIdentifierInfo()->getName().data(), filename );
         StringRef macro = macroToken.getIdentifierInfo()->getName();
         // Skia #defines do not have values, but we set them in config_skia.h .
-        if( macro.startswith( "SK_" ) && loplugin::isSamePathname(filename, 
BUILDDIR "/config_host/config_skia.h"))
+        if( compat::starts_with(macro, "SK_" ) && 
loplugin::isSamePathname(filename, BUILDDIR "/config_host/config_skia.h"))
             return;
         configMacros.insert( macro.str());
         }
diff --git a/compilerplugins/clang/compat.hxx b/compilerplugins/clang/compat.hxx
index d122933eeaaf..42ab1a80545c 100644
--- a/compilerplugins/clang/compat.hxx
+++ b/compilerplugins/clang/compat.hxx
@@ -17,6 +17,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Specifiers.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/FileSystem.h"
 
 #include "config_clang.h"
@@ -63,6 +64,22 @@ inline std::string toString(llvm::APSInt const & i, unsigned 
radix) {
 #endif
 }
 
+inline bool starts_with(llvm::StringRef s, llvm::StringRef Prefix) {
+#if CLANG_VERSION >= 160000
+    return s.starts_with(Prefix);
+#else
+    return s.startswith(Prefix);
+#endif
+}
+
+inline bool ends_with(llvm::StringRef s, llvm::StringRef Suffix) {
+#if CLANG_VERSION >= 160000
+    return s.ends_with(Suffix);
+#else
+    return s.endswith(Suffix);
+#endif
+}
+
 inline std::pair<clang::SourceLocation, clang::SourceLocation> 
getImmediateExpansionRange(
     clang::SourceManager const & SM, clang::SourceLocation Loc)
 {
diff --git a/compilerplugins/clang/consttobool.cxx 
b/compilerplugins/clang/consttobool.cxx
index c13bf7729e72..124ab4efbaaa 100644
--- a/compilerplugins/clang/consttobool.cxx
+++ b/compilerplugins/clang/consttobool.cxx
@@ -266,9 +266,10 @@ private:
     bool isFromCIncludeFile(SourceLocation spellingLocation) const
     {
         return !compiler.getSourceManager().isInMainFile(spellingLocation)
-               && (StringRef(
-                       
compiler.getSourceManager().getPresumedLoc(spellingLocation).getFilename())
-                       .endswith(".h"));
+               && compat::ends_with(StringRef(compiler.getSourceManager()
+                                                  
.getPresumedLoc(spellingLocation)
+                                                  .getFilename()),
+                                    ".h");
     }
 
     bool isSharedCAndCppCode(SourceLocation location) const
diff --git a/compilerplugins/clang/cstylecast.cxx 
b/compilerplugins/clang/cstylecast.cxx
index d51eb75b3df2..a516144a6141 100644
--- a/compilerplugins/clang/cstylecast.cxx
+++ b/compilerplugins/clang/cstylecast.cxx
@@ -319,10 +319,9 @@ bool CStyleCast::isConstCast(QualType from, QualType to) {
 
 bool CStyleCast::isFromCIncludeFile(SourceLocation spellingLocation) const {
     return !compiler.getSourceManager().isInMainFile(spellingLocation)
-        && (StringRef(
-                compiler.getSourceManager().getPresumedLoc(spellingLocation)
-                .getFilename())
-            .endswith(".h"));
+        && compat::ends_with(
+            
StringRef(compiler.getSourceManager().getPresumedLoc(spellingLocation).getFilename()),
+            ".h");
 }
 
 bool CStyleCast::isSharedCAndCppCode(SourceLocation location) const {
@@ -346,7 +345,7 @@ bool CStyleCast::isLastTokenOfImmediateMacroBodyExpansion(
     auto const spell = compiler.getSourceManager().getSpellingLoc(loc);
     auto name = Lexer::getImmediateMacroName(
         loc, compiler.getSourceManager(), compiler.getLangOpts());
-    while (name.startswith("\\\n")) {
+    while (compat::starts_with(name, "\\\n")) {
         name = name.drop_front(2);
         while (!name.empty()
                && (name.front() == ' ' || name.front() == '\t' || name.front() 
== '\n'
diff --git a/compilerplugins/clang/dynexcspec.cxx 
b/compilerplugins/clang/dynexcspec.cxx
index af733ec4f10f..2cedb8e046f2 100644
--- a/compilerplugins/clang/dynexcspec.cxx
+++ b/compilerplugins/clang/dynexcspec.cxx
@@ -13,6 +13,7 @@
 
 #include "clang/AST/Comment.h"
 
+#include "compat.hxx"
 #include "plugin.hxx"
 
 // Remove dynamic exception specifications.  See the mail thread starting at
@@ -115,7 +116,7 @@ public:
                         auto s = StringRef(
                             compiler.getSourceManager().getCharacterData(prev),
                             n);
-                        while (s.startswith("\\\n")) {
+                        while (compat::starts_with(s, "\\\n")) {
                             s = s.drop_front(2);
                             while (!s.empty()
                                    && (s.front() == ' ' || s.front() == '\t'
@@ -126,7 +127,7 @@ public:
                             }
                         }
                         if (!s.empty() && s != "\\") {
-                            if (s.startswith("//")) {
+                            if (compat::starts_with(s, "//")) {
                                 beg = source.getBegin();
                             }
                             break;
diff --git a/compilerplugins/clang/fakebool.cxx 
b/compilerplugins/clang/fakebool.cxx
index cc7a9434a69e..23dac488cb14 100644
--- a/compilerplugins/clang/fakebool.cxx
+++ b/compilerplugins/clang/fakebool.cxx
@@ -19,6 +19,7 @@
 #include "config_clang.h"
 
 #include "check.hxx"
+#include "compat.hxx"
 #include "functionaddress.hxx"
 #include "plugin.hxx"
 
@@ -871,10 +872,9 @@ bool FakeBool::TraverseLinkageSpecDecl(LinkageSpecDecl * 
decl) {
 
 bool FakeBool::isFromCIncludeFile(SourceLocation spellingLocation) const {
     return !compiler.getSourceManager().isInMainFile(spellingLocation)
-        && (StringRef(
-                compiler.getSourceManager().getPresumedLoc(spellingLocation)
-                .getFilename())
-            .endswith(".h"));
+        && compat::ends_with(
+            
StringRef(compiler.getSourceManager().getPresumedLoc(spellingLocation).getFilename()),
+            ".h");
 }
 
 bool FakeBool::isSharedCAndCppCode(SourceLocation location) const {
diff --git a/compilerplugins/clang/fieldcanbelocal.cxx 
b/compilerplugins/clang/fieldcanbelocal.cxx
index ae1af187befb..9d4b60fd094b 100644
--- a/compilerplugins/clang/fieldcanbelocal.cxx
+++ b/compilerplugins/clang/fieldcanbelocal.cxx
@@ -260,9 +260,9 @@ bool FieldCanBeLocal::TraverseCXXMethodDecl(CXXMethodDecl* 
cxxMethodDecl)
     {
         if (cxxMethodDecl->isCopyAssignmentOperator() || 
cxxMethodDecl->isMoveAssignmentOperator()
             || (cxxMethodDecl->getIdentifier()
-                && (cxxMethodDecl->getName().startswith("Clone")
-                    || cxxMethodDecl->getName().startswith("clone")
-                    || cxxMethodDecl->getName().startswith("createClone"))))
+                && (compat::starts_with(cxxMethodDecl->getName(), "Clone")
+                    || compat::starts_with(cxxMethodDecl->getName(), "clone")
+                    || compat::starts_with(cxxMethodDecl->getName(), 
"createClone"))))
             insideMoveOrCopyOrCloneDeclParent = cxxMethodDecl->getParent();
         // these are similar in that they tend to simply enumerate all the 
fields of an object without putting
         // them to some useful purpose
diff --git a/compilerplugins/clang/finalclasses.cxx 
b/compilerplugins/clang/finalclasses.cxx
index 327ff92653c0..2d19dd67d703 100644
--- a/compilerplugins/clang/finalclasses.cxx
+++ b/compilerplugins/clang/finalclasses.cxx
@@ -12,6 +12,7 @@
 #include <string>
 #include <iostream>
 #include "config_clang.h"
+#include "compat.hxx"
 #include "plugin.hxx"
 #include <fstream>
 
@@ -76,8 +77,9 @@ private:
 bool ignoreClass(StringRef s)
 {
     // ignore stuff in the standard library, and UNO stuff we can't touch.
-    if (s.startswith("rtl::") || s.startswith("sal::") || 
s.startswith("com::sun::")
-        || s.startswith("std::") || s.startswith("boost::")
+    if (compat::starts_with(s, "rtl::") || compat::starts_with(s, "sal::")
+        || compat::starts_with(s, "com::sun::") || compat::starts_with(s, 
"std::")
+        || compat::starts_with(s, "boost::")
         || s == "OString" || s == "OUString" || s == "bad_alloc")
     {
         return true;
diff --git a/compilerplugins/clang/literaltoboolconversion.cxx 
b/compilerplugins/clang/literaltoboolconversion.cxx
index 9894daec51b6..3d3a3615ec68 100644
--- a/compilerplugins/clang/literaltoboolconversion.cxx
+++ b/compilerplugins/clang/literaltoboolconversion.cxx
@@ -81,10 +81,9 @@ bool LiteralToBoolConversion::isFromCIncludeFile(
     SourceLocation spellingLocation) const
 {
     return !compiler.getSourceManager().isInMainFile(spellingLocation)
-        && (StringRef(
-                compiler.getSourceManager().getPresumedLoc(spellingLocation)
-                .getFilename())
-            .endswith(".h"));
+        && compat::ends_with(
+            
StringRef(compiler.getSourceManager().getPresumedLoc(spellingLocation).getFilename()),
+            ".h");
 }
 
 bool LiteralToBoolConversion::isSharedCAndCppCode(SourceLocation location) 
const
diff --git a/compilerplugins/clang/mergeclasses.cxx 
b/compilerplugins/clang/mergeclasses.cxx
index 5ac69bc52397..0c023a9bd15a 100644
--- a/compilerplugins/clang/mergeclasses.cxx
+++ b/compilerplugins/clang/mergeclasses.cxx
@@ -87,14 +87,15 @@ public:
 bool ignoreClass(StringRef s)
 {
     // ignore stuff in the standard library, and UNO stuff we can't touch.
-    if (s.startswith("rtl::") || s.startswith("sal::") || 
s.startswith("com::sun::")
-        || s.startswith("std::") || s.startswith("boost::")
+    if (compat::starts_with(s, "rtl::") || compat::starts_with(s, "sal::")
+        || compat::starts_with(s, "com::sun::") || compat::starts_with(s, 
"std::")
+        || compat::starts_with(s, "boost::")
         || s == "OString" || s == "OUString" || s == "bad_alloc")
     {
         return true;
     }
     // ignore instantiations of pointers and arrays
-    if (s.endswith("*") || s.endswith("]")) {
+    if (compat::ends_with(s, "*") || compat::ends_with(s, "]")) {
         return true;
     }
     return false;
diff --git a/compilerplugins/clang/nullptr.cxx 
b/compilerplugins/clang/nullptr.cxx
index dcacb1bd2112..0213b6b05c88 100644
--- a/compilerplugins/clang/nullptr.cxx
+++ b/compilerplugins/clang/nullptr.cxx
@@ -248,10 +248,9 @@ bool Nullptr::isInLokIncludeFile(SourceLocation 
spellingLocation) const {
 
 bool Nullptr::isFromCIncludeFile(SourceLocation spellingLocation) const {
     return !compiler.getSourceManager().isInMainFile(spellingLocation)
-        && (StringRef(
-                compiler.getSourceManager().getPresumedLoc(spellingLocation)
-                .getFilename())
-            .endswith(".h"));
+        && compat::ends_with(
+            
StringRef(compiler.getSourceManager().getPresumedLoc(spellingLocation).getFilename()),
+            ".h");
 }
 
 bool Nullptr::isSharedCAndCppCode(SourceLocation location) const {
diff --git a/compilerplugins/clang/overridevirtual.cxx 
b/compilerplugins/clang/overridevirtual.cxx
index 8dd29ab0e426..b7fd2ce4d9cc 100644
--- a/compilerplugins/clang/overridevirtual.cxx
+++ b/compilerplugins/clang/overridevirtual.cxx
@@ -16,6 +16,7 @@
 
 #include "clang/AST/Attr.h"
 
+#include "compat.hxx"
 #include "plugin.hxx"
 
 namespace {
@@ -94,7 +95,7 @@ bool OverrideVirtual::VisitCXXMethodDecl(CXXMethodDecl const 
* decl) {
             // where "\<NL>" is followed directly by a real token without
             // intervening whitespace, tokens "\<NL>virtual" and "\<NL>{" are
             // reported:
-            if (s.startswith("\\\n")) {
+            if (compat::starts_with(s, "\\\n")) {
                 s = s.drop_front(2);
             }
             if (parens == 0) {
@@ -120,7 +121,7 @@ bool OverrideVirtual::VisitCXXMethodDecl(CXXMethodDecl 
const * decl) {
                     addSpace = false;
                 }
                 seenSpace = true;
-            } else if (s.startswith("/*") || s.startswith("//") || s == "\\") {
+            } else if (compat::starts_with(s, "/*") || compat::starts_with(s, 
"//") || s == "\\") {
                 if (!seenSpace) {
                     addSpace = true;
                 }
diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx
index 10102d426079..8d8207d30437 100644
--- a/compilerplugins/clang/plugin.cxx
+++ b/compilerplugins/clang/plugin.cxx
@@ -203,7 +203,7 @@ bool Plugin::suppressWarningAt(SourceLocation location) 
const {
                 if (isDebugMode()) {
                     report(DiagnosticsEngine::Fatal, "failed to getSpelling", 
prev);
                 }
-            } else if (!spell.startswith("/*")) {
+            } else if (!compat::starts_with(spell, "/*")) {
                 continue;
             }
         }
@@ -441,7 +441,7 @@ StringRef Plugin::getFilenameOfLocation(SourceLocation 
spellingLocation) const
             return fn;
         }
 #if !defined _WIN32
-        assert(fn.startswith("/") || fn == "<stdin>");
+        assert(compat::starts_with(fn, "/") || fn == "<stdin>");
 #endif
         s_Mode = fn == "<stdin>" ? STDIN : GOOD;
         return getFilenameOfLocation(spellingLocation);
@@ -862,9 +862,8 @@ bool RewritePlugin::wouldRewriteWorkdir(SourceLocation loc)
     if (loc.isInvalid() || loc.isMacroID()) {
         return false;
     }
-    return
-        getFilenameOfLocation(compiler.getSourceManager().getSpellingLoc(loc))
-        .startswith(WORKDIR "/");
+    return compat::starts_with(
+        
getFilenameOfLocation(compiler.getSourceManager().getSpellingLoc(loc)), WORKDIR 
"/");
 }
 
 bool RewritePlugin::reportEditFailure( SourceLocation loc )
@@ -918,7 +917,7 @@ bool hasPathnamePrefix(StringRef pathname, StringRef prefix)
 {
     return checkPathname(
         pathname, prefix,
-        [](StringRef p, StringRef a) { return p.startswith(a); });
+        [](StringRef p, StringRef a) { return compat::starts_with(p, a); });
 }
 
 bool isSamePathname(StringRef pathname, StringRef other)
diff --git a/compilerplugins/clang/pluginhandler.cxx 
b/compilerplugins/clang/pluginhandler.cxx
index fdf9658e2765..6f4bab5a5349 100644
--- a/compilerplugins/clang/pluginhandler.cxx
+++ b/compilerplugins/clang/pluginhandler.cxx
@@ -15,6 +15,7 @@
 
 #include "config_clang.h"
 
+#include "compat.hxx"
 #include "plugin.hxx"
 #include "pluginhandler.hxx"
 
@@ -318,7 +319,7 @@ void PluginHandler::HandleTranslationUnit( ASTContext& 
context )
     llvm::TimeTraceScope mainTimeScope("LOPluginMain", StringRef(""));
     if( context.getDiagnostics().hasErrorOccurred())
         return;
-    if (mainFileName.endswith(".ii"))
+    if (compat::ends_with(mainFileName, ".ii"))
     {
         report(DiagnosticsEngine::Fatal,
             "input file has suffix .ii: \"%0\"\nhighly suspicious, probably 
ccache generated, this will break warning suppressions; export CCACHE_CPP2=1 to 
prevent this") << mainFileName;
@@ -353,11 +354,11 @@ void PluginHandler::HandleTranslationUnit( ASTContext& 
context )
         const char* pathWarning = NULL;
         bool bSkip = false;
         StringRef const name = e->getName();
-        if( name.startswith(WORKDIR "/") )
+        if( compat::starts_with(name, WORKDIR "/") )
             pathWarning = "modified source in workdir/ : %0";
-        else if( strcmp( SRCDIR, BUILDDIR ) != 0 && name.startswith(BUILDDIR 
"/") )
+        else if( strcmp( SRCDIR, BUILDDIR ) != 0 && compat::starts_with(name, 
BUILDDIR "/") )
             pathWarning = "modified source in build dir : %0";
-        else if( name.startswith(SRCDIR "/") )
+        else if( compat::starts_with(name, SRCDIR "/") )
             ; // ok
         else
         {
diff --git a/compilerplugins/clang/redundantinline.cxx 
b/compilerplugins/clang/redundantinline.cxx
index 962a11ed6037..c9491445b64f 100644
--- a/compilerplugins/clang/redundantinline.cxx
+++ b/compilerplugins/clang/redundantinline.cxx
@@ -55,7 +55,7 @@ private:
                 loc, compiler.getSourceManager(), compiler.getLangOpts());
             StringRef s(compiler.getSourceManager().getCharacterData(loc), n);
             //TODO: see compilerplugins/clang/override.cxx:
-            if (s.startswith("\\\n")) {
+            if (compat::starts_with(s, "\\\n")) {
                 s = s.drop_front(2);
             }
             if (s == "inline") {
@@ -87,7 +87,7 @@ private:
                 StringRef s(
                     compiler.getSourceManager().getCharacterData(loc), n2);
                 //TODO: see compilerplugins/clang/override.cxx:
-                if (s.startswith("\\\n")) {
+                if (compat::starts_with(s, "\\\n")) {
                     s = s.drop_front(2);
                 }
                 if (!s.empty()) {
diff --git a/compilerplugins/clang/reservedid.cxx 
b/compilerplugins/clang/reservedid.cxx
index f0840ace62ed..8fad7739065a 100644
--- a/compilerplugins/clang/reservedid.cxx
+++ b/compilerplugins/clang/reservedid.cxx
@@ -19,6 +19,7 @@
 
 #include "config_clang.h"
 
+#include "compat.hxx"
 #include "plugin.hxx"
 
 namespace {
@@ -33,7 +34,7 @@ bool isJniFunction(NamedDecl const * decl) {
         return false;
     }
     auto const id = decl->getIdentifier();
-    return id != nullptr && id->getName().startswith("Java_");
+    return id != nullptr && compat::starts_with(id->getName(), "Java_");
 }
 
 class ReservedId:
@@ -146,7 +147,7 @@ bool ReservedId::VisitNamedDecl(NamedDecl const * decl) {
     }
     auto filename = getFilenameOfLocation(spelLoc);
     if (loplugin::hasPathnamePrefix(filename, SRCDIR 
"/bridges/source/cpp_uno/")
-        && (filename.endswith("abi.hxx") || filename.endswith("share.hxx")))
+        && (compat::ends_with(filename, "abi.hxx") || 
compat::ends_with(filename, "share.hxx")))
     {
         return true;
     }
diff --git a/compilerplugins/clang/salcall.cxx 
b/compilerplugins/clang/salcall.cxx
index d2b4fc2bfb2b..06ff72e27a00 100644
--- a/compilerplugins/clang/salcall.cxx
+++ b/compilerplugins/clang/salcall.cxx
@@ -371,7 +371,7 @@ bool SalCall::isSalCallFunction(FunctionDecl const* 
functionDecl, SourceLocation
             assert(SM.isMacroBodyExpansion(startLoc));
             auto const startLoc2 = compat::getImmediateExpansionRange(SM, 
startLoc).second;
             auto name = Lexer::getImmediateMacroName(startLoc, SM, 
compiler.getLangOpts());
-            while (name.startswith("\\\n"))
+            while (compat::starts_with(name, "\\\n"))
             {
                 name = name.drop_front(2);
                 while (!name.empty()
@@ -413,7 +413,7 @@ bool SalCall::isSalCallFunction(FunctionDecl const* 
functionDecl, SourceLocation
         if (SM.isMacroBodyExpansion(endLoc))
         {
             auto name = Lexer::getImmediateMacroName(endLoc, SM, 
compiler.getLangOpts());
-            while (name.startswith("\\\n"))
+            while (compat::starts_with(name, "\\\n"))
             {
                 name = name.drop_front(2);
                 while (!name.empty()
@@ -506,8 +506,8 @@ bool SalCall::isSalCallFunction(FunctionDecl const* 
functionDecl, SourceLocation
                     // in the first line and include the intervening spaces 
and (part of? looks like an
                     // error in Clang) "barbaz", so just skip any tokens 
starting with backslash-newline
                     // when looking backwards here, without even trying to 
look at their content:
-                    if (!(s.empty() || s.startswith("/*") || s.startswith("//")
-                          || s.startswith("\\\n")))
+                    if (!(s.empty() || compat::starts_with(s, "/*") || 
compat::starts_with(s, "//")
+                          || compat::starts_with(s, "\\\n")))
                     {
                         break;
                     }
@@ -532,8 +532,8 @@ bool SalCall::isSalCallFunction(FunctionDecl const* 
functionDecl, SourceLocation
                     // in the first line and include the intervening spaces 
and (part of? looks like an
                     // error in Clang) "barbaz", so just skip any tokens 
starting with backslash-newline
                     // when looking backwards here, without even trying to 
look at their content:
-                    if (!(s.empty() || s.startswith("/*") || s.startswith("//")
-                          || s.startswith("\\\n")))
+                    if (!(s.empty() || compat::starts_with(s, "/*") || 
compat::starts_with(s, "//")
+                          || compat::starts_with(s, "\\\n")))
                     {
                         break;
                     }
@@ -568,7 +568,7 @@ bool SalCall::isSalCallFunction(FunctionDecl const* 
functionDecl, SourceLocation
         {
             unsigned n = Lexer::MeasureTokenLength(loc, SM, 
compiler.getLangOpts());
             auto s = 
StringRef(compiler.getSourceManager().getCharacterData(loc), n);
-            while (s.startswith("\\\n"))
+            while (compat::starts_with(s, "\\\n"))
             {
                 s = s.drop_front(2);
                 while (!s.empty()
diff --git a/compilerplugins/clang/sharedvisitor/analyzer.cxx 
b/compilerplugins/clang/sharedvisitor/analyzer.cxx
index a000bd249ffa..a23f0a16d01e 100644
--- a/compilerplugins/clang/sharedvisitor/analyzer.cxx
+++ b/compilerplugins/clang/sharedvisitor/analyzer.cxx
@@ -25,6 +25,7 @@
 #include "config_clang.h"
 #include "../check.hxx"
 #include "../check.cxx"
+#include "../compat.hxx"
 
 using namespace clang;
 using namespace llvm;
@@ -125,7 +126,7 @@ bool CheckFileVisitor::VisitCXXRecordDecl( CXXRecordDecl* 
decl )
             continue;
         if( method->isStatic() || method->getAccess() != AS_public )
             continue;
-        if( method->getName().startswith( "Visit" ))
+        if( compat::starts_with(method->getName(), "Visit" ))
         {
             if( method->getNumParams() == 1 )
             {
@@ -144,7 +145,7 @@ bool CheckFileVisitor::VisitCXXRecordDecl( CXXRecordDecl* 
decl )
                 abort();
             }
         }
-        else if( method->getName().startswith( "Traverse" ))
+        else if( compat::starts_with(method->getName(), "Traverse" ))
         {
             if( method->getNumParams() == 1 )
             {
@@ -159,13 +160,13 @@ bool CheckFileVisitor::VisitCXXRecordDecl( CXXRecordDecl* 
decl )
                 abort();
             }
         }
-        else if( method->getName().startswith( "PreTraverse" ))
+        else if( compat::starts_with(method->getName(), "PreTraverse" ))
         {
             TraverseFunctionInfo traverseInfo = 
findOrCreateTraverseFunctionInfo( method->getName().substr( 3 ));
             traverseInfo.hasPre = true;
             traverseFunctions.insert( std::move( traverseInfo ));
         }
-        else if( method->getName().startswith( "PostTraverse" ))
+        else if( compat::starts_with(method->getName(), "PostTraverse" ))
         {
                 TraverseFunctionInfo traverseInfo = 
findOrCreateTraverseFunctionInfo( method->getName().substr( 4 ));
                 traverseInfo.hasPost = true;
@@ -175,7 +176,7 @@ bool CheckFileVisitor::VisitCXXRecordDecl( CXXRecordDecl* 
decl )
             std::cout << "ShouldVisitTemplateInstantiations:1" << std::endl;
         else if (method->getName() == "shouldVisitImplicitCode")
             std::cout << "ShouldVisitImplicitCode:1" << std::endl;
-        else if( method->getName().startswith( "WalkUp" ))
+        else if( compat::starts_with(method->getName(), "WalkUp" ))
         {
             std::cerr << "WalkUp function not supported for shared visitor: " 
<< decl->getName().str()
                  << "::" << method->getName().str() << std::endl;
diff --git a/compilerplugins/clang/simplifypointertobool.cxx 
b/compilerplugins/clang/simplifypointertobool.cxx
index 11aed0f317b7..1a9471fcf877 100644
--- a/compilerplugins/clang/simplifypointertobool.cxx
+++ b/compilerplugins/clang/simplifypointertobool.cxx
@@ -19,6 +19,7 @@
 
 #include "plugin.hxx"
 #include "check.hxx"
+#include "compat.hxx"
 
 /**
   Simplify boolean expressions involving smart pointers e.g.
@@ -262,7 +263,7 @@ private:
             auto const s = 
StringRef(compiler.getSourceManager().getCharacterData(start),
                                      Lexer::MeasureTokenLength(start, 
compiler.getSourceManager(),
                                                                
compiler.getLangOpts()));
-            if (s.empty() || s.startswith("\\\n"))
+            if (s.empty() || compat::starts_with(s, "\\\n"))
             {
                 continue;
             }
@@ -279,7 +280,7 @@ private:
             auto const s = 
StringRef(compiler.getSourceManager().getCharacterData(start1),
                                      Lexer::MeasureTokenLength(start1, 
compiler.getSourceManager(),
                                                                
compiler.getLangOpts()));
-            if (!(s.empty() || s.startswith("\\\n")))
+            if (!(s.empty() || compat::starts_with(s, "\\\n")))
             {
                 break;
             }
diff --git a/compilerplugins/clang/singlevalfields.cxx 
b/compilerplugins/clang/singlevalfields.cxx
index 8964d4fa3fde..1e930878e6ff 100644
--- a/compilerplugins/clang/singlevalfields.cxx
+++ b/compilerplugins/clang/singlevalfields.cxx
@@ -291,7 +291,7 @@ void SingleValFields::walkPotentialAssign( const 
DeclaratorDecl* fieldOrVarDecl,
         if (methodDecl && (methodDecl->isCopyAssignmentOperator() || 
methodDecl->isMoveAssignmentOperator()))
            return;
         if (methodDecl && methodDecl->getIdentifier()
-            && (methodDecl->getName().startswith("Clone") || 
methodDecl->getName().startswith("clone")))
+            && (compat::starts_with(methodDecl->getName(), "Clone") || 
compat::starts_with(methodDecl->getName(), "clone")))
            return;
         auto cxxConstructorDecl = dyn_cast<CXXConstructorDecl>(parentFunction);
         if (cxxConstructorDecl && 
cxxConstructorDecl->isCopyOrMoveConstructor())
diff --git a/compilerplugins/clang/stringadd.cxx 
b/compilerplugins/clang/stringadd.cxx
index 022bffa804fc..0ac4ee6d3c65 100644
--- a/compilerplugins/clang/stringadd.cxx
+++ b/compilerplugins/clang/stringadd.cxx
@@ -16,6 +16,7 @@
 
 #include "plugin.hxx"
 #include "check.hxx"
+#include "compat.hxx"
 #include "config_clang.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/StmtVisitor.h"
@@ -478,7 +479,7 @@ bool StringAdd::isSideEffectFree(Expr const* expr)
                     if (isSideEffectFree(callExpr->getArg(0)))
                         return true;
                 // allowlist some known-safe methods
-                if (name.endswith("ResId") || name == "GetXMLToken")
+                if (compat::ends_with(name, "ResId") || name == "GetXMLToken")
                     if (isSideEffectFree(callExpr->getArg(0)))
                         return true;
             }
diff --git a/compilerplugins/clang/stringconstant.cxx 
b/compilerplugins/clang/stringconstant.cxx
index c64c2c9d6589..134be1940b82 100644
--- a/compilerplugins/clang/stringconstant.cxx
+++ b/compilerplugins/clang/stringconstant.cxx
@@ -2089,7 +2089,7 @@ void StringConstant::handleStringCtor(
                 if (!first) {
                     StringRef s(
                         compiler.getSourceManager().getCharacterData(loc2), n);
-                    while (s.startswith("\\\n")) {
+                    while (compat::starts_with(s, "\\\n")) {
                         s = s.drop_front(2);
                         while (!s.empty()
                                && (s.front() == ' ' || s.front() == '\t'
@@ -2099,7 +2099,7 @@ void StringConstant::handleStringCtor(
                             s = s.drop_front(1);
                         }
                     }
-                    if (!(s.empty() || s.startswith("/*") || s.startswith("//")
+                    if (!(s.empty() || compat::starts_with(s, "/*") || 
compat::starts_with(s, "//")
                           || s == "\\"))
                     {
                         break;
@@ -2115,7 +2115,7 @@ void StringConstant::handleStringCtor(
                 unsigned n = Lexer::MeasureTokenLength(
                     l, compiler.getSourceManager(), compiler.getLangOpts());
                 StringRef s(compiler.getSourceManager().getCharacterData(l), 
n);
-                while (s.startswith("\\\n")) {
+                while (compat::starts_with(s, "\\\n")) {
                     s = s.drop_front(2);
                     while (!s.empty()
                            && (s.front() == ' ' || s.front() == '\t'
@@ -2125,7 +2125,7 @@ void StringConstant::handleStringCtor(
                         s = s.drop_front(1);
                     }
                 }
-                if (!(s.empty() || s.startswith("/*") || s.startswith("//")
+                if (!(s.empty() || compat::starts_with(s, "/*") || 
compat::starts_with(s, "//")
                       || s == "\\"))
                 {
                     break;
diff --git a/compilerplugins/clang/unusedfields.cxx 
b/compilerplugins/clang/unusedfields.cxx
index ca5eb3eb00b3..d089d11d4956 100644
--- a/compilerplugins/clang/unusedfields.cxx
+++ b/compilerplugins/clang/unusedfields.cxx
@@ -406,9 +406,9 @@ bool UnusedFields::TraverseCXXMethodDecl(CXXMethodDecl* 
cxxMethodDecl)
         if (cxxMethodDecl->isCopyAssignmentOperator()
             || cxxMethodDecl->isMoveAssignmentOperator()
             || (cxxMethodDecl->getIdentifier()
-                && (cxxMethodDecl->getName().startswith("Clone")
-                    || cxxMethodDecl->getName().startswith("clone")
-                    || cxxMethodDecl->getName().startswith("createClone"))))
+                && (compat::starts_with(cxxMethodDecl->getName(), "Clone")
+                    || compat::starts_with(cxxMethodDecl->getName(), "clone")
+                    || compat::starts_with(cxxMethodDecl->getName(), 
"createClone"))))
             insideMoveOrCopyOrCloneDeclParent = cxxMethodDecl->getParent();
         // these are similar in that they tend to simply enumerate all the 
fields of an object without putting
         // them to some useful purpose
diff --git a/compilerplugins/clang/xmlimport.cxx 
b/compilerplugins/clang/xmlimport.cxx
index 1f9f44090b8a..1e883b60a918 100644
--- a/compilerplugins/clang/xmlimport.cxx
+++ b/compilerplugins/clang/xmlimport.cxx
@@ -12,6 +12,7 @@
 
 #include "plugin.hxx"
 #include "check.hxx"
+#include "compat.hxx"
 #include "config_clang.h"
 #include <iostream>
 #include <unordered_map>
@@ -369,7 +370,8 @@ bool XmlImport::isXmlTokEnum(const Expr* expr)
     auto enumConstant = dyn_cast<EnumConstantDecl>(declRefExpr->getDecl());
     if (!enumConstant)
         return false;
-    return enumConstant->getIdentifier() && 
enumConstant->getName().startswith("XML_TOK_");
+    return enumConstant->getIdentifier()
+           && compat::starts_with(enumConstant->getName(), "XML_TOK_");
 }
 
 bool XmlImport::isUInt16(const Expr* expr)

Reply via email to