https://github.com/Michael137 created 
https://github.com/llvm/llvm-project/pull/172466

We had a dedicated `StringLexer` class that pretty much just replicates the 
`llvm::StringRef` interface. This patch removes the `StringLexer` in favour of 
just using `llvm::StringRef`. Much of the string parsing can be cleaned up, but 
I tried to keep the changes a small as possible so just kept the logic and 
replaced the APIs calls. The only awkward side-effect of this is that we have 
to pass a `llvm::StringRef &` around.

There were some gaps in the API, so added two helper methods to consume/pop off 
characters from the front of the StringRef (maybe those can be added to 
`llvm::StringRef` in the future).

The `StringLexer` also had a roll-back mechanism used in two places. That can 
be handled by just saving a copy of the `StringRef`.

>From c1570be107d01a6da3cbb373bd4c7540a0ff5e83 Mon Sep 17 00:00:00 2001
From: Michael Buch <[email protected]>
Date: Tue, 16 Dec 2025 11:49:58 +0000
Subject: [PATCH] [lldb][ObjC][NFCI] Replace StringLexer with llvm::StringRef

We had a dedicated `StringLexer` class that pretty much just replicates
the `llvm::StringRef` interface. This patch removes the `StringLexer` in
favour of just using `llvm::StringRef`. Much of the string parsing can
be cleaned up, but I tried to keep the changes a small as possible so
just kept the logic and replaced the APIs calls. The only awkward
side-effect of this is that we have to pass a `llvm::StringRef &`
around.

There were some gaps in the API, so added two helper methods to consume/pop off 
characters from the front of the StringRef (maybe those can be added to 
`llvm::StringRef` in the future).

The `StringLexer` also had a roll-back mechanism used in two places.
That can be handled by just saving a copy of the `StringRef`.
---
 .../lldb/DataFormatters/FormattersContainer.h |  18 +--
 lldb/include/lldb/Utility/StringLexer.h       |  56 -------
 .../AppleObjCTypeEncodingParser.cpp           | 106 ++++++++-----
 .../AppleObjCTypeEncodingParser.h             |  21 ++-
 lldb/source/Utility/CMakeLists.txt            |   1 -
 lldb/source/Utility/StringLexer.cpp           |  85 -----------
 lldb/unittests/Utility/CMakeLists.txt         |   1 -
 lldb/unittests/Utility/StringLexerTest.cpp    | 140 ------------------
 8 files changed, 84 insertions(+), 344 deletions(-)
 delete mode 100644 lldb/include/lldb/Utility/StringLexer.h
 delete mode 100644 lldb/source/Utility/StringLexer.cpp
 delete mode 100644 lldb/unittests/Utility/StringLexerTest.cpp

diff --git a/lldb/include/lldb/DataFormatters/FormattersContainer.h 
b/lldb/include/lldb/DataFormatters/FormattersContainer.h
index f7465fc65538d..0761dcfcb12ea 100644
--- a/lldb/include/lldb/DataFormatters/FormattersContainer.h
+++ b/lldb/include/lldb/DataFormatters/FormattersContainer.h
@@ -23,7 +23,6 @@
 #include "lldb/DataFormatters/TypeSynthetic.h"
 #include "lldb/Symbol/CompilerType.h"
 #include "lldb/Utility/RegularExpression.h"
-#include "lldb/Utility/StringLexer.h"
 #include "lldb/ValueObject/ValueObject.h"
 
 namespace lldb_private {
@@ -59,18 +58,15 @@ class TypeMatcher {
     if (type.IsEmpty())
       return type;
 
-    std::string type_cstr(type.AsCString());
-    StringLexer type_lexer(type_cstr);
+    llvm::StringRef type_lexer(type.AsCString());
 
-    type_lexer.AdvanceIf("class ");
-    type_lexer.AdvanceIf("enum ");
-    type_lexer.AdvanceIf("struct ");
-    type_lexer.AdvanceIf("union ");
+    type_lexer.consume_front("class ");
+    type_lexer.consume_front("enum ");
+    type_lexer.consume_front("struct ");
+    type_lexer.consume_front("union ");
+    type_lexer = type_lexer.ltrim();
 
-    while (type_lexer.NextIf({' ', '\t', '\v', '\f'}).first)
-      ;
-
-    return ConstString(type_lexer.GetUnlexed());
+    return ConstString(type_lexer);
   }
 
 public:
diff --git a/lldb/include/lldb/Utility/StringLexer.h 
b/lldb/include/lldb/Utility/StringLexer.h
deleted file mode 100644
index 52f98e860da2b..0000000000000
--- a/lldb/include/lldb/Utility/StringLexer.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===-- StringLexer.h -------------------------------------------*- C++ 
-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_UTILITY_STRINGLEXER_H
-#define LLDB_UTILITY_STRINGLEXER_H
-
-#include <initializer_list>
-#include <string>
-#include <utility>
-
-namespace lldb_private {
-
-class StringLexer {
-public:
-  typedef std::string::size_type Position;
-  typedef std::string::size_type Size;
-
-  typedef std::string::value_type Character;
-
-  StringLexer(std::string s);
-
-  // These APIs are not bounds-checked.  Use HasAtLeast() if you're not sure.
-  Character Peek();
-
-  bool NextIf(Character c);
-
-  std::pair<bool, Character> NextIf(std::initializer_list<Character> cs);
-
-  bool AdvanceIf(const std::string &token);
-
-  Character Next();
-
-  bool HasAtLeast(Size s);
-
-  std::string GetUnlexed();
-
-  // This will assert if there are less than s characters preceding the cursor.
-  void PutBack(Size s);
-
-  StringLexer &operator=(const StringLexer &rhs);
-
-private:
-  std::string m_data;
-  Position m_position;
-
-  void Consume();
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_UTILITY_STRINGLEXER_H
diff --git 
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
 
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index f29a876ba2f24..b4dbb2a86d364 100644
--- 
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ 
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -15,13 +15,29 @@
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
-#include "lldb/Utility/StringLexer.h"
 
 #include "clang/Basic/TargetInfo.h"
 
 #include <optional>
 #include <vector>
 
+static char popChar(llvm::StringRef &str) {
+  const char c = str.front();
+
+  str = str.drop_front();
+
+  return c;
+}
+
+static bool consumeChar(llvm::StringRef &str, char c) {
+  if (!str.starts_with('c'))
+    return false;
+
+  str = str.drop_front();
+
+  return true;
+}
+
 using namespace lldb_private;
 
 AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser(
@@ -35,31 +51,35 @@ AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser(
       runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple());
 }
 
-std::string AppleObjCTypeEncodingParser::ReadStructName(StringLexer &type) {
+std::string AppleObjCTypeEncodingParser::ReadStructName(llvm::StringRef &type) 
{
   StreamString buffer;
-  while (type.HasAtLeast(1) && type.Peek() != '=')
-    buffer.Printf("%c", type.Next());
+  while (!type.empty() && type.front() != '=')
+    buffer.Printf("%c", popChar(type));
+
   return std::string(buffer.GetString());
 }
 
 std::optional<std::string>
-AppleObjCTypeEncodingParser::ReadQuotedString(StringLexer &type) {
-  if (!type.HasAtLeast(1))
+AppleObjCTypeEncodingParser::ReadQuotedString(llvm::StringRef &type) {
+  if (type.empty())
     return std::nullopt;
 
   StreamString buffer;
-  while (type.Peek() != '"') {
-    buffer.Printf("%c", type.Next());
-    if (!type.HasAtLeast(1))
+  while (type.front() != '"') {
+    buffer.Printf("%c", popChar(type));
+
+    if (type.empty())
       return std::nullopt;
   }
   return std::string(buffer.GetString());
 }
 
-uint32_t AppleObjCTypeEncodingParser::ReadNumber(StringLexer &type) {
+uint32_t AppleObjCTypeEncodingParser::ReadNumber(llvm::StringRef &type) {
   uint32_t total = 0;
-  while (type.HasAtLeast(1) && isdigit(type.Peek()))
-    total = 10 * total + (type.Next() - '0');
+  while (!type.empty() && isdigit(type.front())) {
+    total = 10 * total + (type.front() - '0');
+    type = type.drop_front();
+  }
   return total;
 }
 
@@ -72,10 +92,10 @@ AppleObjCTypeEncodingParser::StructElement::StructElement()
 
 AppleObjCTypeEncodingParser::StructElement
 AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx,
-                                               StringLexer &type,
+                                               llvm::StringRef &type,
                                                bool for_expression) {
   StructElement retval;
-  if (type.NextIf('"')) {
+  if (type.consume_front("\"")) {
     if (auto maybe_name = ReadQuotedString(type))
       retval.name = *maybe_name;
     else
@@ -88,22 +108,23 @@ 
AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx,
 }
 
 clang::QualType AppleObjCTypeEncodingParser::BuildStruct(
-    TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
+    TypeSystemClang &ast_ctx, llvm::StringRef &type, bool for_expression) {
   return BuildAggregate(ast_ctx, type, for_expression, _C_STRUCT_B, 
_C_STRUCT_E,
                         llvm::to_underlying(clang::TagTypeKind::Struct));
 }
 
 clang::QualType AppleObjCTypeEncodingParser::BuildUnion(
-    TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
+    TypeSystemClang &ast_ctx, llvm::StringRef &type, bool for_expression) {
   return BuildAggregate(ast_ctx, type, for_expression, _C_UNION_B, _C_UNION_E,
                         llvm::to_underlying(clang::TagTypeKind::Union));
 }
 
 clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
-    TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression,
+    TypeSystemClang &ast_ctx, llvm::StringRef &type, bool for_expression,
     char opener, char closer, uint32_t kind) {
-  if (!type.NextIf(opener))
+  if (!consumeChar(type, opener))
     return clang::QualType();
+
   std::string name(ReadStructName(type));
 
   // We do not handle templated classes/structs at the moment. If the name has
@@ -112,12 +133,12 @@ clang::QualType 
AppleObjCTypeEncodingParser::BuildAggregate(
 
   const bool is_templated = name.find('<') != std::string::npos;
 
-  if (!type.NextIf('='))
+  if (!type.consume_front("="))
     return clang::QualType();
   bool in_union = true;
   std::vector<StructElement> elements;
-  while (in_union && type.HasAtLeast(1)) {
-    if (type.NextIf(closer)) {
+  while (in_union && !type.empty()) {
+    if (consumeChar(type, closer)) {
       in_union = false;
       break;
     } else {
@@ -158,13 +179,15 @@ clang::QualType 
AppleObjCTypeEncodingParser::BuildAggregate(
 }
 
 clang::QualType AppleObjCTypeEncodingParser::BuildArray(
-    TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
-  if (!type.NextIf(_C_ARY_B))
+    TypeSystemClang &ast_ctx, llvm::StringRef &type, bool for_expression) {
+  if (!consumeChar(type, _C_ARY_B))
     return clang::QualType();
+
   uint32_t size = ReadNumber(type);
   clang::QualType element_type(BuildType(ast_ctx, type, for_expression));
-  if (!type.NextIf(_C_ARY_E))
+  if (!consumeChar(type, _C_ARY_E))
     return clang::QualType();
+
   CompilerType array_type(ast_ctx.CreateArrayType(
       CompilerType(ast_ctx.weak_from_this(), element_type.getAsOpaquePtr()),
       size, false));
@@ -177,15 +200,15 @@ clang::QualType AppleObjCTypeEncodingParser::BuildArray(
 // consume but ignore the type info and always return an 'id'; if anything,
 // dynamic typing will resolve things for us anyway
 clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
-    TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression) {
-  if (!type.NextIf(_C_ID))
+    TypeSystemClang &clang_ast_ctx, llvm::StringRef &type, bool 
for_expression) {
+  if (!consumeChar(type, _C_ID))
     return clang::QualType();
 
   clang::ASTContext &ast_ctx = clang_ast_ctx.getASTContext();
 
   std::string name;
 
-  if (type.NextIf('"')) {
+  if (type.consume_front("\"")) {
     // We have to be careful here.  We're used to seeing
     //   @"NSString"
     // but in records it is possible that the string following an @ is the name
@@ -205,17 +228,18 @@ clang::QualType 
AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
     // quoted string is a class name. - If we see anything else, the quoted
     // string is a field name and we push it back onto type.
 
+    // Save a copy for possible rollback.
+    llvm::StringRef backup = type;
     if (auto maybe_name = ReadQuotedString(type))
       name = *maybe_name;
     else
       return clang::QualType();
 
-    if (type.HasAtLeast(1)) {
-      switch (type.Peek()) {
+    if (!type.empty()) {
+      switch (type.front()) {
       default:
-        // roll back
-        type.PutBack(name.length() +
-                     2); // undo our consumption of the string and of the 
quotes
+        // roll back: undo our consumption of the string and of the quotes
+        type = backup;
         name.clear();
         break;
       case _C_STRUCT_E:
@@ -265,14 +289,14 @@ clang::QualType 
AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
 
 clang::QualType
 AppleObjCTypeEncodingParser::BuildType(TypeSystemClang &clang_ast_ctx,
-                                       StringLexer &type, bool for_expression,
+                                       llvm::StringRef &type, bool 
for_expression,
                                        uint32_t *bitfield_bit_size) {
-  if (!type.HasAtLeast(1))
+  if (type.empty())
     return clang::QualType();
 
   clang::ASTContext &ast_ctx = clang_ast_ctx.getASTContext();
 
-  switch (type.Peek()) {
+  switch (type.front()) {
   default:
     break;
   case _C_STRUCT_B:
@@ -285,9 +309,13 @@ AppleObjCTypeEncodingParser::BuildType(TypeSystemClang 
&clang_ast_ctx,
     return BuildObjCObjectPointerType(clang_ast_ctx, type, for_expression);
   }
 
-  switch (type.Next()) {
+  // Save a copy for potential rollback.
+  llvm::StringRef backup = type;
+  type = type.drop_front();
+
+  switch (type.front()) {
   default:
-    type.PutBack(1);
+    type = backup;
     return clang::QualType();
   case _C_CHR:
     return ast_ctx.CharTy;
@@ -347,7 +375,7 @@ AppleObjCTypeEncodingParser::BuildType(TypeSystemClang 
&clang_ast_ctx,
       return ast_ctx.getConstType(target_type);
   }
   case _C_PTR: {
-    if (!for_expression && type.NextIf(_C_UNDEF)) {
+    if (!for_expression && consumeChar(type, _C_UNDEF)) {
       // if we are not supporting the concept of unknownAny, but what is being
       // created here is an unknownAny*, then we can just get away with a void*
       // this is theoretically wrong (in the same sense as 'theoretically
@@ -374,7 +402,7 @@ CompilerType 
AppleObjCTypeEncodingParser::RealizeType(TypeSystemClang &ast_ctx,
                                                       const char *name,
                                                       bool for_expression) {
   if (name && name[0]) {
-    StringLexer lexer(name);
+    llvm::StringRef lexer(name);
     clang::QualType qual_type = BuildType(ast_ctx, lexer, for_expression);
     return ast_ctx.GetType(qual_type);
   }
diff --git 
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
 
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
index 3058514f38ba1..c207fc6f99bf3 100644
--- 
a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
+++ 
b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
@@ -16,7 +16,6 @@
 #include "clang/AST/ASTContext.h"
 
 namespace lldb_private {
-class StringLexer;
 class AppleObjCTypeEncodingParser : public ObjCLanguageRuntime::EncodingToType 
{
 public:
   AppleObjCTypeEncodingParser(ObjCLanguageRuntime &runtime);
@@ -35,35 +34,35 @@ class AppleObjCTypeEncodingParser : public 
ObjCLanguageRuntime::EncodingToType {
     ~StructElement() = default;
   };
 
-  clang::QualType BuildType(TypeSystemClang &clang_ast_ctx, StringLexer &type,
+  clang::QualType BuildType(TypeSystemClang &clang_ast_ctx, llvm::StringRef 
&type,
                             bool for_expression,
                             uint32_t *bitfield_bit_size = nullptr);
 
-  clang::QualType BuildStruct(TypeSystemClang &ast_ctx, StringLexer &type,
+  clang::QualType BuildStruct(TypeSystemClang &ast_ctx, llvm::StringRef &type,
                               bool for_expression);
 
   clang::QualType BuildAggregate(TypeSystemClang &clang_ast_ctx,
-                                 StringLexer &type, bool for_expression,
+                                 llvm::StringRef &type, bool for_expression,
                                  char opener, char closer, uint32_t kind);
 
-  clang::QualType BuildUnion(TypeSystemClang &ast_ctx, StringLexer &type,
+  clang::QualType BuildUnion(TypeSystemClang &ast_ctx, llvm::StringRef &type,
                              bool for_expression);
 
-  clang::QualType BuildArray(TypeSystemClang &ast_ctx, StringLexer &type,
+  clang::QualType BuildArray(TypeSystemClang &ast_ctx, llvm::StringRef &type,
                              bool for_expression);
 
-  std::string ReadStructName(StringLexer &type);
+  std::string ReadStructName(llvm::StringRef &type);
 
-  StructElement ReadStructElement(TypeSystemClang &ast_ctx, StringLexer &type,
+  StructElement ReadStructElement(TypeSystemClang &ast_ctx, llvm::StringRef 
&type,
                                   bool for_expression);
 
   clang::QualType BuildObjCObjectPointerType(TypeSystemClang &clang_ast_ctx,
-                                             StringLexer &type,
+                                             llvm::StringRef &type,
                                              bool for_expression);
 
-  uint32_t ReadNumber(StringLexer &type);
+  uint32_t ReadNumber(llvm::StringRef &type);
 
-  std::optional<std::string> ReadQuotedString(StringLexer &type);
+  std::optional<std::string> ReadQuotedString(llvm::StringRef &type);
 
   ObjCLanguageRuntime &m_runtime;
 };
diff --git a/lldb/source/Utility/CMakeLists.txt 
b/lldb/source/Utility/CMakeLists.txt
index 80b53f8c098d2..04f1692e53b35 100644
--- a/lldb/source/Utility/CMakeLists.txt
+++ b/lldb/source/Utility/CMakeLists.txt
@@ -63,7 +63,6 @@ add_lldb_library(lldbUtility NO_INTERNAL_DEPENDENCIES
   StreamString.cpp
   StringExtractor.cpp
   StringExtractorGDBRemote.cpp
-  StringLexer.cpp
   StringList.cpp
   StructuredData.cpp
   TildeExpressionResolver.cpp
diff --git a/lldb/source/Utility/StringLexer.cpp 
b/lldb/source/Utility/StringLexer.cpp
deleted file mode 100644
index bda6e25ce7a35..0000000000000
--- a/lldb/source/Utility/StringLexer.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-//===-- StringLexer.cpp 
---------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Utility/StringLexer.h"
-
-#include <algorithm>
-#include <cassert>
-#include <utility>
-
-using namespace lldb_private;
-
-StringLexer::StringLexer(std::string s) : m_data(std::move(s)), m_position(0) 
{}
-
-StringLexer::Character StringLexer::Peek() { return m_data[m_position]; }
-
-bool StringLexer::NextIf(Character c) {
-  auto val = Peek();
-  if (val == c) {
-    Next();
-    return true;
-  }
-  return false;
-}
-
-std::pair<bool, StringLexer::Character>
-StringLexer::NextIf(std::initializer_list<Character> cs) {
-  auto val = Peek();
-  for (auto c : cs) {
-    if (val == c) {
-      Next();
-      return {true, c};
-    }
-  }
-  return {false, 0};
-}
-
-bool StringLexer::AdvanceIf(const std::string &token) {
-  auto pos = m_position;
-  bool matches = true;
-  for (auto c : token) {
-    if (!NextIf(c)) {
-      matches = false;
-      break;
-    }
-  }
-  if (!matches) {
-    m_position = pos;
-    return false;
-  }
-  return true;
-}
-
-StringLexer::Character StringLexer::Next() {
-  auto val = Peek();
-  Consume();
-  return val;
-}
-
-bool StringLexer::HasAtLeast(Size s) {
-  return (m_data.size() - m_position) >= s;
-}
-
-void StringLexer::PutBack(Size s) {
-  assert(m_position >= s);
-  m_position -= s;
-}
-
-std::string StringLexer::GetUnlexed() {
-  return std::string(m_data, m_position);
-}
-
-void StringLexer::Consume() { m_position++; }
-
-StringLexer &StringLexer::operator=(const StringLexer &rhs) {
-  if (this != &rhs) {
-    m_data = rhs.m_data;
-    m_position = rhs.m_position;
-  }
-  return *this;
-}
diff --git a/lldb/unittests/Utility/CMakeLists.txt 
b/lldb/unittests/Utility/CMakeLists.txt
index 4cbe15bb5b073..25f21ab4d478d 100644
--- a/lldb/unittests/Utility/CMakeLists.txt
+++ b/lldb/unittests/Utility/CMakeLists.txt
@@ -34,7 +34,6 @@ add_lldb_unittest(UtilityTests
   StreamTest.cpp
   StringExtractorGDBRemoteTest.cpp
   StringExtractorTest.cpp
-  StringLexerTest.cpp
   StringListTest.cpp
   StructuredDataTest.cpp
   SubsystemRAIITest.cpp
diff --git a/lldb/unittests/Utility/StringLexerTest.cpp 
b/lldb/unittests/Utility/StringLexerTest.cpp
deleted file mode 100644
index f7a81bddceae1..0000000000000
--- a/lldb/unittests/Utility/StringLexerTest.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-//===-- StringLexerTest.cpp 
-----------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Utility/StringLexer.h"
-#include "gtest/gtest.h"
-
-using namespace lldb_private;
-
-TEST(StringLexerTest, GetUnlexed) {
-  StringLexer l("foo");
-  EXPECT_EQ("foo", l.GetUnlexed());
-  l.Next();
-  EXPECT_EQ("oo", l.GetUnlexed());
-  l.Next();
-  l.Next();
-  EXPECT_EQ("", l.GetUnlexed());
-}
-
-TEST(StringLexerTest, HasAtLeast) {
-  StringLexer l("foo");
-  EXPECT_FALSE(l.HasAtLeast(5));
-  EXPECT_FALSE(l.HasAtLeast(4));
-  EXPECT_TRUE(l.HasAtLeast(3));
-  EXPECT_TRUE(l.HasAtLeast(2));
-  EXPECT_TRUE(l.HasAtLeast(1));
-
-  l.Next();
-  EXPECT_FALSE(l.HasAtLeast(5));
-  EXPECT_FALSE(l.HasAtLeast(4));
-  EXPECT_FALSE(l.HasAtLeast(3));
-  EXPECT_TRUE(l.HasAtLeast(2));
-  EXPECT_TRUE(l.HasAtLeast(1));
-
-  l.Next();
-  l.Next();
-  EXPECT_FALSE(l.HasAtLeast(5));
-  EXPECT_FALSE(l.HasAtLeast(4));
-  EXPECT_FALSE(l.HasAtLeast(3));
-  EXPECT_FALSE(l.HasAtLeast(2));
-  EXPECT_FALSE(l.HasAtLeast(1));
-}
-
-TEST(StringLexerTest, AdvanceIf) {
-  StringLexer l("foobar");
-
-  EXPECT_FALSE(l.AdvanceIf("oo"));
-  // Skip the "fo" part.
-  EXPECT_TRUE(l.AdvanceIf("fo"));
-  EXPECT_FALSE(l.AdvanceIf("obarz"));
-  // Skip the remaining string.
-  EXPECT_TRUE(l.AdvanceIf("obar"));
-
-  EXPECT_FALSE(l.AdvanceIf("obarz"));
-  EXPECT_FALSE(l.AdvanceIf("foo"));
-  EXPECT_FALSE(l.AdvanceIf("o"));
-  EXPECT_FALSE(l.AdvanceIf(" "));
-}
-
-TEST(StringLexerTest, PutBack) {
-  StringLexer l("foo");
-
-  l.Next();
-  l.PutBack(1);
-  EXPECT_EQ("foo", l.GetUnlexed());
-
-  l.Next();
-  l.Next();
-  l.Next();
-  l.PutBack(2);
-  EXPECT_EQ("oo", l.GetUnlexed());
-
-  l.PutBack(1);
-  EXPECT_EQ("foo", l.GetUnlexed());
-}
-
-TEST(StringLexerTest, Peek) {
-  StringLexer l("foo");
-
-  EXPECT_EQ('f', l.Peek());
-  l.Next();
-  EXPECT_EQ('o', l.Peek());
-  l.Next();
-  EXPECT_EQ('o', l.Peek());
-}
-
-TEST(StringLexerTest, Next) {
-  StringLexer l("foo");
-  EXPECT_EQ('f', l.Next());
-  EXPECT_EQ('o', l.Next());
-  EXPECT_EQ('o', l.Next());
-}
-
-TEST(StringLexerTest, NextIf) {
-  StringLexer l("foo");
-
-  EXPECT_FALSE(l.NextIf('\0'));
-  EXPECT_FALSE(l.NextIf(' '));
-  EXPECT_FALSE(l.NextIf('o'));
-
-  EXPECT_TRUE(l.NextIf('f'));
-
-  EXPECT_FALSE(l.NextIf('\0'));
-  EXPECT_FALSE(l.NextIf(' '));
-  EXPECT_FALSE(l.NextIf('f'));
-
-  EXPECT_TRUE(l.NextIf('o'));
-
-  EXPECT_FALSE(l.NextIf('\0'));
-  EXPECT_FALSE(l.NextIf(' '));
-  EXPECT_FALSE(l.NextIf('f'));
-
-  EXPECT_TRUE(l.NextIf('o'));
-}
-
-TEST(StringLexerTest, NextIfList) {
-  StringLexer l("foo");
-
-  EXPECT_FALSE(l.NextIf({'\0', ' ', 'o'}).first);
-
-  auto r = l.NextIf({'f'});
-  EXPECT_TRUE(r.first);
-  EXPECT_EQ('f', r.second);
-
-  EXPECT_FALSE(l.NextIf({'\0', ' ', 'f'}).first);
-
-  r = l.NextIf({'f', 'o'});
-  EXPECT_TRUE(r.first);
-  EXPECT_EQ('o', r.second);
-
-  EXPECT_FALSE(l.NextIf({'\0', ' ', 'f'}).first);
-
-  r = l.NextIf({'*', 'f', 'o', 'o'});
-  EXPECT_TRUE(r.first);
-  EXPECT_EQ('o', r.second);
-}

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to