Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:53

0001 //===-- Language.h ---------------------------------------------------*- C++
0002 //-*-===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef LLDB_TARGET_LANGUAGE_H
0011 #define LLDB_TARGET_LANGUAGE_H
0012 
0013 #include <functional>
0014 #include <memory>
0015 #include <set>
0016 #include <vector>
0017 
0018 #include "lldb/Core/Highlighter.h"
0019 #include "lldb/Core/PluginInterface.h"
0020 #include "lldb/DataFormatters/DumpValueObjectOptions.h"
0021 #include "lldb/DataFormatters/FormatClasses.h"
0022 #include "lldb/DataFormatters/StringPrinter.h"
0023 #include "lldb/Symbol/TypeSystem.h"
0024 #include "lldb/lldb-private.h"
0025 #include "lldb/lldb-public.h"
0026 
0027 namespace lldb_private {
0028 
0029 class LanguageProperties : public Properties {
0030 public:
0031   LanguageProperties();
0032 
0033   static llvm::StringRef GetSettingName();
0034 
0035   bool GetEnableFilterForLineBreakpoints() const;
0036 };
0037 
0038 class Language : public PluginInterface {
0039 public:
0040   class TypeScavenger {
0041   public:
0042     class Result {
0043     public:
0044       virtual bool IsValid() = 0;
0045 
0046       virtual bool DumpToStream(Stream &stream,
0047                                 bool print_help_if_available) = 0;
0048 
0049       virtual ~Result() = default;
0050     };
0051 
0052     typedef std::set<std::unique_ptr<Result>> ResultSet;
0053 
0054     virtual ~TypeScavenger() = default;
0055 
0056     size_t Find(ExecutionContextScope *exe_scope, const char *key,
0057                 ResultSet &results, bool append = true);
0058 
0059   protected:
0060     TypeScavenger() = default;
0061 
0062     virtual bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
0063                            ResultSet &results) = 0;
0064   };
0065 
0066   class ImageListTypeScavenger : public TypeScavenger {
0067     class Result : public Language::TypeScavenger::Result {
0068     public:
0069       Result(CompilerType type) : m_compiler_type(type) {}
0070 
0071       bool IsValid() override { return m_compiler_type.IsValid(); }
0072 
0073       bool DumpToStream(Stream &stream, bool print_help_if_available) override {
0074         if (IsValid()) {
0075           m_compiler_type.DumpTypeDescription(&stream);
0076           stream.EOL();
0077           return true;
0078         }
0079         return false;
0080       }
0081 
0082       ~Result() override = default;
0083 
0084     private:
0085       CompilerType m_compiler_type;
0086     };
0087 
0088   protected:
0089     ImageListTypeScavenger() = default;
0090 
0091     ~ImageListTypeScavenger() override = default;
0092 
0093     // is this type something we should accept? it's usually going to be a
0094     // filter by language + maybe some sugar tweaking
0095     // returning an empty type means rejecting this candidate entirely;
0096     // any other result will be accepted as a valid match
0097     virtual CompilerType AdjustForInclusion(CompilerType &candidate) = 0;
0098 
0099     bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
0100                    ResultSet &results) override;
0101   };
0102 
0103   template <typename... ScavengerTypes>
0104   class EitherTypeScavenger : public TypeScavenger {
0105   public:
0106     EitherTypeScavenger() : TypeScavenger() {
0107       for (std::shared_ptr<TypeScavenger> scavenger : { std::shared_ptr<TypeScavenger>(new ScavengerTypes())... }) {
0108         if (scavenger)
0109           m_scavengers.push_back(scavenger);
0110       }
0111     }
0112   protected:
0113     bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
0114                    ResultSet &results) override {
0115       const bool append = false;
0116       for (auto& scavenger : m_scavengers) {
0117         if (scavenger && scavenger->Find(exe_scope, key, results, append))
0118           return true;
0119       }
0120       return false;
0121     }
0122   private:
0123     std::vector<std::shared_ptr<TypeScavenger>> m_scavengers;
0124   };
0125 
0126   template <typename... ScavengerTypes>
0127   class UnionTypeScavenger : public TypeScavenger {
0128   public:
0129     UnionTypeScavenger() : TypeScavenger() {
0130       for (std::shared_ptr<TypeScavenger> scavenger : { std::shared_ptr<TypeScavenger>(new ScavengerTypes())... }) {
0131         if (scavenger)
0132           m_scavengers.push_back(scavenger);
0133       }
0134     }
0135   protected:
0136     bool Find_Impl(ExecutionContextScope *exe_scope, const char *key,
0137                    ResultSet &results) override {
0138       const bool append = true;
0139       bool success = false;
0140       for (auto& scavenger : m_scavengers) {
0141         if (scavenger)
0142           success = scavenger->Find(exe_scope, key, results, append) || success;
0143       }
0144       return success;
0145     }
0146   private:
0147     std::vector<std::shared_ptr<TypeScavenger>> m_scavengers;
0148   };
0149 
0150   enum class FunctionNameRepresentation {
0151     eName,
0152     eNameWithArgs,
0153     eNameWithNoArgs
0154   };
0155 
0156   ~Language() override;
0157 
0158   static Language *FindPlugin(lldb::LanguageType language);
0159 
0160   /// Returns the Language associated with the given file path or a nullptr
0161   /// if there is no known language.
0162   static Language *FindPlugin(llvm::StringRef file_path);
0163 
0164   static Language *FindPlugin(lldb::LanguageType language,
0165                               llvm::StringRef file_path);
0166 
0167   // return false from callback to stop iterating
0168   static void ForEach(std::function<bool(Language *)> callback);
0169 
0170   virtual lldb::LanguageType GetLanguageType() const = 0;
0171 
0172   // Implement this function to return the user-defined entry point name
0173   // for the language.
0174   virtual llvm::StringRef GetUserEntryPointName() const { return {}; }
0175 
0176   virtual bool IsTopLevelFunction(Function &function);
0177 
0178   virtual bool IsSourceFile(llvm::StringRef file_path) const = 0;
0179 
0180   virtual const Highlighter *GetHighlighter() const { return nullptr; }
0181 
0182   virtual lldb::TypeCategoryImplSP GetFormatters();
0183 
0184   virtual HardcodedFormatters::HardcodedFormatFinder GetHardcodedFormats();
0185 
0186   virtual HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries();
0187 
0188   virtual HardcodedFormatters::HardcodedSyntheticFinder
0189   GetHardcodedSynthetics();
0190 
0191   virtual std::vector<FormattersMatchCandidate>
0192   GetPossibleFormattersMatches(ValueObject &valobj,
0193                                lldb::DynamicValueType use_dynamic);
0194 
0195   virtual std::unique_ptr<TypeScavenger> GetTypeScavenger();
0196 
0197   virtual const char *GetLanguageSpecificTypeLookupHelp();
0198 
0199   class MethodNameVariant {
0200     ConstString m_name;
0201     lldb::FunctionNameType m_type;
0202 
0203   public:
0204     MethodNameVariant(ConstString name, lldb::FunctionNameType type)
0205         : m_name(name), m_type(type) {}
0206     ConstString GetName() const { return m_name; }
0207     lldb::FunctionNameType GetType() const { return m_type; }
0208   };
0209   // If a language can have more than one possible name for a method, this
0210   // function can be used to enumerate them. This is useful when doing name
0211   // lookups.
0212   virtual std::vector<Language::MethodNameVariant>
0213   GetMethodNameVariants(ConstString method_name) const {
0214     return std::vector<Language::MethodNameVariant>();
0215   };
0216 
0217   /// Returns true iff the given symbol name is compatible with the mangling
0218   /// scheme of this language.
0219   ///
0220   /// This function should only return true if there is a high confidence
0221   /// that the name actually belongs to this language.
0222   virtual bool SymbolNameFitsToLanguage(Mangled name) const { return false; }
0223 
0224   /// An individual data formatter may apply to several types and cross language
0225   /// boundaries. Each of those languages may want to customize the display of
0226   /// values of said types by appending proper prefix/suffix information in
0227   /// language-specific ways. This function returns that prefix and suffix.
0228   ///
0229   /// \param[in] type_hint
0230   ///   A StringRef used to determine what the prefix and suffix should be. It
0231   ///   is called a hint because some types may have multiple variants for which
0232   ///   the prefix and/or suffix may vary.
0233   ///
0234   /// \return
0235   ///   A std::pair<StringRef, StringRef>, the first being the prefix and the
0236   ///   second being the suffix. They may be empty.
0237   virtual std::pair<llvm::StringRef, llvm::StringRef>
0238   GetFormatterPrefixSuffix(llvm::StringRef type_hint);
0239 
0240   // When looking up functions, we take a user provided string which may be a
0241   // partial match to the full demangled name and compare it to the actual
0242   // demangled name to see if it matches as much as the user specified.  An
0243   // example of this is if the user provided A::my_function, but the
0244   // symbol was really B::A::my_function.  We want that to be
0245   // a match.  But we wouldn't want this to match AnotherA::my_function.  The
0246   // user is specifying a truncated path, not a truncated set of characters.
0247   // This function does a language-aware comparison for those purposes.
0248   virtual bool DemangledNameContainsPath(llvm::StringRef path,
0249                                          ConstString demangled) const;
0250 
0251   // if a language has a custom format for printing variable declarations that
0252   // it wants LLDB to honor it should return an appropriate closure here
0253   virtual DumpValueObjectOptions::DeclPrintingHelper GetDeclPrintingHelper();
0254 
0255   virtual LazyBool IsLogicalTrue(ValueObject &valobj, Status &error);
0256 
0257   // for a ValueObject of some "reference type", if the value points to the
0258   // nil/null object, this method returns true
0259   virtual bool IsNilReference(ValueObject &valobj);
0260 
0261   /// Returns the summary string for ValueObjects for which IsNilReference() is
0262   /// true.
0263   virtual llvm::StringRef GetNilReferenceSummaryString() { return {}; }
0264 
0265   // for a ValueObject of some "reference type", if the language provides a
0266   // technique to decide whether the reference has ever been assigned to some
0267   // object, this method will return true if such detection is possible, and if
0268   // the reference has never been assigned
0269   virtual bool IsUninitializedReference(ValueObject &valobj);
0270 
0271   virtual bool GetFunctionDisplayName(const SymbolContext *sc,
0272                                       const ExecutionContext *exe_ctx,
0273                                       FunctionNameRepresentation representation,
0274                                       Stream &s);
0275 
0276   virtual ConstString
0277   GetDemangledFunctionNameWithoutArguments(Mangled mangled) const {
0278     if (ConstString demangled = mangled.GetDemangledName())
0279       return demangled;
0280 
0281     return mangled.GetMangledName();
0282   }
0283 
0284   virtual ConstString GetDisplayDemangledName(Mangled mangled) const {
0285     return mangled.GetDemangledName();
0286   }
0287 
0288   virtual void GetExceptionResolverDescription(bool catch_on, bool throw_on,
0289                                                Stream &s);
0290 
0291   static void GetDefaultExceptionResolverDescription(bool catch_on,
0292                                                      bool throw_on, Stream &s);
0293 
0294   // These are accessors for general information about the Languages lldb knows
0295   // about:
0296 
0297   static lldb::LanguageType
0298   GetLanguageTypeFromString(const char *string) = delete;
0299   static lldb::LanguageType GetLanguageTypeFromString(llvm::StringRef string);
0300 
0301   static const char *GetNameForLanguageType(lldb::LanguageType language);
0302 
0303   static void PrintAllLanguages(Stream &s, const char *prefix,
0304                                 const char *suffix);
0305 
0306   /// Prints to the specified stream 's' each language type that the
0307   /// current target supports for expression evaluation.
0308   ///
0309   /// \param[out] s      Stream to which the language types are written.
0310   /// \param[in]  prefix String that is prepended to the language type.
0311   /// \param[in]  suffix String that is appended to the language type.
0312   static void PrintSupportedLanguagesForExpressions(Stream &s,
0313                                                     llvm::StringRef prefix,
0314                                                     llvm::StringRef suffix);
0315 
0316   // return false from callback to stop iterating
0317   static void ForAllLanguages(std::function<bool(lldb::LanguageType)> callback);
0318 
0319   static bool LanguageIsCPlusPlus(lldb::LanguageType language);
0320 
0321   static bool LanguageIsObjC(lldb::LanguageType language);
0322 
0323   static bool LanguageIsC(lldb::LanguageType language);
0324 
0325   /// Equivalent to \c LanguageIsC||LanguageIsObjC||LanguageIsCPlusPlus.
0326   static bool LanguageIsCFamily(lldb::LanguageType language);
0327 
0328   static bool LanguageIsPascal(lldb::LanguageType language);
0329 
0330   // return the primary language, so if LanguageIsC(l), return eLanguageTypeC,
0331   // etc.
0332   static lldb::LanguageType GetPrimaryLanguage(lldb::LanguageType language);
0333 
0334   static std::set<lldb::LanguageType> GetSupportedLanguages();
0335 
0336   static LanguageSet GetLanguagesSupportingTypeSystems();
0337   static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions();
0338   static LanguageSet GetLanguagesSupportingREPLs();
0339 
0340   static LanguageProperties &GetGlobalLanguageProperties();
0341 
0342   // Given a mangled function name, calculates some alternative manglings since
0343   // the compiler mangling may not line up with the symbol we are expecting.
0344   virtual std::vector<ConstString>
0345   GenerateAlternateFunctionManglings(const ConstString mangled) const {
0346     return std::vector<ConstString>();
0347   }
0348 
0349   virtual ConstString
0350   FindBestAlternateFunctionMangledName(const Mangled mangled,
0351                                        const SymbolContext &sym_ctx) const {
0352     return ConstString();
0353   }
0354 
0355   virtual llvm::StringRef GetInstanceVariableName() { return {}; }
0356 
0357   /// Returns true if this SymbolContext should be ignored when setting
0358   /// breakpoints by line (number or regex). Helpful for languages that create
0359   /// artificial functions without meaningful user code associated with them
0360   /// (e.g. code that gets expanded in late compilation stages, like by
0361   /// CoroSplitter).
0362   virtual bool IgnoreForLineBreakpoints(const SymbolContext &) const {
0363     return false;
0364   }
0365 
0366   /// Returns a boolean indicating whether two symbol contexts are equal for the
0367   /// purposes of frame comparison. If the plugin has no opinion, it should
0368   /// return nullopt.
0369   virtual std::optional<bool>
0370   AreEqualForFrameComparison(const SymbolContext &sc1,
0371                              const SymbolContext &sc2) const {
0372     return {};
0373   }
0374 
0375   virtual std::optional<bool> GetBooleanFromString(llvm::StringRef str) const;
0376 
0377   /// Returns true if this Language supports exception breakpoints on throw via
0378   /// a corresponding LanguageRuntime plugin.
0379   virtual bool SupportsExceptionBreakpointsOnThrow() const { return false; }
0380 
0381   /// Returns true if this Language supports exception breakpoints on catch via
0382   /// a corresponding LanguageRuntime plugin.
0383   virtual bool SupportsExceptionBreakpointsOnCatch() const { return false; }
0384 
0385   /// Returns the keyword used for throw statements in this language, e.g.
0386   /// Python uses \b raise. Defaults to \b throw.
0387   virtual llvm::StringRef GetThrowKeyword() const { return "throw"; }
0388 
0389   /// Returns the keyword used for catch statements in this language, e.g.
0390   /// Python uses \b except. Defaults to \b catch.
0391   virtual llvm::StringRef GetCatchKeyword() const { return "catch"; }
0392 
0393 protected:
0394   // Classes that inherit from Language can see and modify these
0395 
0396   Language();
0397 
0398 private:
0399   Language(const Language &) = delete;
0400   const Language &operator=(const Language &) = delete;
0401 };
0402 
0403 } // namespace lldb_private
0404 
0405 #endif // LLDB_TARGET_LANGUAGE_H