Coverage Report

Created: 2022-01-25 06:29

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