1 //===-- CPlusPlusNameParser.h -----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_CPlusPlusNameParser_h_
11 #define liblldb_CPlusPlusNameParser_h_
14 #include "clang/Lex/Lexer.h"
15 #include "llvm/ADT/Optional.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringRef.h"
19 #include "lldb/Utility/ConstString.h"
20 #include "lldb/lldb-private.h"
22 namespace lldb_private {
24 // Helps to validate and obtain various parts of C++ definitions.
25 class CPlusPlusNameParser {
27 CPlusPlusNameParser(llvm::StringRef text) : m_text(text) { ExtractTokens(); }
30 llvm::StringRef basename;
31 llvm::StringRef context;
34 struct ParsedFunction {
36 llvm::StringRef arguments;
37 llvm::StringRef qualifiers;
40 // Treats given text as a function definition and parses it.
41 // Function definition might or might not have a return type and this should
42 // change parsing result.
44 // main(int, chat const*)
46 // std::vector<int>::push_back(int)
47 // int& map<int, pair<short, int>>::operator[](short) const
48 // int (*get_function(const chat *))()
49 llvm::Optional<ParsedFunction> ParseAsFunctionDefinition();
51 // Treats given text as a potentially nested name of C++ entity (function,
52 // class, field) and parses it.
56 // std::vector<int>::push_back
57 // map<int, pair<short, int>>::operator[]
58 // func<C>(int, C&)::nested_class::method
59 llvm::Optional<ParsedName> ParseAsFullName();
62 // A C++ definition to parse.
63 llvm::StringRef m_text;
64 // Tokens extracted from m_text.
65 llvm::SmallVector<clang::Token, 30> m_tokens;
66 // Index of the next token to look at from m_tokens.
67 size_t m_next_token_index = 0;
69 // Range of tokens saved in m_next_token_index.
71 size_t begin_index = 0;
75 Range(size_t begin, size_t end) : begin_index(begin), end_index(end) {
79 size_t size() const { return end_index - begin_index; }
81 bool empty() const { return size() == 0; }
84 struct ParsedNameRanges {
89 // Bookmark automatically restores parsing position (m_next_token_index)
90 // when destructed unless it's manually removed with Remove().
93 Bookmark(size_t &position)
94 : m_position(position), m_position_value(position) {}
95 Bookmark(const Bookmark &) = delete;
96 Bookmark(Bookmark &&b)
97 : m_position(b.m_position), m_position_value(b.m_position_value),
98 m_restore(b.m_restore) {
101 Bookmark &operator=(Bookmark &&) = delete;
102 Bookmark &operator=(const Bookmark &) = delete;
104 void Remove() { m_restore = false; }
105 size_t GetSavedPosition() { return m_position_value; }
108 m_position = m_position_value;
114 size_t m_position_value;
115 bool m_restore = true;
118 bool HasMoreTokens();
121 bool ConsumeToken(clang::tok::TokenKind kind);
122 template <typename... Ts> bool ConsumeToken(Ts... kinds);
123 Bookmark SetBookmark();
124 size_t GetCurrentPosition();
125 clang::Token &Peek();
126 bool ConsumeBrackets(clang::tok::TokenKind left, clang::tok::TokenKind right);
128 llvm::Optional<ParsedFunction> ParseFunctionImpl(bool expect_return_type);
130 // Parses functions returning function pointers 'string (*f(int x))(float y)'
131 llvm::Optional<ParsedFunction> ParseFuncPtr(bool expect_return_type);
133 // Consumes function arguments enclosed within '(' ... ')'
134 bool ConsumeArguments();
136 // Consumes template arguments enclosed within '<' ... '>'
137 bool ConsumeTemplateArgs();
139 // Consumes '(anonymous namespace)'
140 bool ConsumeAnonymousNamespace();
142 // Consumes '{lambda ...}'
143 bool ConsumeLambda();
145 // Consumes operator declaration like 'operator *' or 'operator delete []'
146 bool ConsumeOperator();
148 // Skips 'const' and 'volatile'
149 void SkipTypeQualifiers();
151 // Skips 'const', 'volatile', '&', '&&' in the end of the function.
152 void SkipFunctionQualifiers();
154 // Consumes built-in types like 'int' or 'unsigned long long int'
155 bool ConsumeBuiltinType();
157 // Consumes types defined via decltype keyword.
158 bool ConsumeDecltype();
160 // Skips 'const' and 'volatile'
161 void SkipPtrsAndRefs();
163 // Consumes things like 'const * const &'
164 bool ConsumePtrsAndRefs();
166 // Consumes full type name like 'Namespace::Class<int>::Method()::InnerClass'
167 bool ConsumeTypename();
169 llvm::Optional<ParsedNameRanges> ParseFullNameImpl();
170 llvm::StringRef GetTextForRange(const Range &range);
172 // Populate m_tokens by calling clang lexer on m_text.
173 void ExtractTokens();
176 } // namespace lldb_private
178 #endif // liblldb_CPlusPlusNameParser_h_