Language.h revision 360784
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 liblldb_Language_h_
11#define liblldb_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
27namespace lldb_private {
28
29class Language : public PluginInterface {
30public:
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      virtual ~Result() = default;
41    };
42
43    typedef std::set<std::unique_ptr<Result>> ResultSet;
44
45    virtual ~TypeScavenger() = default;
46
47    size_t Find(ExecutionContextScope *exe_scope, const char *key,
48                ResultSet &results, bool append = true);
49
50  protected:
51    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      Result(CompilerType type)
61          : Language::TypeScavenger::Result(), m_compiler_type(type) {}
62
63      bool IsValid() override { return m_compiler_type.IsValid(); }
64
65      bool DumpToStream(Stream &stream, bool print_help_if_available) override {
66        if (IsValid()) {
67          m_compiler_type.DumpTypeDescription(&stream);
68          stream.EOL();
69          return true;
70        }
71        return false;
72      }
73
74      ~Result() override = default;
75
76    private:
77      CompilerType m_compiler_type;
78    };
79
80  protected:
81    ImageListTypeScavenger() = default;
82
83    ~ImageListTypeScavenger() override = default;
84
85    // is this type something we should accept? it's usually going to be a
86    // filter by language + maybe some sugar tweaking
87    // returning an empty type means rejecting this candidate entirely;
88    // any other result will be accepted as a valid match
89    virtual CompilerType AdjustForInclusion(CompilerType &candidate) = 0;
90
91    bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
92                   ResultSet &results) override;
93  };
94
95  template <typename... ScavengerTypes>
96  class EitherTypeScavenger : public TypeScavenger {
97  public:
98    EitherTypeScavenger() : TypeScavenger(), m_scavengers() {
99      for (std::shared_ptr<TypeScavenger> scavenger : { std::shared_ptr<TypeScavenger>(new ScavengerTypes())... }) {
100        if (scavenger)
101          m_scavengers.push_back(scavenger);
102      }
103    }
104  protected:
105    bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
106                   ResultSet &results) override {
107      const bool append = false;
108      for (auto& scavenger : m_scavengers) {
109        if (scavenger && scavenger->Find(exe_scope, key, results, append))
110          return true;
111      }
112      return false;
113    }
114  private:
115    std::vector<std::shared_ptr<TypeScavenger>> m_scavengers;
116  };
117
118  template <typename... ScavengerTypes>
119  class UnionTypeScavenger : public TypeScavenger {
120  public:
121    UnionTypeScavenger() : TypeScavenger(), m_scavengers() {
122      for (std::shared_ptr<TypeScavenger> scavenger : { std::shared_ptr<TypeScavenger>(new ScavengerTypes())... }) {
123        if (scavenger)
124          m_scavengers.push_back(scavenger);
125      }
126    }
127  protected:
128    bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
129                   ResultSet &results) override {
130      const bool append = true;
131      bool success = false;
132      for (auto& scavenger : m_scavengers) {
133        if (scavenger)
134          success = scavenger->Find(exe_scope, key, results, append) || success;
135      }
136      return success;
137    }
138  private:
139    std::vector<std::shared_ptr<TypeScavenger>> m_scavengers;
140  };
141
142  enum class FunctionNameRepresentation {
143    eName,
144    eNameWithArgs,
145    eNameWithNoArgs
146  };
147
148  ~Language() override;
149
150  static Language *FindPlugin(lldb::LanguageType language);
151
152  /// Returns the Language associated with the given file path or a nullptr
153  /// if there is no known language.
154  static Language *FindPlugin(llvm::StringRef file_path);
155
156  static Language *FindPlugin(lldb::LanguageType language,
157                              llvm::StringRef file_path);
158
159  // return false from callback to stop iterating
160  static void ForEach(std::function<bool(Language *)> callback);
161
162  virtual lldb::LanguageType GetLanguageType() const = 0;
163
164  virtual bool IsTopLevelFunction(Function &function);
165
166  virtual bool IsSourceFile(llvm::StringRef file_path) const = 0;
167
168  virtual const Highlighter *GetHighlighter() const { return nullptr; }
169
170  virtual lldb::TypeCategoryImplSP GetFormatters();
171
172  virtual HardcodedFormatters::HardcodedFormatFinder GetHardcodedFormats();
173
174  virtual HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries();
175
176  virtual HardcodedFormatters::HardcodedSyntheticFinder
177  GetHardcodedSynthetics();
178
179  virtual std::vector<ConstString>
180  GetPossibleFormattersMatches(ValueObject &valobj,
181                               lldb::DynamicValueType use_dynamic);
182
183  virtual lldb_private::formatters::StringPrinter::EscapingHelper
184      GetStringPrinterEscapingHelper(
185          lldb_private::formatters::StringPrinter::GetPrintableElementType);
186
187  virtual std::unique_ptr<TypeScavenger> GetTypeScavenger();
188
189  virtual const char *GetLanguageSpecificTypeLookupHelp();
190
191  // If a language can have more than one possible name for a method, this
192  // function can be used to enumerate them. This is useful when doing name
193  // lookups.
194  virtual std::vector<ConstString>
195  GetMethodNameVariants(ConstString method_name) const {
196    return std::vector<ConstString>();
197  };
198
199  // if an individual data formatter can apply to several types and cross a
200  // language boundary it makes sense for individual languages to want to
201  // customize the printing of values of that type by appending proper
202  // prefix/suffix information in language-specific ways
203  virtual bool GetFormatterPrefixSuffix(ValueObject &valobj,
204                                        ConstString type_hint,
205                                        std::string &prefix,
206                                        std::string &suffix);
207
208  // if a language has a custom format for printing variable declarations that
209  // it wants LLDB to honor it should return an appropriate closure here
210  virtual DumpValueObjectOptions::DeclPrintingHelper GetDeclPrintingHelper();
211
212  virtual LazyBool IsLogicalTrue(ValueObject &valobj, Status &error);
213
214  // for a ValueObject of some "reference type", if the value points to the
215  // nil/null object, this method returns true
216  virtual bool IsNilReference(ValueObject &valobj);
217
218  // for a ValueObject of some "reference type", if the language provides a
219  // technique to decide whether the reference has ever been assigned to some
220  // object, this method will return true if such detection is possible, and if
221  // the reference has never been assigned
222  virtual bool IsUninitializedReference(ValueObject &valobj);
223
224  virtual bool GetFunctionDisplayName(const SymbolContext *sc,
225                                      const ExecutionContext *exe_ctx,
226                                      FunctionNameRepresentation representation,
227                                      Stream &s);
228
229  virtual void GetExceptionResolverDescription(bool catch_on, bool throw_on,
230                                               Stream &s);
231
232  static void GetDefaultExceptionResolverDescription(bool catch_on,
233                                                     bool throw_on, Stream &s);
234
235  // These are accessors for general information about the Languages lldb knows
236  // about:
237
238  static lldb::LanguageType
239  GetLanguageTypeFromString(const char *string) = delete;
240  static lldb::LanguageType GetLanguageTypeFromString(llvm::StringRef string);
241
242  static const char *GetNameForLanguageType(lldb::LanguageType language);
243
244  static void PrintAllLanguages(Stream &s, const char *prefix,
245                                const char *suffix);
246
247  // return false from callback to stop iterating
248  static void ForAllLanguages(std::function<bool(lldb::LanguageType)> callback);
249
250  static bool LanguageIsCPlusPlus(lldb::LanguageType language);
251
252  static bool LanguageIsObjC(lldb::LanguageType language);
253
254  static bool LanguageIsC(lldb::LanguageType language);
255
256  /// Equivalent to \c LanguageIsC||LanguageIsObjC||LanguageIsCPlusPlus.
257  static bool LanguageIsCFamily(lldb::LanguageType language);
258
259  static bool LanguageIsPascal(lldb::LanguageType language);
260
261  // return the primary language, so if LanguageIsC(l), return eLanguageTypeC,
262  // etc.
263  static lldb::LanguageType GetPrimaryLanguage(lldb::LanguageType language);
264
265  static std::set<lldb::LanguageType> GetSupportedLanguages();
266
267  static LanguageSet GetLanguagesSupportingTypeSystems();
268  static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions();
269  static LanguageSet GetLanguagesSupportingREPLs();
270
271protected:
272  // Classes that inherit from Language can see and modify these
273
274  Language();
275
276private:
277  DISALLOW_COPY_AND_ASSIGN(Language);
278};
279
280} // namespace lldb_private
281
282#endif // liblldb_Language_h_
283