brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 326efb7 Raw
189 lines · c
1//===-- CPlusPlusNameParser.h -----------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H10#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H11 12#include "clang/Lex/Lexer.h"13#include "llvm/ADT/SmallVector.h"14#include "llvm/ADT/StringRef.h"15 16#include "lldb/Utility/ConstString.h"17#include "lldb/lldb-private.h"18#include <optional>19 20namespace lldb_private {21 22// Helps to validate and obtain various parts of C++ definitions.23class CPlusPlusNameParser {24public:25  CPlusPlusNameParser(llvm::StringRef text) : m_text(text) { ExtractTokens(); }26 27  struct ParsedName {28    llvm::StringRef basename;29    llvm::StringRef context;30  };31 32  struct ParsedFunction {33    ParsedName name;34    llvm::StringRef arguments;35    llvm::StringRef qualifiers;36    llvm::StringRef return_type;37  };38 39  // Treats given text as a function definition and parses it.40  // Function definition might or might not have a return type and this should41  // change parsing result.42  // Examples:43  //    main(int, chat const*)44  //    T fun(int, bool)45  //    std::vector<int>::push_back(int)46  //    int& map<int, pair<short, int>>::operator[](short) const47  //    int (*get_function(const chat *))()48  std::optional<ParsedFunction> ParseAsFunctionDefinition();49 50  // Treats given text as a potentially nested name of C++ entity (function,51  // class, field) and parses it.52  // Examples:53  //    main54  //    fun55  //    std::vector<int>::push_back56  //    map<int, pair<short, int>>::operator[]57  //    func<C>(int, C&)::nested_class::method58  std::optional<ParsedName> ParseAsFullName();59 60private:61  // A C++ definition to parse.62  llvm::StringRef m_text;63  // Tokens extracted from m_text.64  llvm::SmallVector<clang::Token, 30> m_tokens;65  // Index of the next token to look at from m_tokens.66  size_t m_next_token_index = 0;67 68  // Range of tokens saved in m_next_token_index.69  struct Range {70    size_t begin_index = 0;71    size_t end_index = 0;72 73    Range() = default;74    Range(size_t begin, size_t end) : begin_index(begin), end_index(end) {75      assert(end >= begin);76    }77 78    size_t size() const { return end_index - begin_index; }79 80    bool empty() const { return size() == 0; }81  };82 83  struct ParsedNameRanges {84    Range basename_range;85    Range context_range;86  };87 88  // Bookmark automatically restores parsing position (m_next_token_index)89  // when destructed unless it's manually removed with Remove().90  class Bookmark {91  public:92    Bookmark(size_t &position)93        : m_position(position), m_position_value(position) {}94    Bookmark(const Bookmark &) = delete;95    Bookmark(Bookmark &&b)96        : m_position(b.m_position), m_position_value(b.m_position_value),97          m_restore(b.m_restore) {98      b.Remove();99    }100    Bookmark &operator=(Bookmark &&) = delete;101    Bookmark &operator=(const Bookmark &) = delete;102 103    void Remove() { m_restore = false; }104    size_t GetSavedPosition() { return m_position_value; }105    ~Bookmark() {106      if (m_restore) {107        m_position = m_position_value;108      }109    }110 111  private:112    size_t &m_position;113    size_t m_position_value;114    bool m_restore = true;115  };116 117  bool HasMoreTokens();118  void Advance();119  void TakeBack();120  bool ConsumeToken(clang::tok::TokenKind kind);121 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  std::optional<ParsedFunction> ParseFunctionImpl(bool expect_return_type);129 130  // Parses functions returning function pointers 'string (*f(int x))(float y)'131  std::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  /// Consumes ABI tags enclosed within '[abi:' ... ']'170  ///171  /// Since there is no restriction on what the ABI tag172  /// string may contain, this API supports parsing a small173  /// set of special characters.174  ///175  /// The following regex describes the set of supported characters:176  ///   [A-Za-z,.\s\d]+177  bool ConsumeAbiTag();178 179  std::optional<ParsedNameRanges> ParseFullNameImpl();180  llvm::StringRef GetTextForRange(const Range &range);181 182  // Populate m_tokens by calling clang lexer on m_text.183  void ExtractTokens();184};185 186} // namespace lldb_private187 188#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H189