Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Target/Language.h
Line
Count
Source (jump to first uncovered line)
1
//===-- Language.h ---------------------------------------------------*- C++
2
//-*-===//
3
//
4
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5
// See https://llvm.org/LICENSE.txt for license information.
6
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7
//
8
//===----------------------------------------------------------------------===//
9
10
#ifndef LLDB_TARGET_LANGUAGE_H
11
#define LLDB_TARGET_LANGUAGE_H
12
13
#include <functional>
14
#include <memory>
15
#include <set>
16
#include <vector>
17
18
#include "lldb/Core/Highlighter.h"
19
#include "lldb/Core/PluginInterface.h"
20
#include "lldb/DataFormatters/DumpValueObjectOptions.h"
21
#include "lldb/DataFormatters/FormatClasses.h"
22
#include "lldb/DataFormatters/StringPrinter.h"
23
#include "lldb/Symbol/TypeSystem.h"
24
#include "lldb/lldb-private.h"
25
#include "lldb/lldb-public.h"
26
27
namespace lldb_private {
28
29
class Language : public PluginInterface {
30
public:
31
  class TypeScavenger {
32
  public:
33
    class Result {
34
    public:
35
      virtual bool IsValid() = 0;
36
37
      virtual bool DumpToStream(Stream &stream,
38
                                bool print_help_if_available) = 0;
39
40
25
      virtual ~Result() = default;
41
    };
42
43
    typedef std::set<std::unique_ptr<Result>> ResultSet;
44
45
190
    virtual ~TypeScavenger() = default;
46
47
    size_t Find(ExecutionContextScope *exe_scope, const char *key,
48
                ResultSet &results, bool append = true);
49
50
  protected:
51
190
    TypeScavenger() = default;
52
53
    virtual bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
54
                           ResultSet &results) = 0;
55
  };
56
57
  class ImageListTypeScavenger : public TypeScavenger {
58
    class Result : public Language::TypeScavenger::Result {
59
    public:
60
13
      Result(CompilerType type) : m_compiler_type(type) {}
61
62
26
      bool IsValid() override { return m_compiler_type.IsValid(); }
63
64
13
      bool DumpToStream(Stream &stream, bool print_help_if_available) override {
65
13
        if (IsValid()) {
66
13
          m_compiler_type.DumpTypeDescription(&stream);
67
13
          stream.EOL();
68
13
          return true;
69
13
        }
70
0
        return false;
71
13
      }
72
73
13
      ~Result() override = default;
74
75
    private:
76
      CompilerType m_compiler_type;
77
    };
78
79
  protected:
80
118
    ImageListTypeScavenger() = default;
81
82
118
    ~ImageListTypeScavenger() override = default;
83
84
    // is this type something we should accept? it's usually going to be a
85
    // filter by language + maybe some sugar tweaking
86
    // returning an empty type means rejecting this candidate entirely;
87
    // any other result will be accepted as a valid match
88
    virtual CompilerType AdjustForInclusion(CompilerType &candidate) = 0;
89
90
    bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
91
                   ResultSet &results) override;
92
  };
93
94
  template <typename... ScavengerTypes>
95
  class EitherTypeScavenger : public TypeScavenger {
96
  public:
97
24
    EitherTypeScavenger() : TypeScavenger() {
98
72
      for (std::shared_ptr<TypeScavenger> scavenger : { std::shared_ptr<TypeScavenger>(new ScavengerTypes())... }) {
99
72
        if (scavenger)
100
72
          m_scavengers.push_back(scavenger);
101
72
      }
102
24
    }
103
  protected:
104
    bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
105
24
                   ResultSet &results) override {
106
24
      const bool append = false;
107
57
      for (auto& scavenger : m_scavengers) {
108
57
        if (scavenger && scavenger->Find(exe_scope, key, results, append))
109
15
          return true;
110
57
      }
111
9
      return false;
112
24
    }
113
  private:
114
    std::vector<std::shared_ptr<TypeScavenger>> m_scavengers;
115
  };
116
117
  template <typename... ScavengerTypes>
118
  class UnionTypeScavenger : public TypeScavenger {
119
  public:
120
    UnionTypeScavenger() : TypeScavenger() {
121
      for (std::shared_ptr<TypeScavenger> scavenger : { std::shared_ptr<TypeScavenger>(new ScavengerTypes())... }) {
122
        if (scavenger)
123
          m_scavengers.push_back(scavenger);
124
      }
125
    }
126
  protected:
127
    bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
128
                   ResultSet &results) override {
129
      const bool append = true;
130
      bool success = false;
131
      for (auto& scavenger : m_scavengers) {
132
        if (scavenger)
133
          success = scavenger->Find(exe_scope, key, results, append) || success;
134
      }
135
      return success;
136
    }
137
  private:
138
    std::vector<std::shared_ptr<TypeScavenger>> m_scavengers;
139
  };
140
141
  enum class FunctionNameRepresentation {
142
    eName,
143
    eNameWithArgs,
144
    eNameWithNoArgs
145
  };
146
147
  ~Language() override;
148
149
  static Language *FindPlugin(lldb::LanguageType language);
150
151
  /// Returns the Language associated with the given file path or a nullptr
152
  /// if there is no known language.
153
  static Language *FindPlugin(llvm::StringRef file_path);
154
155
  static Language *FindPlugin(lldb::LanguageType language,
156
                              llvm::StringRef file_path);
157
158
  // return false from callback to stop iterating
159
  static void ForEach(std::function<bool(Language *)> callback);
160
161
  virtual lldb::LanguageType GetLanguageType() const = 0;
162
163
  virtual bool IsTopLevelFunction(Function &function);
164
165
  virtual bool IsSourceFile(llvm::StringRef file_path) const = 0;
166
167
0
  virtual const Highlighter *GetHighlighter() const { return nullptr; }
168
169
  virtual lldb::TypeCategoryImplSP GetFormatters();
170
171
  virtual HardcodedFormatters::HardcodedFormatFinder GetHardcodedFormats();
172
173
  virtual HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries();
174
175
  virtual HardcodedFormatters::HardcodedSyntheticFinder
176
  GetHardcodedSynthetics();
177
178
  virtual std::vector<ConstString>
179
  GetPossibleFormattersMatches(ValueObject &valobj,
180
                               lldb::DynamicValueType use_dynamic);
181
182
  virtual std::unique_ptr<TypeScavenger> GetTypeScavenger();
183
184
  virtual const char *GetLanguageSpecificTypeLookupHelp();
185
186
  class MethodNameVariant {
187
    ConstString m_name;
188
    lldb::FunctionNameType m_type;
189
190
  public:
191
    MethodNameVariant(ConstString name, lldb::FunctionNameType type)
192
10.0M
        : m_name(name), m_type(type) {}
193
10.0M
    ConstString GetName() const { return m_name; }
194
10.9M
    lldb::FunctionNameType GetType() const { return m_type; }
195
  };
196
  // If a language can have more than one possible name for a method, this
197
  // function can be used to enumerate them. This is useful when doing name
198
  // lookups.
199
  virtual std::vector<Language::MethodNameVariant>
200
484M
  GetMethodNameVariants(ConstString method_name) const {
201
484M
    return std::vector<Language::MethodNameVariant>();
202
484M
  };
203
204
  /// Returns true iff the given symbol name is compatible with the mangling
205
  /// scheme of this language.
206
  ///
207
  /// This function should only return true if there is a high confidence
208
  /// that the name actually belongs to this language.
209
118k
  virtual bool SymbolNameFitsToLanguage(Mangled name) const { return false; }
210
211
  // if an individual data formatter can apply to several types and cross a
212
  // language boundary it makes sense for individual languages to want to
213
  // customize the printing of values of that type by appending proper
214
  // prefix/suffix information in language-specific ways
215
  virtual bool GetFormatterPrefixSuffix(ValueObject &valobj,
216
                                        ConstString type_hint,
217
                                        std::string &prefix,
218
                                        std::string &suffix);
219
220
  // if a language has a custom format for printing variable declarations that
221
  // it wants LLDB to honor it should return an appropriate closure here
222
  virtual DumpValueObjectOptions::DeclPrintingHelper GetDeclPrintingHelper();
223
224
  virtual LazyBool IsLogicalTrue(ValueObject &valobj, Status &error);
225
226
  // for a ValueObject of some "reference type", if the value points to the
227
  // nil/null object, this method returns true
228
  virtual bool IsNilReference(ValueObject &valobj);
229
230
  /// Returns the summary string for ValueObjects for which IsNilReference() is
231
  /// true.
232
0
  virtual llvm::StringRef GetNilReferenceSummaryString() { return {}; }
233
234
  // for a ValueObject of some "reference type", if the language provides a
235
  // technique to decide whether the reference has ever been assigned to some
236
  // object, this method will return true if such detection is possible, and if
237
  // the reference has never been assigned
238
  virtual bool IsUninitializedReference(ValueObject &valobj);
239
240
  virtual bool GetFunctionDisplayName(const SymbolContext *sc,
241
                                      const ExecutionContext *exe_ctx,
242
                                      FunctionNameRepresentation representation,
243
                                      Stream &s);
244
245
  virtual ConstString
246
14.3k
  GetDemangledFunctionNameWithoutArguments(Mangled mangled) const {
247
14.3k
    if (ConstString demangled = mangled.GetDemangledName())
248
14.3k
      return demangled;
249
250
0
    return mangled.GetMangledName();
251
14.3k
  }
252
253
  virtual void GetExceptionResolverDescription(bool catch_on, bool throw_on,
254
                                               Stream &s);
255
256
  static void GetDefaultExceptionResolverDescription(bool catch_on,
257
                                                     bool throw_on, Stream &s);
258
259
  // These are accessors for general information about the Languages lldb knows
260
  // about:
261
262
  static lldb::LanguageType
263
  GetLanguageTypeFromString(const char *string) = delete;
264
  static lldb::LanguageType GetLanguageTypeFromString(llvm::StringRef string);
265
266
  static const char *GetNameForLanguageType(lldb::LanguageType language);
267
268
  static void PrintAllLanguages(Stream &s, const char *prefix,
269
                                const char *suffix);
270
271
  // return false from callback to stop iterating
272
  static void ForAllLanguages(std::function<bool(lldb::LanguageType)> callback);
273
274
  static bool LanguageIsCPlusPlus(lldb::LanguageType language);
275
276
  static bool LanguageIsObjC(lldb::LanguageType language);
277
278
  static bool LanguageIsC(lldb::LanguageType language);
279
280
  /// Equivalent to \c LanguageIsC||LanguageIsObjC||LanguageIsCPlusPlus.
281
  static bool LanguageIsCFamily(lldb::LanguageType language);
282
283
  static bool LanguageIsPascal(lldb::LanguageType language);
284
285
  // return the primary language, so if LanguageIsC(l), return eLanguageTypeC,
286
  // etc.
287
  static lldb::LanguageType GetPrimaryLanguage(lldb::LanguageType language);
288
289
  static std::set<lldb::LanguageType> GetSupportedLanguages();
290
291
  static LanguageSet GetLanguagesSupportingTypeSystems();
292
  static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions();
293
  static LanguageSet GetLanguagesSupportingREPLs();
294
295
  // Given a mangled function name, calculates some alternative manglings since
296
  // the compiler mangling may not line up with the symbol we are expecting.
297
  virtual std::vector<ConstString>
298
0
  GenerateAlternateFunctionManglings(const ConstString mangled) const {
299
0
    return std::vector<ConstString>();
300
0
  }
301
302
  virtual ConstString
303
  FindBestAlternateFunctionMangledName(const Mangled mangled,
304
0
                                       const SymbolContext &sym_ctx) const {
305
0
    return ConstString();
306
0
  }
307
308
protected:
309
  // Classes that inherit from Language can see and modify these
310
311
  Language();
312
313
private:
314
  Language(const Language &) = delete;
315
  const Language &operator=(const Language &) = delete;
316
};
317
318
} // namespace lldb_private
319
320
#endif // LLDB_TARGET_LANGUAGE_H