19313Ssos//===-- LanguageRuntime.h ---------------------------------------------------*-
2133749Stjr// C++ -*-===//
3230132Suqs//
49313Ssos// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
59313Ssos// See https://llvm.org/LICENSE.txt for license information.
69313Ssos// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
79313Ssos//
89313Ssos//===----------------------------------------------------------------------===//
99313Ssos
1014331Speter#ifndef LLDB_TARGET_LANGUAGERUNTIME_H
119313Ssos#define LLDB_TARGET_LANGUAGERUNTIME_H
129313Ssos
139313Ssos#include "lldb/Breakpoint/BreakpointResolver.h"
149313Ssos#include "lldb/Breakpoint/BreakpointResolverName.h"
159313Ssos#include "lldb/Core/PluginInterface.h"
1697748Sschweikh#include "lldb/Core/Value.h"
179313Ssos#include "lldb/Core/ValueObject.h"
189313Ssos#include "lldb/Expression/LLVMUserExpression.h"
199313Ssos#include "lldb/Symbol/DeclVendor.h"
209313Ssos#include "lldb/Target/ExecutionContextScope.h"
219313Ssos#include "lldb/Target/Runtime.h"
229313Ssos#include "lldb/lldb-private.h"
239313Ssos#include "lldb/lldb-public.h"
249313Ssos#include <optional>
259313Ssos
269313Ssosnamespace lldb_private {
279313Ssos
289313Ssosclass ExceptionSearchFilter : public SearchFilter {
299313Ssospublic:
30116173Sobrien  ExceptionSearchFilter(const lldb::TargetSP &target_sp,
31116173Sobrien                        lldb::LanguageType language,
32116173Sobrien                        bool update_module_list = true);
33156874Sru
34235063Snetchild  ~ExceptionSearchFilter() override = default;
3549842Smarcel
369313Ssos  bool ModulePasses(const lldb::ModuleSP &module_sp) override;
37102954Sbde
3876166Smarkm  bool ModulePasses(const FileSpec &spec) override;
39158415Snetchild
4076166Smarkm  void Search(Searcher &searcher) override;
41133816Stjr
4291385Srobert  void GetDescription(Stream *s) override;
4312458Sbde
44114216Skan  static SearchFilter *
4576166Smarkm  CreateFromStructuredData(Target &target,
46102954Sbde                           const StructuredData::Dictionary &data_dict,
479313Ssos                           Status &error);
489313Ssos
4976166Smarkm  StructuredData::ObjectSP SerializeToStructuredData() override;
509313Ssos
51164033Srwatsonprotected:
5276166Smarkm  lldb::LanguageType m_language;
5372538Sjlemon  LanguageRuntime *m_language_runtime;
54220373Strasz  lldb::SearchFilterSP m_filter_sp;
559313Ssos
56164184Strhodes  lldb::SearchFilterSP DoCreateCopy() override;
57235063Snetchild
5876166Smarkm  void UpdateModuleListIfNeeded();
599313Ssos};
60102814Siedowse
6112458Sbdeclass LanguageRuntime : public Runtime, public PluginInterface {
6276166Smarkmpublic:
63102954Sbde  static LanguageRuntime *FindPlugin(Process *process,
6476166Smarkm                                     lldb::LanguageType language);
6580180Spirzyk
669313Ssos  static void InitializeCommands(CommandObject *parent);
679313Ssos
68177257Srdivacky  virtual lldb::LanguageType GetLanguageType() const = 0;
699313Ssos
70163606Srwatson  /// Return the preferred language runtime instance, which in most cases will
71163606Srwatson  /// be the current instance.
7212652Sbde  virtual LanguageRuntime *GetPreferredLanguageRuntime(ValueObject &in_value) {
7312689Speter    return nullptr;
7412458Sbde  }
7512689Speter
7612842Sbde  virtual bool GetObjectDescription(Stream &str, ValueObject &object) = 0;
7780180Spirzyk
7880180Spirzyk  virtual bool GetObjectDescription(Stream &str, Value &value,
7912458Sbde                                    ExecutionContextScope *exe_scope) = 0;
80140214Sobrien
81140214Sobrien
82140214Sobrien  struct VTableInfo {
83140214Sobrien    Address addr; /// Address of the vtable's virtual function table
8464909Smarcel    Symbol *symbol; /// The vtable symbol from the symbol table
8568583Smarcel  };
86133816Stjr  /// Get the vtable information for a given value.
87102954Sbde  ///
88235063Snetchild  /// \param[in] in_value
89177997Skib  ///     The value object to try and extract the VTableInfo from.
9064909Smarcel  ///
91163734Snetchild  /// \param[in] check_type
9264909Smarcel  ///     If true, the compiler type of \a in_value will be checked to see if
93178976Srdivacky  ///     it is an instance to, or pointer or reference to a class or struct
94178976Srdivacky  ///     that has a vtable. If the type doesn't meet the requirements, an
95178976Srdivacky  ///     error will be returned explaining why the type isn't suitable.
9664909Smarcel  ///
97235063Snetchild  /// \return
98235063Snetchild  ///     An error if anything goes wrong while trying to extract the vtable
99235063Snetchild  ///     or if \a check_type is true and the type doesn't have a vtable.
100235063Snetchild  virtual llvm::Expected<VTableInfo> GetVTableInfo(ValueObject &in_value,
101235063Snetchild                                                   bool check_type) {
102235063Snetchild    return llvm::createStringError(
103235063Snetchild        std::errc::invalid_argument,
104235063Snetchild        "language doesn't support getting vtable information");
105235063Snetchild  }
106235063Snetchild
107235063Snetchild  // this call should return true if it could set the name and/or the type
108191966Sdchagin  virtual bool GetDynamicTypeAndAddress(ValueObject &in_value,
109191966Sdchagin                                        lldb::DynamicValueType use_dynamic,
11083221Smarcel                                        TypeAndOrName &class_type_or_name,
11183221Smarcel                                        Address &address,
11283221Smarcel                                        Value::ValueType &value_type) = 0;
113165871Snetchild
11449626Smarcel  // This call should return a CompilerType given a generic type name and an
11549626Smarcel  // ExecutionContextScope in which one can actually fetch any specialization
11683221Smarcel  // information required.
11783221Smarcel  virtual CompilerType GetConcreteType(ExecutionContextScope *exe_scope,
11883221Smarcel                                       ConstString abstract_type_name) {
119122802Ssobomax    return CompilerType();
12083221Smarcel  }
12183221Smarcel
12283221Smarcel  // This should be a fast test to determine whether it is likely that this
12383221Smarcel  // value would have a dynamic type.
12483221Smarcel  virtual bool CouldHaveDynamicValue(ValueObject &in_value) = 0;
12583221Smarcel
12683221Smarcel  // The contract for GetDynamicTypeAndAddress() is to return a "bare-bones"
127164380Skib  // dynamic type For instance, given a Base* pointer,
128122802Ssobomax  // GetDynamicTypeAndAddress() will return the type of Derived, not Derived*.
129122802Ssobomax  // The job of this API is to correct this misalignment between the static
130122802Ssobomax  // type and the discovered dynamic type
131164380Skib  virtual TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
13280180Spirzyk                                         ValueObject &static_value) = 0;
1339313Ssos
13483366Sjulian  virtual void SetExceptionBreakpoints() {}
13580180Spirzyk
13683221Smarcel  virtual void ClearExceptionBreakpoints() {}
13783221Smarcel
138117723Sphk  virtual bool ExceptionBreakpointsAreSet() { return false; }
13983221Smarcel
14080180Spirzyk  virtual bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) {
14183221Smarcel    return false;
142147816Sjhb  }
143147816Sjhb
144147816Sjhb  static lldb::BreakpointSP
14580180Spirzyk  CreateExceptionBreakpoint(Target &target, lldb::LanguageType language,
14683221Smarcel                            bool catch_bp, bool throw_bp,
14783221Smarcel                            bool is_internal = false);
148122802Ssobomax
149122802Ssobomax  static lldb::BreakpointPreconditionSP
15080180Spirzyk  GetExceptionPrecondition(lldb::LanguageType language, bool throw_bp);
15183221Smarcel
152170170Sattilio  virtual lldb::ValueObjectSP GetExceptionObjectForThread(
15380180Spirzyk      lldb::ThreadSP thread_sp) {
15483221Smarcel    return lldb::ValueObjectSP();
155124082Salc  }
156124082Salc
15783221Smarcel  virtual lldb::ThreadSP GetBacktraceThreadFromException(
15883221Smarcel      lldb::ValueObjectSP thread_sp) {
159124082Salc    return lldb::ThreadSP();
16080180Spirzyk  }
16183221Smarcel
16283221Smarcel  virtual DeclVendor *GetDeclVendor() { return nullptr; }
16380180Spirzyk
164117723Sphk  virtual lldb::BreakpointResolverSP
165165686Snetchild  CreateExceptionResolver(const lldb::BreakpointSP &bkpt,
166117723Sphk                          bool catch_bp, bool throw_bp) = 0;
16780180Spirzyk
168122802Ssobomax  virtual lldb::SearchFilterSP CreateExceptionSearchFilter() {
16980180Spirzyk    return m_process->GetTarget().GetSearchFilterForModule(nullptr);
170122802Ssobomax  }
171122802Ssobomax
172122802Ssobomax  virtual bool GetTypeBitSize(const CompilerType &compiler_type,
173122802Ssobomax                              uint64_t &size) {
174122802Ssobomax    return false;
175218031Sdchagin  }
17680180Spirzyk
17780180Spirzyk  virtual void SymbolsDidLoad(const ModuleList &module_list) {}
17880180Spirzyk
17983366Sjulian  virtual lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
1809313Ssos                                                          bool stop_others) = 0;
18183221Smarcel
182180766Srdivacky  /// Identify whether a name is a runtime value that should not be hidden by
183141467Sjhb  /// from the user interface.
1849313Ssos  virtual bool IsAllowedRuntimeValue(ConstString name) { return false; }
1859313Ssos
18672543Sjlemon  virtual std::optional<CompilerType> GetRuntimeType(CompilerType base_type) {
18772543Sjlemon    return std::nullopt;
1889313Ssos  }
189180766Srdivacky
190180766Srdivacky  void ModulesDidLoad(const ModuleList &module_list) override {}
19183221Smarcel
192180766Srdivacky  // Called by ClangExpressionParser::PrepareForExecution to query for any
193180766Srdivacky  // custom LLVM IR passes that need to be run before an expression is
19483221Smarcel  // assembled and run.
195180766Srdivacky  virtual bool GetIRPasses(LLVMUserExpression::IRPasses &custom_passes) {
19683221Smarcel    return false;
19783221Smarcel  }
19883221Smarcel
199141467Sjhb  // Given the name of a runtime symbol (e.g. in Objective-C, an ivar offset
200141467Sjhb  // symbol), try to determine from the runtime what the value of that symbol
201141467Sjhb  // would be. Useful when the underlying binary is stripped.
202165686Snetchild  virtual lldb::addr_t LookupRuntimeSymbol(ConstString name) {
20383221Smarcel    return LLDB_INVALID_ADDRESS;
20483221Smarcel  }
20583366Sjulian
20683221Smarcel  virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
207141467Sjhb  static char ID;
2089313Ssos
2099313Ssos  /// A language runtime may be able to provide a special UnwindPlan for
2109313Ssos  /// the frame represented by the register contents \a regctx when that
21183366Sjulian  /// frame is not following the normal ABI conventions.
2129313Ssos  /// Instead of using the normal UnwindPlan for the function, we will use
21383366Sjulian  /// this special UnwindPlan for this one backtrace.
21483221Smarcel  /// One example of this would be a language that has asynchronous functions,
21583221Smarcel  /// functions that may not be currently-executing, while waiting on other
21683221Smarcel  /// asynchronous calls they made, but are part of a logical backtrace that
21783221Smarcel  /// we want to show the developer because that's how they think of the
2189313Ssos  /// program flow.
2199313Ssos  ///
22072543Sjlemon  /// \param[in] thread
221133845Sobrien  ///     The thread that the unwind is happening on.
2229313Ssos  ///
22383221Smarcel  /// \param[in] regctx
22483221Smarcel  ///     The RegisterContext for the frame we need to create an UnwindPlan.
225165686Snetchild  ///     We don't yet have a StackFrame when we're selecting the UnwindPlan.
226225617Skmacy  ///
22783366Sjulian  /// \param[out] behaves_like_zeroth_frame
22883221Smarcel  ///     With normal ABI calls, all stack frames except the zeroth frame need
22983366Sjulian  ///     to have the return-pc value backed up by 1 for symbolication purposes.
2309313Ssos  ///     For these LanguageRuntime unwind plans, they may not follow normal ABI
231218031Sdchagin  ///     calling conventions and the return pc may need to be symbolicated
2329313Ssos  ///     as-is.
2339313Ssos  ///
234158415Snetchild  /// \return
235158415Snetchild  ///     Returns an UnwindPlan to find the caller frame if it should be used,
236133816Stjr  ///     instead of the UnwindPlan that would normally be used for this
2379313Ssos  ///     function.
23883366Sjulian  static lldb::UnwindPlanSP
2399313Ssos  GetRuntimeUnwindPlan(lldb_private::Thread &thread,
24083221Smarcel                       lldb_private::RegisterContext *regctx,
24183221Smarcel                       bool &behaves_like_zeroth_frame);
24283221Smarcel
24383221Smarcelprotected:
24483221Smarcel  // The static GetRuntimeUnwindPlan method above is only implemented in the
24583221Smarcel  // base class; subclasses may override this protected member if they can
24683221Smarcel  // provide one of these UnwindPlans.
247102814Siedowse  virtual lldb::UnwindPlanSP
248231885Skib  GetRuntimeUnwindPlan(lldb::ProcessSP process_sp,
249242476Skib                       lldb_private::RegisterContext *regctx,
2509313Ssos                       bool &behaves_like_zeroth_frame) {
251102814Siedowse    return lldb::UnwindPlanSP();
25214331Speter  }
2539313Ssos
25472543Sjlemon  LanguageRuntime(Process *process);
255102814Siedowse};
2569313Ssos
2579313Ssos} // namespace lldb_private
25883221Smarcel
25983221Smarcel#endif // LLDB_TARGET_LANGUAGERUNTIME_H
26083221Smarcel