]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r308421, and update
[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 // C Includes
14 // C++ Includes
15
16 // Other libraries and framework includes
17 #include "clang/Lex/Lexer.h"
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21
22 // Project includes
23 #include "lldb/Utility/ConstString.h"
24 #include "lldb/lldb-private.h"
25
26 namespace lldb_private {
27
28 // Helps to validate and obtain various parts of C++ definitions.
29 class CPlusPlusNameParser {
30 public:
31   CPlusPlusNameParser(llvm::StringRef text) : m_text(text) { ExtractTokens(); }
32
33   struct ParsedName {
34     llvm::StringRef basename;
35     llvm::StringRef context;
36   };
37
38   struct ParsedFunction {
39     ParsedName name;
40     llvm::StringRef arguments;
41     llvm::StringRef qualifiers;
42   };
43
44   // Treats given text as a function definition and parses it.
45   // Function definition might or might not have a return type and this should
46   // change parsing result.
47   // Examples:
48   //    main(int, chat const*)
49   //    T fun(int, bool)
50   //    std::vector<int>::push_back(int)
51   //    int& map<int, pair<short, int>>::operator[](short) const
52   //    int (*get_function(const chat *))()
53   llvm::Optional<ParsedFunction> ParseAsFunctionDefinition();
54
55   // Treats given text as a potentially nested name of C++ entity (function,
56   // class, field) and parses it.
57   // Examples:
58   //    main
59   //    fun
60   //    std::vector<int>::push_back
61   //    map<int, pair<short, int>>::operator[]
62   //    func<C>(int, C&)::nested_class::method
63   llvm::Optional<ParsedName> ParseAsFullName();
64
65 private:
66   // A C++ definition to parse.
67   llvm::StringRef m_text;
68   // Tokens extracted from m_text.
69   llvm::SmallVector<clang::Token, 30> m_tokens;
70   // Index of the next token to look at from m_tokens.
71   size_t m_next_token_index = 0;
72
73   // Range of tokens saved in m_next_token_index.
74   struct Range {
75     size_t begin_index = 0;
76     size_t end_index = 0;
77
78     Range() {}
79     Range(size_t begin, size_t end) : begin_index(begin), end_index(end) {
80       assert(end >= begin);
81     }
82
83     size_t size() const { return end_index - begin_index; }
84
85     bool empty() const { return size() == 0; }
86   };
87
88   struct ParsedNameRanges {
89     Range basename_range;
90     Range context_range;
91   };
92
93   // Bookmark automatically restores parsing position (m_next_token_index)
94   // when destructed unless it's manually removed with Remove().
95   class Bookmark {
96   public:
97     Bookmark(size_t &position)
98         : m_position(position), m_position_value(position) {}
99     Bookmark(const Bookmark &) = delete;
100     Bookmark(Bookmark &&b)
101         : m_position(b.m_position), m_position_value(b.m_position_value),
102           m_restore(b.m_restore) {
103       b.Remove();
104     }
105     Bookmark &operator=(Bookmark &&) = delete;
106     Bookmark &operator=(const Bookmark &) = delete;
107
108     void Remove() { m_restore = false; }
109     size_t GetSavedPosition() { return m_position_value; }
110     ~Bookmark() {
111       if (m_restore) {
112         m_position = m_position_value;
113       }
114     }
115
116   private:
117     size_t &m_position;
118     size_t m_position_value;
119     bool m_restore = true;
120   };
121
122   bool HasMoreTokens();
123   void Advance();
124   void TakeBack();
125   bool ConsumeToken(clang::tok::TokenKind kind);
126   template <typename... Ts> bool ConsumeToken(Ts... kinds);
127   Bookmark SetBookmark();
128   size_t GetCurrentPosition();
129   clang::Token &Peek();
130   bool ConsumeBrackets(clang::tok::TokenKind left, clang::tok::TokenKind right);
131
132   llvm::Optional<ParsedFunction> ParseFunctionImpl(bool expect_return_type);
133
134   // Parses functions returning function pointers 'string (*f(int x))(float y)'
135   llvm::Optional<ParsedFunction> ParseFuncPtr(bool expect_return_type);
136
137   // Consumes function arguments enclosed within '(' ... ')'
138   bool ConsumeArguments();
139
140   // Consumes template arguments enclosed within '<' ... '>'
141   bool ConsumeTemplateArgs();
142
143   // Consumes '(anonymous namespace)'
144   bool ConsumeAnonymousNamespace();
145
146   // Consumes '{lambda ...}'
147   bool ConsumeLambda();
148
149   // Consumes operator declaration like 'operator *' or 'operator delete []'
150   bool ConsumeOperator();
151
152   // Skips 'const' and 'volatile'
153   void SkipTypeQualifiers();
154
155   // Skips 'const', 'volatile', '&', '&&' in the end of the function.
156   void SkipFunctionQualifiers();
157
158   // Consumes built-in types like 'int' or 'unsigned long long int'
159   bool ConsumeBuiltinType();
160
161   // Consumes types defined via decltype keyword.
162   bool ConsumeDecltype();
163
164   // Skips 'const' and 'volatile'
165   void SkipPtrsAndRefs();
166
167   // Consumes things like 'const * const &'
168   bool ConsumePtrsAndRefs();
169
170   // Consumes full type name like 'Namespace::Class<int>::Method()::InnerClass'
171   bool ConsumeTypename();
172
173   llvm::Optional<ParsedNameRanges> ParseFullNameImpl();
174   llvm::StringRef GetTextForRange(const Range &range);
175
176   // Populate m_tokens by calling clang lexer on m_text.
177   void ExtractTokens();
178 };
179
180 } // namespace lldb_private
181
182 #endif // liblldb_CPlusPlusNameParser_h_