Language.h 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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. #ifndef LLDB_TARGET_LANGUAGE_H
  10. #define LLDB_TARGET_LANGUAGE_H
  11. #include <functional>
  12. #include <memory>
  13. #include <set>
  14. #include <vector>
  15. #include "lldb/Core/Highlighter.h"
  16. #include "lldb/Core/PluginInterface.h"
  17. #include "lldb/DataFormatters/DumpValueObjectOptions.h"
  18. #include "lldb/DataFormatters/FormatClasses.h"
  19. #include "lldb/DataFormatters/StringPrinter.h"
  20. #include "lldb/Symbol/TypeSystem.h"
  21. #include "lldb/lldb-private.h"
  22. #include "lldb/lldb-public.h"
  23. namespace lldb_private {
  24. class Language : public PluginInterface {
  25. public:
  26. class TypeScavenger {
  27. public:
  28. class Result {
  29. public:
  30. virtual bool IsValid() = 0;
  31. virtual bool DumpToStream(Stream &stream,
  32. bool print_help_if_available) = 0;
  33. virtual ~Result() = default;
  34. };
  35. typedef std::set<std::unique_ptr<Result>> ResultSet;
  36. virtual ~TypeScavenger() = default;
  37. size_t Find(ExecutionContextScope *exe_scope, const char *key,
  38. ResultSet &results, bool append = true);
  39. protected:
  40. TypeScavenger() = default;
  41. virtual bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
  42. ResultSet &results) = 0;
  43. };
  44. class ImageListTypeScavenger : public TypeScavenger {
  45. class Result : public Language::TypeScavenger::Result {
  46. public:
  47. Result(CompilerType type)
  48. : Language::TypeScavenger::Result(), m_compiler_type(type) {}
  49. bool IsValid() override { return m_compiler_type.IsValid(); }
  50. bool DumpToStream(Stream &stream, bool print_help_if_available) override {
  51. if (IsValid()) {
  52. m_compiler_type.DumpTypeDescription(&stream);
  53. stream.EOL();
  54. return true;
  55. }
  56. return false;
  57. }
  58. ~Result() override = default;
  59. private:
  60. CompilerType m_compiler_type;
  61. };
  62. protected:
  63. ImageListTypeScavenger() = default;
  64. ~ImageListTypeScavenger() override = default;
  65. // is this type something we should accept? it's usually going to be a
  66. // filter by language + maybe some sugar tweaking
  67. // returning an empty type means rejecting this candidate entirely;
  68. // any other result will be accepted as a valid match
  69. virtual CompilerType AdjustForInclusion(CompilerType &candidate) = 0;
  70. bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
  71. ResultSet &results) override;
  72. };
  73. template <typename... ScavengerTypes>
  74. class EitherTypeScavenger : public TypeScavenger {
  75. public:
  76. EitherTypeScavenger() : TypeScavenger(), m_scavengers() {
  77. for (std::shared_ptr<TypeScavenger> scavenger : { std::shared_ptr<TypeScavenger>(new ScavengerTypes())... }) {
  78. if (scavenger)
  79. m_scavengers.push_back(scavenger);
  80. }
  81. }
  82. protected:
  83. bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
  84. ResultSet &results) override {
  85. const bool append = false;
  86. for (auto& scavenger : m_scavengers) {
  87. if (scavenger && scavenger->Find(exe_scope, key, results, append))
  88. return true;
  89. }
  90. return false;
  91. }
  92. private:
  93. std::vector<std::shared_ptr<TypeScavenger>> m_scavengers;
  94. };
  95. template <typename... ScavengerTypes>
  96. class UnionTypeScavenger : public TypeScavenger {
  97. public:
  98. UnionTypeScavenger() : 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 = true;
  108. bool success = false;
  109. for (auto& scavenger : m_scavengers) {
  110. if (scavenger)
  111. success = scavenger->Find(exe_scope, key, results, append) || success;
  112. }
  113. return success;
  114. }
  115. private:
  116. std::vector<std::shared_ptr<TypeScavenger>> m_scavengers;
  117. };
  118. enum class FunctionNameRepresentation {
  119. eName,
  120. eNameWithArgs,
  121. eNameWithNoArgs
  122. };
  123. ~Language() override;
  124. static Language *FindPlugin(lldb::LanguageType language);
  125. /// Returns the Language associated with the given file path or a nullptr
  126. /// if there is no known language.
  127. static Language *FindPlugin(llvm::StringRef file_path);
  128. static Language *FindPlugin(lldb::LanguageType language,
  129. llvm::StringRef file_path);
  130. // return false from callback to stop iterating
  131. static void ForEach(std::function<bool(Language *)> callback);
  132. virtual lldb::LanguageType GetLanguageType() const = 0;
  133. virtual bool IsTopLevelFunction(Function &function);
  134. virtual bool IsSourceFile(llvm::StringRef file_path) const = 0;
  135. virtual const Highlighter *GetHighlighter() const { return nullptr; }
  136. virtual lldb::TypeCategoryImplSP GetFormatters();
  137. virtual HardcodedFormatters::HardcodedFormatFinder GetHardcodedFormats();
  138. virtual HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries();
  139. virtual HardcodedFormatters::HardcodedSyntheticFinder
  140. GetHardcodedSynthetics();
  141. virtual std::vector<ConstString>
  142. GetPossibleFormattersMatches(ValueObject &valobj,
  143. lldb::DynamicValueType use_dynamic);
  144. virtual std::unique_ptr<TypeScavenger> GetTypeScavenger();
  145. virtual const char *GetLanguageSpecificTypeLookupHelp();
  146. // If a language can have more than one possible name for a method, this
  147. // function can be used to enumerate them. This is useful when doing name
  148. // lookups.
  149. virtual std::vector<ConstString>
  150. GetMethodNameVariants(ConstString method_name) const {
  151. return std::vector<ConstString>();
  152. };
  153. // if an individual data formatter can apply to several types and cross a
  154. // language boundary it makes sense for individual languages to want to
  155. // customize the printing of values of that type by appending proper
  156. // prefix/suffix information in language-specific ways
  157. virtual bool GetFormatterPrefixSuffix(ValueObject &valobj,
  158. ConstString type_hint,
  159. std::string &prefix,
  160. std::string &suffix);
  161. // if a language has a custom format for printing variable declarations that
  162. // it wants LLDB to honor it should return an appropriate closure here
  163. virtual DumpValueObjectOptions::DeclPrintingHelper GetDeclPrintingHelper();
  164. virtual LazyBool IsLogicalTrue(ValueObject &valobj, Status &error);
  165. // for a ValueObject of some "reference type", if the value points to the
  166. // nil/null object, this method returns true
  167. virtual bool IsNilReference(ValueObject &valobj);
  168. /// Returns the summary string for ValueObjects for which IsNilReference() is
  169. /// true.
  170. virtual llvm::StringRef GetNilReferenceSummaryString() { return {}; }
  171. // for a ValueObject of some "reference type", if the language provides a
  172. // technique to decide whether the reference has ever been assigned to some
  173. // object, this method will return true if such detection is possible, and if
  174. // the reference has never been assigned
  175. virtual bool IsUninitializedReference(ValueObject &valobj);
  176. virtual bool GetFunctionDisplayName(const SymbolContext *sc,
  177. const ExecutionContext *exe_ctx,
  178. FunctionNameRepresentation representation,
  179. Stream &s);
  180. virtual void GetExceptionResolverDescription(bool catch_on, bool throw_on,
  181. Stream &s);
  182. static void GetDefaultExceptionResolverDescription(bool catch_on,
  183. bool throw_on, Stream &s);
  184. // These are accessors for general information about the Languages lldb knows
  185. // about:
  186. static lldb::LanguageType
  187. GetLanguageTypeFromString(const char *string) = delete;
  188. static lldb::LanguageType GetLanguageTypeFromString(llvm::StringRef string);
  189. static const char *GetNameForLanguageType(lldb::LanguageType language);
  190. static void PrintAllLanguages(Stream &s, const char *prefix,
  191. const char *suffix);
  192. // return false from callback to stop iterating
  193. static void ForAllLanguages(std::function<bool(lldb::LanguageType)> callback);
  194. static bool LanguageIsCPlusPlus(lldb::LanguageType language);
  195. static bool LanguageIsObjC(lldb::LanguageType language);
  196. static bool LanguageIsC(lldb::LanguageType language);
  197. /// Equivalent to \c LanguageIsC||LanguageIsObjC||LanguageIsCPlusPlus.
  198. static bool LanguageIsCFamily(lldb::LanguageType language);
  199. static bool LanguageIsPascal(lldb::LanguageType language);
  200. // return the primary language, so if LanguageIsC(l), return eLanguageTypeC,
  201. // etc.
  202. static lldb::LanguageType GetPrimaryLanguage(lldb::LanguageType language);
  203. static std::set<lldb::LanguageType> GetSupportedLanguages();
  204. static LanguageSet GetLanguagesSupportingTypeSystems();
  205. static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions();
  206. static LanguageSet GetLanguagesSupportingREPLs();
  207. protected:
  208. // Classes that inherit from Language can see and modify these
  209. Language();
  210. private:
  211. Language(const Language &) = delete;
  212. const Language &operator=(const Language &) = delete;
  213. };
  214. } // namespace lldb_private
  215. #endif // LLDB_TARGET_LANGUAGE_H