1515#include " lldb/Target/Target.h"
1616#include " lldb/Utility/LLDBLog.h"
1717#include " lldb/Utility/Log.h"
18- #include " lldb/Utility/StringLexer.h"
1918
2019#include " clang/Basic/TargetInfo.h"
2120
2221#include < optional>
2322#include < vector>
2423
24+ static char popChar (llvm::StringRef &str) {
25+ const char c = str.front ();
26+
27+ str = str.drop_front ();
28+
29+ return c;
30+ }
31+
32+ static bool consumeChar (llvm::StringRef &str, char c) {
33+ if (!str.starts_with (c))
34+ return false ;
35+
36+ str = str.drop_front ();
37+
38+ return true ;
39+ }
40+
2541using namespace lldb_private ;
2642
2743AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser (
@@ -35,31 +51,33 @@ AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser(
3551 runtime.GetProcess ()->GetTarget ().GetArchitecture ().GetTriple ());
3652}
3753
38- std::string AppleObjCTypeEncodingParser::ReadStructName (StringLexer &type) {
54+ std::string AppleObjCTypeEncodingParser::ReadStructName (llvm::StringRef &type) {
3955 StreamString buffer;
40- while (type.HasAtLeast (1 ) && type.Peek () != ' =' )
41- buffer.Printf (" %c" , type.Next ());
56+ while (!type.empty () && type.front () != ' =' )
57+ buffer.Printf (" %c" , popChar (type));
58+
4259 return std::string (buffer.GetString ());
4360}
4461
4562std::optional<std::string>
46- AppleObjCTypeEncodingParser::ReadQuotedString (StringLexer &type) {
47- if (! type.HasAtLeast ( 1 ))
63+ AppleObjCTypeEncodingParser::ReadQuotedString (llvm::StringRef &type) {
64+ if (type.empty ( ))
4865 return std::nullopt ;
4966
5067 StreamString buffer;
51- while (type.Peek () != ' "' ) {
52- buffer.Printf (" %c" , type.Next ());
53- if (!type.HasAtLeast (1 ))
68+ while (type.front () != ' "' ) {
69+ buffer.Printf (" %c" , popChar (type));
70+
71+ if (type.empty ())
5472 return std::nullopt ;
5573 }
5674 return std::string (buffer.GetString ());
5775}
5876
59- uint32_t AppleObjCTypeEncodingParser::ReadNumber (StringLexer &type) {
77+ uint32_t AppleObjCTypeEncodingParser::ReadNumber (llvm::StringRef &type) {
6078 uint32_t total = 0 ;
61- while (type.HasAtLeast ( 1 ) && isdigit (type.Peek ()))
62- total = 10 * total + (type. Next ( ) - ' 0' );
79+ while (! type.empty ( ) && isdigit (type.front ()))
80+ total = 10 * total + (popChar (type ) - ' 0' );
6381 return total;
6482}
6583
@@ -72,10 +90,10 @@ AppleObjCTypeEncodingParser::StructElement::StructElement()
7290
7391AppleObjCTypeEncodingParser::StructElement
7492AppleObjCTypeEncodingParser::ReadStructElement (TypeSystemClang &ast_ctx,
75- StringLexer &type,
93+ llvm::StringRef &type,
7694 bool for_expression) {
7795 StructElement retval;
78- if (type.NextIf ( ' " ' )) {
96+ if (type.consume_front ( " \" " )) {
7997 if (auto maybe_name = ReadQuotedString (type))
8098 retval.name = *maybe_name;
8199 else
@@ -88,22 +106,23 @@ AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx,
88106}
89107
90108clang::QualType AppleObjCTypeEncodingParser::BuildStruct (
91- TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
109+ TypeSystemClang &ast_ctx, llvm::StringRef &type, bool for_expression) {
92110 return BuildAggregate (ast_ctx, type, for_expression, _C_STRUCT_B, _C_STRUCT_E,
93111 llvm::to_underlying (clang::TagTypeKind::Struct));
94112}
95113
96114clang::QualType AppleObjCTypeEncodingParser::BuildUnion (
97- TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
115+ TypeSystemClang &ast_ctx, llvm::StringRef &type, bool for_expression) {
98116 return BuildAggregate (ast_ctx, type, for_expression, _C_UNION_B, _C_UNION_E,
99117 llvm::to_underlying (clang::TagTypeKind::Union));
100118}
101119
102120clang::QualType AppleObjCTypeEncodingParser::BuildAggregate (
103- TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression,
121+ TypeSystemClang &ast_ctx, llvm::StringRef &type, bool for_expression,
104122 char opener, char closer, uint32_t kind) {
105- if (!type. NextIf ( opener))
123+ if (!consumeChar (type, opener))
106124 return clang::QualType ();
125+
107126 std::string name (ReadStructName (type));
108127
109128 // We do not handle templated classes/structs at the moment. If the name has
@@ -112,12 +131,12 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
112131
113132 const bool is_templated = name.find (' <' ) != std::string::npos;
114133
115- if (!type.NextIf ( ' = ' ))
134+ if (!type.consume_front ( " = " ))
116135 return clang::QualType ();
117136 bool in_union = true ;
118137 std::vector<StructElement> elements;
119- while (in_union && type.HasAtLeast ( 1 )) {
120- if (type. NextIf ( closer)) {
138+ while (in_union && ! type.empty ( )) {
139+ if (consumeChar (type, closer)) {
121140 in_union = false ;
122141 break ;
123142 } else {
@@ -158,13 +177,15 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
158177}
159178
160179clang::QualType AppleObjCTypeEncodingParser::BuildArray (
161- TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) {
162- if (!type. NextIf ( _C_ARY_B))
180+ TypeSystemClang &ast_ctx, llvm::StringRef &type, bool for_expression) {
181+ if (!consumeChar (type, _C_ARY_B))
163182 return clang::QualType ();
183+
164184 uint32_t size = ReadNumber (type);
165185 clang::QualType element_type (BuildType (ast_ctx, type, for_expression));
166- if (!type. NextIf ( _C_ARY_E))
186+ if (!consumeChar (type, _C_ARY_E))
167187 return clang::QualType ();
188+
168189 CompilerType array_type (ast_ctx.CreateArrayType (
169190 CompilerType (ast_ctx.weak_from_this (), element_type.getAsOpaquePtr ()),
170191 size, false ));
@@ -177,15 +198,16 @@ clang::QualType AppleObjCTypeEncodingParser::BuildArray(
177198// consume but ignore the type info and always return an 'id'; if anything,
178199// dynamic typing will resolve things for us anyway
179200clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType (
180- TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression) {
181- if (!type.NextIf (_C_ID))
201+ TypeSystemClang &clang_ast_ctx, llvm::StringRef &type,
202+ bool for_expression) {
203+ if (!consumeChar (type, _C_ID))
182204 return clang::QualType ();
183205
184206 clang::ASTContext &ast_ctx = clang_ast_ctx.getASTContext ();
185207
186208 std::string name;
187209
188- if (type.NextIf ( ' " ' )) {
210+ if (type.consume_front ( " \" " )) {
189211 // We have to be careful here. We're used to seeing
190212 // @"NSString"
191213 // but in records it is possible that the string following an @ is the name
@@ -205,17 +227,18 @@ clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
205227 // quoted string is a class name. - If we see anything else, the quoted
206228 // string is a field name and we push it back onto type.
207229
230+ // Save a copy for possible rollback.
231+ llvm::StringRef backup = type;
208232 if (auto maybe_name = ReadQuotedString (type))
209233 name = *maybe_name;
210234 else
211235 return clang::QualType ();
212236
213- if (type.HasAtLeast ( 1 )) {
214- switch (type.Peek ()) {
237+ if (! type.empty ( )) {
238+ switch (type.front ()) {
215239 default :
216- // roll back
217- type.PutBack (name.length () +
218- 2 ); // undo our consumption of the string and of the quotes
240+ // roll back: undo our consumption of the string and of the quotes
241+ type = backup;
219242 name.clear ();
220243 break ;
221244 case _C_STRUCT_E:
@@ -263,16 +286,15 @@ clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
263286 }
264287}
265288
266- clang::QualType
267- AppleObjCTypeEncodingParser::BuildType (TypeSystemClang &clang_ast_ctx,
268- StringLexer &type, bool for_expression,
269- uint32_t *bitfield_bit_size) {
270- if (!type.HasAtLeast (1 ))
289+ clang::QualType AppleObjCTypeEncodingParser::BuildType (
290+ TypeSystemClang &clang_ast_ctx, llvm::StringRef &type, bool for_expression,
291+ uint32_t *bitfield_bit_size) {
292+ if (type.empty ())
271293 return clang::QualType ();
272294
273295 clang::ASTContext &ast_ctx = clang_ast_ctx.getASTContext ();
274296
275- switch (type.Peek ()) {
297+ switch (type.front ()) {
276298 default :
277299 break ;
278300 case _C_STRUCT_B:
@@ -285,9 +307,12 @@ AppleObjCTypeEncodingParser::BuildType(TypeSystemClang &clang_ast_ctx,
285307 return BuildObjCObjectPointerType (clang_ast_ctx, type, for_expression);
286308 }
287309
288- switch (type.Next ()) {
310+ // Save a copy for potential rollback.
311+ llvm::StringRef backup = type;
312+
313+ switch (popChar (type)) {
289314 default :
290- type. PutBack ( 1 ) ;
315+ type = backup ;
291316 return clang::QualType ();
292317 case _C_CHR:
293318 return ast_ctx.CharTy ;
@@ -347,7 +372,7 @@ AppleObjCTypeEncodingParser::BuildType(TypeSystemClang &clang_ast_ctx,
347372 return ast_ctx.getConstType (target_type);
348373 }
349374 case _C_PTR: {
350- if (!for_expression && type. NextIf ( _C_UNDEF)) {
375+ if (!for_expression && consumeChar (type, _C_UNDEF)) {
351376 // if we are not supporting the concept of unknownAny, but what is being
352377 // created here is an unknownAny*, then we can just get away with a void*
353378 // this is theoretically wrong (in the same sense as 'theoretically
@@ -374,7 +399,7 @@ CompilerType AppleObjCTypeEncodingParser::RealizeType(TypeSystemClang &ast_ctx,
374399 const char *name,
375400 bool for_expression) {
376401 if (name && name[0 ]) {
377- StringLexer lexer (name);
402+ llvm::StringRef lexer (name);
378403 clang::QualType qual_type = BuildType (ast_ctx, lexer, for_expression);
379404 return ast_ctx.GetType (qual_type);
380405 }
0 commit comments