CPlusPlusNameParser.h revision 317027
1130803Smarcel//===-- CPlusPlusNameParser.h -----------------------------------*- C++ -*-===//
2130803Smarcel//
3130803Smarcel//                     The LLVM Compiler Infrastructure
4130803Smarcel//
5130803Smarcel// This file is distributed under the University of Illinois Open Source
6130803Smarcel// License. See LICENSE.TXT for details.
7130803Smarcel//
8130803Smarcel//===----------------------------------------------------------------------===//
9130803Smarcel
10130803Smarcel#ifndef liblldb_CPlusPlusNameParser_h_
11130803Smarcel#define liblldb_CPlusPlusNameParser_h_
12130803Smarcel
13130803Smarcel// C Includes
14130803Smarcel// C++ Includes
15130803Smarcel
16130803Smarcel// Other libraries and framework includes
17130803Smarcel#include "clang/Lex/Lexer.h"
18130803Smarcel#include "llvm/ADT/Optional.h"
19130803Smarcel#include "llvm/ADT/SmallVector.h"
20130803Smarcel#include "llvm/ADT/StringRef.h"
21130803Smarcel
22130803Smarcel// Project includes
23130803Smarcel#include "lldb/Utility/ConstString.h"
24130803Smarcel#include "lldb/lldb-private.h"
25130803Smarcel
26130803Smarcelnamespace lldb_private {
27130803Smarcel
28130803Smarcel// Helps to validate and obtain various parts of C++ definitions.
29130803Smarcelclass CPlusPlusNameParser {
30130803Smarcelpublic:
31130803Smarcel  CPlusPlusNameParser(llvm::StringRef text) : m_text(text) { ExtractTokens(); }
32130803Smarcel
33130803Smarcel  struct ParsedName {
34130803Smarcel    llvm::StringRef basename;
35130803Smarcel    llvm::StringRef context;
36130803Smarcel  };
37130803Smarcel
38130803Smarcel  struct ParsedFunction {
39130803Smarcel    ParsedName name;
40130803Smarcel    llvm::StringRef arguments;
41130803Smarcel    llvm::StringRef qualifiers;
42130803Smarcel  };
43130803Smarcel
44130803Smarcel  // Treats given text as a function definition and parses it.
45130803Smarcel  // Function definition might or might not have a return type and this should
46130803Smarcel  // change parsing result.
47130803Smarcel  // Examples:
48130803Smarcel  //    main(int, chat const*)
49130803Smarcel  //    T fun(int, bool)
50130803Smarcel  //    std::vector<int>::push_back(int)
51130803Smarcel  //    int& map<int, pair<short, int>>::operator[](short) const
52130803Smarcel  //    int (*get_function(const chat *))()
53130803Smarcel  llvm::Optional<ParsedFunction> ParseAsFunctionDefinition();
54130803Smarcel
55130803Smarcel  // Treats given text as a potentially nested name of C++ entity (function,
56130803Smarcel  // class, field) and parses it.
57130803Smarcel  // Examples:
58130803Smarcel  //    main
59130803Smarcel  //    fun
60130803Smarcel  //    std::vector<int>::push_back
61130803Smarcel  //    map<int, pair<short, int>>::operator[]
62130803Smarcel  //    func<C>(int, C&)::nested_class::method
63130803Smarcel  llvm::Optional<ParsedName> ParseAsFullName();
64130803Smarcel
65130803Smarcelprivate:
66130803Smarcel  // A C++ definition to parse.
67130803Smarcel  llvm::StringRef m_text;
68130803Smarcel  // Tokens extracted from m_text.
69130803Smarcel  llvm::SmallVector<clang::Token, 30> m_tokens;
70130803Smarcel  // Index of the next token to look at from m_tokens.
71130803Smarcel  size_t m_next_token_index = 0;
72130803Smarcel
73130803Smarcel  // Range of tokens saved in m_next_token_index.
74130803Smarcel  struct Range {
75130803Smarcel    size_t begin_index = 0;
76130803Smarcel    size_t end_index = 0;
77130803Smarcel
78130803Smarcel    Range() {}
79130803Smarcel    Range(size_t begin, size_t end) : begin_index(begin), end_index(end) {
80130803Smarcel      assert(end >= begin);
81130803Smarcel    }
82130803Smarcel
83130803Smarcel    size_t size() const { return end_index - begin_index; }
84130803Smarcel
85130803Smarcel    bool empty() const { return size() == 0; }
86130803Smarcel  };
87130803Smarcel
88130803Smarcel  struct ParsedNameRanges {
89130803Smarcel    Range basename_range;
90130803Smarcel    Range context_range;
91130803Smarcel  };
92130803Smarcel
93130803Smarcel  // Bookmark automatically restores parsing position (m_next_token_index)
94130803Smarcel  // when destructed unless it's manually removed with Remove().
95130803Smarcel  class Bookmark {
96130803Smarcel  public:
97130803Smarcel    Bookmark(size_t &position)
98130803Smarcel        : m_position(position), m_position_value(position) {}
99130803Smarcel    Bookmark(const Bookmark &) = delete;
100130803Smarcel    Bookmark(Bookmark &&b)
101130803Smarcel        : m_position(b.m_position), m_position_value(b.m_position_value),
102130803Smarcel          m_restore(b.m_restore) {
103130803Smarcel      b.Remove();
104130803Smarcel    }
105130803Smarcel    Bookmark &operator=(Bookmark &&) = delete;
106130803Smarcel    Bookmark &operator=(const Bookmark &) = delete;
107130803Smarcel
108130803Smarcel    void Remove() { m_restore = false; }
109130803Smarcel    size_t GetSavedPosition() { return m_position_value; }
110130803Smarcel    ~Bookmark() {
111130803Smarcel      if (m_restore) {
112130803Smarcel        m_position = m_position_value;
113130803Smarcel      }
114130803Smarcel    }
115130803Smarcel
116130803Smarcel  private:
117130803Smarcel    size_t &m_position;
118130803Smarcel    size_t m_position_value;
119130803Smarcel    bool m_restore = true;
120130803Smarcel  };
121130803Smarcel
122130803Smarcel  bool HasMoreTokens();
123130803Smarcel  void Advance();
124130803Smarcel  void TakeBack();
125130803Smarcel  bool ConsumeToken(clang::tok::TokenKind kind);
126130803Smarcel  template <typename... Ts> bool ConsumeToken(Ts... kinds);
127130803Smarcel  Bookmark SetBookmark();
128130803Smarcel  size_t GetCurrentPosition();
129130803Smarcel  clang::Token &Peek();
130130803Smarcel  bool ConsumeBrackets(clang::tok::TokenKind left, clang::tok::TokenKind right);
131130803Smarcel
132130803Smarcel  llvm::Optional<ParsedFunction> ParseFunctionImpl(bool expect_return_type);
133130803Smarcel
134130803Smarcel  // Parses functions returning function pointers 'string (*f(int x))(float y)'
135130803Smarcel  llvm::Optional<ParsedFunction> ParseFuncPtr(bool expect_return_type);
136130803Smarcel
137130803Smarcel  // Consumes function arguments enclosed within '(' ... ')'
138130803Smarcel  bool ConsumeArguments();
139130803Smarcel
140130803Smarcel  // Consumes template arguments enclosed within '<' ... '>'
141130803Smarcel  bool ConsumeTemplateArgs();
142130803Smarcel
143130803Smarcel  // Consumes '(anonymous namespace)'
144130803Smarcel  bool ConsumeAnonymousNamespace();
145130803Smarcel
146130803Smarcel  // Consumes operator declaration like 'operator *' or 'operator delete []'
147130803Smarcel  bool ConsumeOperator();
148130803Smarcel
149130803Smarcel  // Skips 'const' and 'volatile'
150130803Smarcel  void SkipTypeQualifiers();
151130803Smarcel
152130803Smarcel  // Skips 'const', 'volatile', '&', '&&' in the end of the function.
153130803Smarcel  void SkipFunctionQualifiers();
154130803Smarcel
155130803Smarcel  // Consumes built-in types like 'int' or 'unsigned long long int'
156130803Smarcel  bool ConsumeBuiltinType();
157130803Smarcel
158130803Smarcel  // Consumes types defined via decltype keyword.
159130803Smarcel  bool ConsumeDecltype();
160130803Smarcel
161130803Smarcel  // Skips 'const' and 'volatile'
162130803Smarcel  void SkipPtrsAndRefs();
163130803Smarcel
164130803Smarcel  // Consumes things like 'const * const &'
165130803Smarcel  bool ConsumePtrsAndRefs();
166130803Smarcel
167130803Smarcel  // Consumes full type name like 'Namespace::Class<int>::Method()::InnerClass'
168130803Smarcel  bool ConsumeTypename();
169130803Smarcel
170130803Smarcel  llvm::Optional<ParsedNameRanges> ParseFullNameImpl();
171130803Smarcel  llvm::StringRef GetTextForRange(const Range &range);
172130803Smarcel
173130803Smarcel  // Populate m_tokens by calling clang lexer on m_text.
174130803Smarcel  void ExtractTokens();
175130803Smarcel};
176130803Smarcel
177130803Smarcel} // namespace lldb_private
178130803Smarcel
179130803Smarcel#endif // liblldb_CPlusPlusNameParser_h_
180130803Smarcel