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