]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Language / CPlusPlus / CPlusPlusNameParser.h
1 //===-- CPlusPlusNameParser.h -----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef liblldb_CPlusPlusNameParser_h_
11 #define liblldb_CPlusPlusNameParser_h_
12
13
14 #include "clang/Lex/Lexer.h"
15 #include "llvm/ADT/Optional.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringRef.h"
18
19 #include "lldb/Utility/ConstString.h"
20 #include "lldb/lldb-private.h"
21
22 namespace lldb_private {
23
24 // Helps to validate and obtain various parts of C++ definitions.
25 class CPlusPlusNameParser {
26 public:
27   CPlusPlusNameParser(llvm::StringRef text) : m_text(text) { ExtractTokens(); }
28
29   struct ParsedName {
30     llvm::StringRef basename;
31     llvm::StringRef context;
32   };
33
34   struct ParsedFunction {
35     ParsedName name;
36     llvm::StringRef arguments;
37     llvm::StringRef qualifiers;
38   };
39
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.
43   // Examples:
44   //    main(int, chat const*)
45   //    T fun(int, bool)
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();
50
51   // Treats given text as a potentially nested name of C++ entity (function,
52   // class, field) and parses it.
53   // Examples:
54   //    main
55   //    fun
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();
60
61 private:
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;
68
69   // Range of tokens saved in m_next_token_index.
70   struct Range {
71     size_t begin_index = 0;
72     size_t end_index = 0;
73
74     Range() {}
75     Range(size_t begin, size_t end) : begin_index(begin), end_index(end) {
76       assert(end >= begin);
77     }
78
79     size_t size() const { return end_index - begin_index; }
80
81     bool empty() const { return size() == 0; }
82   };
83
84   struct ParsedNameRanges {
85     Range basename_range;
86     Range context_range;
87   };
88
89   // Bookmark automatically restores parsing position (m_next_token_index)
90   // when destructed unless it's manually removed with Remove().
91   class Bookmark {
92   public:
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) {
99       b.Remove();
100     }
101     Bookmark &operator=(Bookmark &&) = delete;
102     Bookmark &operator=(const Bookmark &) = delete;
103
104     void Remove() { m_restore = false; }
105     size_t GetSavedPosition() { return m_position_value; }
106     ~Bookmark() {
107       if (m_restore) {
108         m_position = m_position_value;
109       }
110     }
111
112   private:
113     size_t &m_position;
114     size_t m_position_value;
115     bool m_restore = true;
116   };
117
118   bool HasMoreTokens();
119   void Advance();
120   void TakeBack();
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);
127
128   llvm::Optional<ParsedFunction> ParseFunctionImpl(bool expect_return_type);
129
130   // Parses functions returning function pointers 'string (*f(int x))(float y)'
131   llvm::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)'
140   bool ConsumeAnonymousNamespace();
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.
152   void SkipFunctionQualifiers();
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   llvm::Optional<ParsedNameRanges> ParseFullNameImpl();
170   llvm::StringRef GetTextForRange(const Range &range);
171
172   // Populate m_tokens by calling clang lexer on m_text.
173   void ExtractTokens();
174 };
175
176 } // namespace lldb_private
177
178 #endif // liblldb_CPlusPlusNameParser_h_