130fdc8d8SChris Lattner //===-- SBFunction.cpp ------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
930fdc8d8SChris Lattner #include "lldb/API/SBFunction.h"
10baf5664fSJonas Devlieghere #include "SBReproducerPrivate.h"
1130fdc8d8SChris Lattner #include "lldb/API/SBProcess.h"
12dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
131d273166SGreg Clayton #include "lldb/Core/Disassembler.h"
141d273166SGreg Clayton #include "lldb/Core/Module.h"
151d273166SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
1630fdc8d8SChris Lattner #include "lldb/Symbol/Function.h"
1705faeb71SGreg Clayton #include "lldb/Symbol/Type.h"
18fe68904fSGreg Clayton #include "lldb/Symbol/VariableList.h"
191d273166SGreg Clayton #include "lldb/Target/ExecutionContext.h"
201d273166SGreg Clayton #include "lldb/Target/Target.h"
2130fdc8d8SChris Lattner 
2230fdc8d8SChris Lattner using namespace lldb;
231d273166SGreg Clayton using namespace lldb_private;
2430fdc8d8SChris Lattner 
25baf5664fSJonas Devlieghere SBFunction::SBFunction() : m_opaque_ptr(NULL) {
26baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFunction);
27baf5664fSJonas Devlieghere }
2830fdc8d8SChris Lattner 
29b9c1b51eSKate Stone SBFunction::SBFunction(lldb_private::Function *lldb_object_ptr)
30b9c1b51eSKate Stone     : m_opaque_ptr(lldb_object_ptr) {}
3130fdc8d8SChris Lattner 
32b9c1b51eSKate Stone SBFunction::SBFunction(const lldb::SBFunction &rhs)
33baf5664fSJonas Devlieghere     : m_opaque_ptr(rhs.m_opaque_ptr) {
34baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBFunction, (const lldb::SBFunction &), rhs);
35baf5664fSJonas Devlieghere }
36efabb123SGreg Clayton 
37b9c1b51eSKate Stone const SBFunction &SBFunction::operator=(const SBFunction &rhs) {
38baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(const lldb::SBFunction &,
39baf5664fSJonas Devlieghere                      SBFunction, operator=,(const lldb::SBFunction &), rhs);
40baf5664fSJonas Devlieghere 
41efabb123SGreg Clayton   m_opaque_ptr = rhs.m_opaque_ptr;
42efabb123SGreg Clayton   return *this;
43efabb123SGreg Clayton }
44efabb123SGreg Clayton 
45b9c1b51eSKate Stone SBFunction::~SBFunction() { m_opaque_ptr = NULL; }
4630fdc8d8SChris Lattner 
47baf5664fSJonas Devlieghere bool SBFunction::IsValid() const {
48baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFunction, IsValid);
497f5237bcSPavel Labath   return this->operator bool();
507f5237bcSPavel Labath }
517f5237bcSPavel Labath SBFunction::operator bool() const {
527f5237bcSPavel Labath   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFunction, operator bool);
53baf5664fSJonas Devlieghere 
54baf5664fSJonas Devlieghere   return m_opaque_ptr != NULL;
55baf5664fSJonas Devlieghere }
5630fdc8d8SChris Lattner 
57b9c1b51eSKate Stone const char *SBFunction::GetName() const {
58baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFunction, GetName);
59baf5664fSJonas Devlieghere 
60cfd1acedSGreg Clayton   const char *cstr = NULL;
616611103cSGreg Clayton   if (m_opaque_ptr)
62ddaf6a72SGreg Clayton     cstr = m_opaque_ptr->GetName().AsCString();
63ceb6b139SCaroline Tice 
64cfd1acedSGreg Clayton   return cstr;
6530fdc8d8SChris Lattner }
6630fdc8d8SChris Lattner 
67b9c1b51eSKate Stone const char *SBFunction::GetDisplayName() const {
68baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFunction, GetDisplayName);
69baf5664fSJonas Devlieghere 
70c1f705c2SEnrico Granata   const char *cstr = NULL;
71c1f705c2SEnrico Granata   if (m_opaque_ptr)
72b9c1b51eSKate Stone     cstr = m_opaque_ptr->GetMangled()
73b9c1b51eSKate Stone                .GetDisplayDemangledName(m_opaque_ptr->GetLanguage())
74b9c1b51eSKate Stone                .AsCString();
75c1f705c2SEnrico Granata 
76c1f705c2SEnrico Granata   return cstr;
77c1f705c2SEnrico Granata }
78c1f705c2SEnrico Granata 
79b9c1b51eSKate Stone const char *SBFunction::GetMangledName() const {
80baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFunction, GetMangledName);
81baf5664fSJonas Devlieghere 
82cfd1acedSGreg Clayton   const char *cstr = NULL;
836611103cSGreg Clayton   if (m_opaque_ptr)
84cfd1acedSGreg Clayton     cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString();
85cfd1acedSGreg Clayton   return cstr;
8630fdc8d8SChris Lattner }
8730fdc8d8SChris Lattner 
88b9c1b51eSKate Stone bool SBFunction::operator==(const SBFunction &rhs) const {
89baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(
90baf5664fSJonas Devlieghere       bool, SBFunction, operator==,(const lldb::SBFunction &), rhs);
91baf5664fSJonas Devlieghere 
926611103cSGreg Clayton   return m_opaque_ptr == rhs.m_opaque_ptr;
9330fdc8d8SChris Lattner }
9430fdc8d8SChris Lattner 
95b9c1b51eSKate Stone bool SBFunction::operator!=(const SBFunction &rhs) const {
96baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(
97baf5664fSJonas Devlieghere       bool, SBFunction, operator!=,(const lldb::SBFunction &), rhs);
98baf5664fSJonas Devlieghere 
996611103cSGreg Clayton   return m_opaque_ptr != rhs.m_opaque_ptr;
10030fdc8d8SChris Lattner }
101dde9cff3SCaroline Tice 
102b9c1b51eSKate Stone bool SBFunction::GetDescription(SBStream &s) {
103baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBFunction, GetDescription, (lldb::SBStream &), s);
104baf5664fSJonas Devlieghere 
105b9c1b51eSKate Stone   if (m_opaque_ptr) {
106d01b2953SDaniel Malea     s.Printf("SBFunction: id = 0x%8.8" PRIx64 ", name = %s",
107b9c1b51eSKate Stone              m_opaque_ptr->GetID(), m_opaque_ptr->GetName().AsCString());
10805faeb71SGreg Clayton     Type *func_type = m_opaque_ptr->GetType();
10905faeb71SGreg Clayton     if (func_type)
11005faeb71SGreg Clayton       s.Printf(", type = %s", func_type->GetName().AsCString());
111dde9cff3SCaroline Tice     return true;
112dde9cff3SCaroline Tice   }
11305faeb71SGreg Clayton   s.Printf("No value");
11405faeb71SGreg Clayton   return false;
11505faeb71SGreg Clayton }
1161d273166SGreg Clayton 
117b9c1b51eSKate Stone SBInstructionList SBFunction::GetInstructions(SBTarget target) {
118baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBInstructionList, SBFunction, GetInstructions,
119baf5664fSJonas Devlieghere                      (lldb::SBTarget), target);
120baf5664fSJonas Devlieghere 
121baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(GetInstructions(target, NULL));
1220f063ba6SJim Ingham }
1230f063ba6SJim Ingham 
124b9c1b51eSKate Stone SBInstructionList SBFunction::GetInstructions(SBTarget target,
125b9c1b51eSKate Stone                                               const char *flavor) {
126baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBInstructionList, SBFunction, GetInstructions,
127baf5664fSJonas Devlieghere                      (lldb::SBTarget, const char *), target, flavor);
128baf5664fSJonas Devlieghere 
1291d273166SGreg Clayton   SBInstructionList sb_instructions;
130b9c1b51eSKate Stone   if (m_opaque_ptr) {
1311d273166SGreg Clayton     ExecutionContext exe_ctx;
132b9556accSGreg Clayton     TargetSP target_sp(target.GetSP());
133bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
134b9c1b51eSKate Stone     if (target_sp) {
135bb19a13cSSaleem Abdulrasool       lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
136b9556accSGreg Clayton       target_sp->CalculateExecutionContext(exe_ctx);
137b9556accSGreg Clayton       exe_ctx.SetProcessSP(target_sp->GetProcessSP());
1381d273166SGreg Clayton     }
139b9c1b51eSKate Stone     ModuleSP module_sp(
140b9c1b51eSKate Stone         m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule());
141b9c1b51eSKate Stone     if (module_sp) {
1426b3e6d54SJason Molenda       const bool prefer_file_cache = false;
143b9c1b51eSKate Stone       sb_instructions.SetDisassembler(Disassembler::DisassembleRange(
144b9c1b51eSKate Stone           module_sp->GetArchitecture(), NULL, flavor, exe_ctx,
145b9c1b51eSKate Stone           m_opaque_ptr->GetAddressRange(), prefer_file_cache));
1461d273166SGreg Clayton     }
1471d273166SGreg Clayton   }
148baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_instructions);
1491d273166SGreg Clayton }
1501d273166SGreg Clayton 
151b9c1b51eSKate Stone lldb_private::Function *SBFunction::get() { return m_opaque_ptr; }
1521d273166SGreg Clayton 
153b9c1b51eSKate Stone void SBFunction::reset(lldb_private::Function *lldb_object_ptr) {
15472eff18aSGreg Clayton   m_opaque_ptr = lldb_object_ptr;
15572eff18aSGreg Clayton }
15672eff18aSGreg Clayton 
157b9c1b51eSKate Stone SBAddress SBFunction::GetStartAddress() {
158baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBFunction, GetStartAddress);
159baf5664fSJonas Devlieghere 
16093d00df5SGreg Clayton   SBAddress addr;
16193d00df5SGreg Clayton   if (m_opaque_ptr)
16293d00df5SGreg Clayton     addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress());
163baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(addr);
16493d00df5SGreg Clayton }
16593d00df5SGreg Clayton 
166b9c1b51eSKate Stone SBAddress SBFunction::GetEndAddress() {
167baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBFunction, GetEndAddress);
168baf5664fSJonas Devlieghere 
16993d00df5SGreg Clayton   SBAddress addr;
170b9c1b51eSKate Stone   if (m_opaque_ptr) {
17193d00df5SGreg Clayton     addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize();
172b9c1b51eSKate Stone     if (byte_size > 0) {
17393d00df5SGreg Clayton       addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress());
17493d00df5SGreg Clayton       addr->Slide(byte_size);
17593d00df5SGreg Clayton     }
17693d00df5SGreg Clayton   }
177baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(addr);
17893d00df5SGreg Clayton }
17993d00df5SGreg Clayton 
180b9c1b51eSKate Stone const char *SBFunction::GetArgumentName(uint32_t arg_idx) {
181baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(const char *, SBFunction, GetArgumentName, (uint32_t),
182baf5664fSJonas Devlieghere                      arg_idx);
183baf5664fSJonas Devlieghere 
184b9c1b51eSKate Stone   if (m_opaque_ptr) {
185fe68904fSGreg Clayton     Block &block = m_opaque_ptr->GetBlock(true);
186fe68904fSGreg Clayton     VariableListSP variable_list_sp = block.GetBlockVariableList(true);
187b9c1b51eSKate Stone     if (variable_list_sp) {
188fe68904fSGreg Clayton       VariableList arguments;
189b9c1b51eSKate Stone       variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
190b9c1b51eSKate Stone                                                  arguments, true);
191fe68904fSGreg Clayton       lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx);
192fe68904fSGreg Clayton       if (variable_sp)
193fe68904fSGreg Clayton         return variable_sp->GetName().GetCString();
194fe68904fSGreg Clayton     }
195fe68904fSGreg Clayton   }
196fe68904fSGreg Clayton   return nullptr;
197fe68904fSGreg Clayton }
19893d00df5SGreg Clayton 
199b9c1b51eSKate Stone uint32_t SBFunction::GetPrologueByteSize() {
200baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBFunction, GetPrologueByteSize);
201baf5664fSJonas Devlieghere 
20293d00df5SGreg Clayton   if (m_opaque_ptr)
20393d00df5SGreg Clayton     return m_opaque_ptr->GetPrologueByteSize();
20493d00df5SGreg Clayton   return 0;
20593d00df5SGreg Clayton }
20693d00df5SGreg Clayton 
207b9c1b51eSKate Stone SBType SBFunction::GetType() {
208baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBType, SBFunction, GetType);
209baf5664fSJonas Devlieghere 
2105569e64eSGreg Clayton   SBType sb_type;
211b9c1b51eSKate Stone   if (m_opaque_ptr) {
2125569e64eSGreg Clayton     Type *function_type = m_opaque_ptr->GetType();
2135569e64eSGreg Clayton     if (function_type)
2145569e64eSGreg Clayton       sb_type.ref().SetType(function_type->shared_from_this());
2155569e64eSGreg Clayton   }
216baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_type);
2175569e64eSGreg Clayton }
2185569e64eSGreg Clayton 
219b9c1b51eSKate Stone SBBlock SBFunction::GetBlock() {
220baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock, SBFunction, GetBlock);
221baf5664fSJonas Devlieghere 
2225569e64eSGreg Clayton   SBBlock sb_block;
2235569e64eSGreg Clayton   if (m_opaque_ptr)
2245569e64eSGreg Clayton     sb_block.SetPtr(&m_opaque_ptr->GetBlock(true));
225baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_block);
2265569e64eSGreg Clayton }
2275569e64eSGreg Clayton 
228b9c1b51eSKate Stone lldb::LanguageType SBFunction::GetLanguage() {
229baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::LanguageType, SBFunction, GetLanguage);
230baf5664fSJonas Devlieghere 
231b9c1b51eSKate Stone   if (m_opaque_ptr) {
2326cd8e0c9SEnrico Granata     if (m_opaque_ptr->GetCompileUnit())
2336cd8e0c9SEnrico Granata       return m_opaque_ptr->GetCompileUnit()->GetLanguage();
2346cd8e0c9SEnrico Granata   }
2356cd8e0c9SEnrico Granata   return lldb::eLanguageTypeUnknown;
2366cd8e0c9SEnrico Granata }
2375569e64eSGreg Clayton 
238b9c1b51eSKate Stone bool SBFunction::GetIsOptimized() {
239baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBFunction, GetIsOptimized);
240baf5664fSJonas Devlieghere 
241b9c1b51eSKate Stone   if (m_opaque_ptr) {
2426ab659a9SJason Molenda     if (m_opaque_ptr->GetCompileUnit())
2436ab659a9SJason Molenda       return m_opaque_ptr->GetCompileUnit()->GetIsOptimized();
2446ab659a9SJason Molenda   }
2456ab659a9SJason Molenda   return false;
2466ab659a9SJason Molenda }
247*ae211eceSMichal Gorny 
248*ae211eceSMichal Gorny namespace lldb_private {
249*ae211eceSMichal Gorny namespace repro {
250*ae211eceSMichal Gorny 
251*ae211eceSMichal Gorny template <>
252*ae211eceSMichal Gorny void RegisterMethods<SBFunction>(Registry &R) {
253*ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBFunction, ());
254*ae211eceSMichal Gorny   LLDB_REGISTER_CONSTRUCTOR(SBFunction, (const lldb::SBFunction &));
255*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(const lldb::SBFunction &,
256*ae211eceSMichal Gorny                        SBFunction, operator=,(const lldb::SBFunction &));
257*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBFunction, IsValid, ());
258*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(bool, SBFunction, operator bool, ());
259*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBFunction, GetName, ());
260*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBFunction, GetDisplayName, ());
261*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(const char *, SBFunction, GetMangledName, ());
262*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(
263*ae211eceSMichal Gorny       bool, SBFunction, operator==,(const lldb::SBFunction &));
264*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD_CONST(
265*ae211eceSMichal Gorny       bool, SBFunction, operator!=,(const lldb::SBFunction &));
266*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBFunction, GetDescription, (lldb::SBStream &));
267*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBInstructionList, SBFunction, GetInstructions,
268*ae211eceSMichal Gorny                        (lldb::SBTarget));
269*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBInstructionList, SBFunction, GetInstructions,
270*ae211eceSMichal Gorny                        (lldb::SBTarget, const char *));
271*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBAddress, SBFunction, GetStartAddress, ());
272*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBAddress, SBFunction, GetEndAddress, ());
273*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(const char *, SBFunction, GetArgumentName, (uint32_t));
274*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(uint32_t, SBFunction, GetPrologueByteSize, ());
275*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBType, SBFunction, GetType, ());
276*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::SBBlock, SBFunction, GetBlock, ());
277*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(lldb::LanguageType, SBFunction, GetLanguage, ());
278*ae211eceSMichal Gorny   LLDB_REGISTER_METHOD(bool, SBFunction, GetIsOptimized, ());
279*ae211eceSMichal Gorny }
280*ae211eceSMichal Gorny 
281*ae211eceSMichal Gorny }
282*ae211eceSMichal Gorny }
283