LLDB mainline
CPlusPlusNameParser.h
Go to the documentation of this file.
1//===-- CPlusPlusNameParser.h -----------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H
10#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H
11
12#include "clang/Lex/Lexer.h"
13#include "llvm/ADT/SmallVector.h"
14#include "llvm/ADT/StringRef.h"
15
17#include "lldb/lldb-private.h"
18#include <optional>
19
20namespace lldb_private {
21
22// Helps to validate and obtain various parts of C++ definitions.
24public:
25 CPlusPlusNameParser(llvm::StringRef text) : m_text(text) { ExtractTokens(); }
26
27 struct ParsedName {
28 llvm::StringRef basename;
29 llvm::StringRef context;
30 };
31
34 llvm::StringRef arguments;
35 llvm::StringRef qualifiers;
36 llvm::StringRef return_type;
37 };
38
39 // Treats given text as a function definition and parses it.
40 // Function definition might or might not have a return type and this should
41 // change parsing result.
42 // Examples:
43 // main(int, chat const*)
44 // T fun(int, bool)
45 // std::vector<int>::push_back(int)
46 // int& map<int, pair<short, int>>::operator[](short) const
47 // int (*get_function(const chat *))()
48 std::optional<ParsedFunction> ParseAsFunctionDefinition();
49
50 // Treats given text as a potentially nested name of C++ entity (function,
51 // class, field) and parses it.
52 // Examples:
53 // main
54 // fun
55 // std::vector<int>::push_back
56 // map<int, pair<short, int>>::operator[]
57 // func<C>(int, C&)::nested_class::method
58 std::optional<ParsedName> ParseAsFullName();
59
60private:
61 // A C++ definition to parse.
62 llvm::StringRef m_text;
63 // Tokens extracted from m_text.
64 llvm::SmallVector<clang::Token, 30> m_tokens;
65 // Index of the next token to look at from m_tokens.
67
68 // Range of tokens saved in m_next_token_index.
69 struct Range {
70 size_t begin_index = 0;
71 size_t end_index = 0;
72
73 Range() = default;
74 Range(size_t begin, size_t end) : begin_index(begin), end_index(end) {
75 assert(end >= begin);
76 }
77
78 size_t size() const { return end_index - begin_index; }
79
80 bool empty() const { return size() == 0; }
81 };
82
86 };
87
88 // Bookmark automatically restores parsing position (m_next_token_index)
89 // when destructed unless it's manually removed with Remove().
90 class Bookmark {
91 public:
92 Bookmark(size_t &position)
93 : m_position(position), m_position_value(position) {}
94 Bookmark(const Bookmark &) = delete;
98 b.Remove();
99 }
101 Bookmark &operator=(const Bookmark &) = delete;
102
103 void Remove() { m_restore = false; }
106 if (m_restore) {
108 }
109 }
110
111 private:
112 size_t &m_position;
114 bool m_restore = true;
115 };
116
117 bool HasMoreTokens();
118 void Advance();
119 void TakeBack();
120 bool ConsumeToken(clang::tok::TokenKind kind);
121
122 template <typename... Ts> bool ConsumeToken(Ts... kinds);
124 size_t GetCurrentPosition();
125 clang::Token &Peek();
126 bool ConsumeBrackets(clang::tok::TokenKind left, clang::tok::TokenKind right);
127
128 std::optional<ParsedFunction> ParseFunctionImpl(bool expect_return_type);
129
130 // Parses functions returning function pointers 'string (*f(int x))(float y)'
131 std::optional<ParsedFunction> ParseFuncPtr(bool expect_return_type);
132
133 // Consumes function arguments enclosed within '(' ... ')'
134 bool ConsumeArguments();
135
136 // Consumes template arguments enclosed within '<' ... '>'
137 bool ConsumeTemplateArgs();
138
139 // Consumes '(anonymous namespace)'
141
142 // Consumes '{lambda ...}'
143 bool ConsumeLambda();
144
145 // Consumes operator declaration like 'operator *' or 'operator delete []'
146 bool ConsumeOperator();
147
148 // Skips 'const' and 'volatile'
149 void SkipTypeQualifiers();
150
151 // Skips 'const', 'volatile', '&', '&&' in the end of the function.
153
154 // Consumes built-in types like 'int' or 'unsigned long long int'
155 bool ConsumeBuiltinType();
156
157 // Consumes types defined via decltype keyword.
158 bool ConsumeDecltype();
159
160 // Skips 'const' and 'volatile'
161 void SkipPtrsAndRefs();
162
163 // Consumes things like 'const * const &'
164 bool ConsumePtrsAndRefs();
165
166 // Consumes full type name like 'Namespace::Class<int>::Method()::InnerClass'
167 bool ConsumeTypename();
168
169 /// Consumes ABI tags enclosed within '[abi:' ... ']'
170 ///
171 /// Since there is no restriction on what the ABI tag
172 /// string may contain, this API supports parsing a small
173 /// set of special characters.
174 ///
175 /// The following regex describes the set of supported characters:
176 /// [A-Za-z,.\s\d]+
177 bool ConsumeAbiTag();
178
179 std::optional<ParsedNameRanges> ParseFullNameImpl();
180 llvm::StringRef GetTextForRange(const Range &range);
181
182 // Populate m_tokens by calling clang lexer on m_text.
183 void ExtractTokens();
184};
185
186} // namespace lldb_private
187
188#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H
Bookmark & operator=(const Bookmark &)=delete
Bookmark & operator=(Bookmark &&)=delete
std::optional< ParsedNameRanges > ParseFullNameImpl()
bool ConsumeToken(clang::tok::TokenKind kind)
std::optional< ParsedFunction > ParseFunctionImpl(bool expect_return_type)
std::optional< ParsedFunction > ParseAsFunctionDefinition()
std::optional< ParsedName > ParseAsFullName()
bool ConsumeAbiTag()
Consumes ABI tags enclosed within '[abi:' ... ']'.
bool ConsumeBrackets(clang::tok::TokenKind left, clang::tok::TokenKind right)
llvm::StringRef GetTextForRange(const Range &range)
CPlusPlusNameParser(llvm::StringRef text)
std::optional< ParsedFunction > ParseFuncPtr(bool expect_return_type)
llvm::SmallVector< clang::Token, 30 > m_tokens
A class that represents a running process on the host machine.