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"
10*baf5664fSJonas 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"
216f9e6901SZachary Turner #include "lldb/Utility/Log.h"
2230fdc8d8SChris Lattner 
2330fdc8d8SChris Lattner using namespace lldb;
241d273166SGreg Clayton using namespace lldb_private;
2530fdc8d8SChris Lattner 
26*baf5664fSJonas Devlieghere SBFunction::SBFunction() : m_opaque_ptr(NULL) {
27*baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFunction);
28*baf5664fSJonas Devlieghere }
2930fdc8d8SChris Lattner 
30b9c1b51eSKate Stone SBFunction::SBFunction(lldb_private::Function *lldb_object_ptr)
31b9c1b51eSKate Stone     : m_opaque_ptr(lldb_object_ptr) {}
3230fdc8d8SChris Lattner 
33b9c1b51eSKate Stone SBFunction::SBFunction(const lldb::SBFunction &rhs)
34*baf5664fSJonas Devlieghere     : m_opaque_ptr(rhs.m_opaque_ptr) {
35*baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBFunction, (const lldb::SBFunction &), rhs);
36*baf5664fSJonas Devlieghere }
37efabb123SGreg Clayton 
38b9c1b51eSKate Stone const SBFunction &SBFunction::operator=(const SBFunction &rhs) {
39*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(const lldb::SBFunction &,
40*baf5664fSJonas Devlieghere                      SBFunction, operator=,(const lldb::SBFunction &), rhs);
41*baf5664fSJonas Devlieghere 
42efabb123SGreg Clayton   m_opaque_ptr = rhs.m_opaque_ptr;
43efabb123SGreg Clayton   return *this;
44efabb123SGreg Clayton }
45efabb123SGreg Clayton 
46b9c1b51eSKate Stone SBFunction::~SBFunction() { m_opaque_ptr = NULL; }
4730fdc8d8SChris Lattner 
48*baf5664fSJonas Devlieghere bool SBFunction::IsValid() const {
49*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBFunction, IsValid);
50*baf5664fSJonas Devlieghere 
51*baf5664fSJonas Devlieghere   return m_opaque_ptr != NULL;
52*baf5664fSJonas Devlieghere }
5330fdc8d8SChris Lattner 
54b9c1b51eSKate Stone const char *SBFunction::GetName() const {
55*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFunction, GetName);
56*baf5664fSJonas Devlieghere 
57cfd1acedSGreg Clayton   const char *cstr = NULL;
586611103cSGreg Clayton   if (m_opaque_ptr)
59ddaf6a72SGreg Clayton     cstr = m_opaque_ptr->GetName().AsCString();
60ceb6b139SCaroline Tice 
615160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
62b9c1b51eSKate Stone   if (log) {
63cfd1acedSGreg Clayton     if (cstr)
64324a1036SSaleem Abdulrasool       log->Printf("SBFunction(%p)::GetName () => \"%s\"",
65324a1036SSaleem Abdulrasool                   static_cast<void *>(m_opaque_ptr), cstr);
66cfd1acedSGreg Clayton     else
67324a1036SSaleem Abdulrasool       log->Printf("SBFunction(%p)::GetName () => NULL",
68324a1036SSaleem Abdulrasool                   static_cast<void *>(m_opaque_ptr));
69cfd1acedSGreg Clayton   }
70cfd1acedSGreg Clayton   return cstr;
7130fdc8d8SChris Lattner }
7230fdc8d8SChris Lattner 
73b9c1b51eSKate Stone const char *SBFunction::GetDisplayName() const {
74*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFunction, GetDisplayName);
75*baf5664fSJonas Devlieghere 
76c1f705c2SEnrico Granata   const char *cstr = NULL;
77c1f705c2SEnrico Granata   if (m_opaque_ptr)
78b9c1b51eSKate Stone     cstr = m_opaque_ptr->GetMangled()
79b9c1b51eSKate Stone                .GetDisplayDemangledName(m_opaque_ptr->GetLanguage())
80b9c1b51eSKate Stone                .AsCString();
81c1f705c2SEnrico Granata 
82c1f705c2SEnrico Granata   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
83b9c1b51eSKate Stone   if (log) {
84c1f705c2SEnrico Granata     if (cstr)
85c1f705c2SEnrico Granata       log->Printf("SBFunction(%p)::GetDisplayName () => \"%s\"",
86c1f705c2SEnrico Granata                   static_cast<void *>(m_opaque_ptr), cstr);
87c1f705c2SEnrico Granata     else
88c1f705c2SEnrico Granata       log->Printf("SBFunction(%p)::GetDisplayName () => NULL",
89c1f705c2SEnrico Granata                   static_cast<void *>(m_opaque_ptr));
90c1f705c2SEnrico Granata   }
91c1f705c2SEnrico Granata   return cstr;
92c1f705c2SEnrico Granata }
93c1f705c2SEnrico Granata 
94b9c1b51eSKate Stone const char *SBFunction::GetMangledName() const {
95*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBFunction, GetMangledName);
96*baf5664fSJonas Devlieghere 
97cfd1acedSGreg Clayton   const char *cstr = NULL;
986611103cSGreg Clayton   if (m_opaque_ptr)
99cfd1acedSGreg Clayton     cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString();
1005160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
101b9c1b51eSKate Stone   if (log) {
102cfd1acedSGreg Clayton     if (cstr)
103324a1036SSaleem Abdulrasool       log->Printf("SBFunction(%p)::GetMangledName () => \"%s\"",
104324a1036SSaleem Abdulrasool                   static_cast<void *>(m_opaque_ptr), cstr);
105cfd1acedSGreg Clayton     else
106324a1036SSaleem Abdulrasool       log->Printf("SBFunction(%p)::GetMangledName () => NULL",
107324a1036SSaleem Abdulrasool                   static_cast<void *>(m_opaque_ptr));
108cfd1acedSGreg Clayton   }
109cfd1acedSGreg Clayton   return cstr;
11030fdc8d8SChris Lattner }
11130fdc8d8SChris Lattner 
112b9c1b51eSKate Stone bool SBFunction::operator==(const SBFunction &rhs) const {
113*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(
114*baf5664fSJonas Devlieghere       bool, SBFunction, operator==,(const lldb::SBFunction &), rhs);
115*baf5664fSJonas Devlieghere 
1166611103cSGreg Clayton   return m_opaque_ptr == rhs.m_opaque_ptr;
11730fdc8d8SChris Lattner }
11830fdc8d8SChris Lattner 
119b9c1b51eSKate Stone bool SBFunction::operator!=(const SBFunction &rhs) const {
120*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST(
121*baf5664fSJonas Devlieghere       bool, SBFunction, operator!=,(const lldb::SBFunction &), rhs);
122*baf5664fSJonas Devlieghere 
1236611103cSGreg Clayton   return m_opaque_ptr != rhs.m_opaque_ptr;
12430fdc8d8SChris Lattner }
125dde9cff3SCaroline Tice 
126b9c1b51eSKate Stone bool SBFunction::GetDescription(SBStream &s) {
127*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBFunction, GetDescription, (lldb::SBStream &), s);
128*baf5664fSJonas Devlieghere 
129b9c1b51eSKate Stone   if (m_opaque_ptr) {
130d01b2953SDaniel Malea     s.Printf("SBFunction: id = 0x%8.8" PRIx64 ", name = %s",
131b9c1b51eSKate Stone              m_opaque_ptr->GetID(), m_opaque_ptr->GetName().AsCString());
13205faeb71SGreg Clayton     Type *func_type = m_opaque_ptr->GetType();
13305faeb71SGreg Clayton     if (func_type)
13405faeb71SGreg Clayton       s.Printf(", type = %s", func_type->GetName().AsCString());
135dde9cff3SCaroline Tice     return true;
136dde9cff3SCaroline Tice   }
13705faeb71SGreg Clayton   s.Printf("No value");
13805faeb71SGreg Clayton   return false;
13905faeb71SGreg Clayton }
1401d273166SGreg Clayton 
141b9c1b51eSKate Stone SBInstructionList SBFunction::GetInstructions(SBTarget target) {
142*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBInstructionList, SBFunction, GetInstructions,
143*baf5664fSJonas Devlieghere                      (lldb::SBTarget), target);
144*baf5664fSJonas Devlieghere 
145*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(GetInstructions(target, NULL));
1460f063ba6SJim Ingham }
1470f063ba6SJim Ingham 
148b9c1b51eSKate Stone SBInstructionList SBFunction::GetInstructions(SBTarget target,
149b9c1b51eSKate Stone                                               const char *flavor) {
150*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(lldb::SBInstructionList, SBFunction, GetInstructions,
151*baf5664fSJonas Devlieghere                      (lldb::SBTarget, const char *), target, flavor);
152*baf5664fSJonas Devlieghere 
1531d273166SGreg Clayton   SBInstructionList sb_instructions;
154b9c1b51eSKate Stone   if (m_opaque_ptr) {
1551d273166SGreg Clayton     ExecutionContext exe_ctx;
156b9556accSGreg Clayton     TargetSP target_sp(target.GetSP());
157bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
158b9c1b51eSKate Stone     if (target_sp) {
159bb19a13cSSaleem Abdulrasool       lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
160b9556accSGreg Clayton       target_sp->CalculateExecutionContext(exe_ctx);
161b9556accSGreg Clayton       exe_ctx.SetProcessSP(target_sp->GetProcessSP());
1621d273166SGreg Clayton     }
163b9c1b51eSKate Stone     ModuleSP module_sp(
164b9c1b51eSKate Stone         m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule());
165b9c1b51eSKate Stone     if (module_sp) {
1666b3e6d54SJason Molenda       const bool prefer_file_cache = false;
167b9c1b51eSKate Stone       sb_instructions.SetDisassembler(Disassembler::DisassembleRange(
168b9c1b51eSKate Stone           module_sp->GetArchitecture(), NULL, flavor, exe_ctx,
169b9c1b51eSKate Stone           m_opaque_ptr->GetAddressRange(), prefer_file_cache));
1701d273166SGreg Clayton     }
1711d273166SGreg Clayton   }
172*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_instructions);
1731d273166SGreg Clayton }
1741d273166SGreg Clayton 
175b9c1b51eSKate Stone lldb_private::Function *SBFunction::get() { return m_opaque_ptr; }
1761d273166SGreg Clayton 
177b9c1b51eSKate Stone void SBFunction::reset(lldb_private::Function *lldb_object_ptr) {
17872eff18aSGreg Clayton   m_opaque_ptr = lldb_object_ptr;
17972eff18aSGreg Clayton }
18072eff18aSGreg Clayton 
181b9c1b51eSKate Stone SBAddress SBFunction::GetStartAddress() {
182*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBFunction, GetStartAddress);
183*baf5664fSJonas Devlieghere 
18493d00df5SGreg Clayton   SBAddress addr;
18593d00df5SGreg Clayton   if (m_opaque_ptr)
18693d00df5SGreg Clayton     addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress());
187*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(addr);
18893d00df5SGreg Clayton }
18993d00df5SGreg Clayton 
190b9c1b51eSKate Stone SBAddress SBFunction::GetEndAddress() {
191*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBFunction, GetEndAddress);
192*baf5664fSJonas Devlieghere 
19393d00df5SGreg Clayton   SBAddress addr;
194b9c1b51eSKate Stone   if (m_opaque_ptr) {
19593d00df5SGreg Clayton     addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize();
196b9c1b51eSKate Stone     if (byte_size > 0) {
19793d00df5SGreg Clayton       addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress());
19893d00df5SGreg Clayton       addr->Slide(byte_size);
19993d00df5SGreg Clayton     }
20093d00df5SGreg Clayton   }
201*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(addr);
20293d00df5SGreg Clayton }
20393d00df5SGreg Clayton 
204b9c1b51eSKate Stone const char *SBFunction::GetArgumentName(uint32_t arg_idx) {
205*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(const char *, SBFunction, GetArgumentName, (uint32_t),
206*baf5664fSJonas Devlieghere                      arg_idx);
207*baf5664fSJonas Devlieghere 
208b9c1b51eSKate Stone   if (m_opaque_ptr) {
209fe68904fSGreg Clayton     Block &block = m_opaque_ptr->GetBlock(true);
210fe68904fSGreg Clayton     VariableListSP variable_list_sp = block.GetBlockVariableList(true);
211b9c1b51eSKate Stone     if (variable_list_sp) {
212fe68904fSGreg Clayton       VariableList arguments;
213b9c1b51eSKate Stone       variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
214b9c1b51eSKate Stone                                                  arguments, true);
215fe68904fSGreg Clayton       lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx);
216fe68904fSGreg Clayton       if (variable_sp)
217fe68904fSGreg Clayton         return variable_sp->GetName().GetCString();
218fe68904fSGreg Clayton     }
219fe68904fSGreg Clayton   }
220fe68904fSGreg Clayton   return nullptr;
221fe68904fSGreg Clayton }
22293d00df5SGreg Clayton 
223b9c1b51eSKate Stone uint32_t SBFunction::GetPrologueByteSize() {
224*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBFunction, GetPrologueByteSize);
225*baf5664fSJonas Devlieghere 
22693d00df5SGreg Clayton   if (m_opaque_ptr)
22793d00df5SGreg Clayton     return m_opaque_ptr->GetPrologueByteSize();
22893d00df5SGreg Clayton   return 0;
22993d00df5SGreg Clayton }
23093d00df5SGreg Clayton 
231b9c1b51eSKate Stone SBType SBFunction::GetType() {
232*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBType, SBFunction, GetType);
233*baf5664fSJonas Devlieghere 
2345569e64eSGreg Clayton   SBType sb_type;
235b9c1b51eSKate Stone   if (m_opaque_ptr) {
2365569e64eSGreg Clayton     Type *function_type = m_opaque_ptr->GetType();
2375569e64eSGreg Clayton     if (function_type)
2385569e64eSGreg Clayton       sb_type.ref().SetType(function_type->shared_from_this());
2395569e64eSGreg Clayton   }
240*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_type);
2415569e64eSGreg Clayton }
2425569e64eSGreg Clayton 
243b9c1b51eSKate Stone SBBlock SBFunction::GetBlock() {
244*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock, SBFunction, GetBlock);
245*baf5664fSJonas Devlieghere 
2465569e64eSGreg Clayton   SBBlock sb_block;
2475569e64eSGreg Clayton   if (m_opaque_ptr)
2485569e64eSGreg Clayton     sb_block.SetPtr(&m_opaque_ptr->GetBlock(true));
249*baf5664fSJonas Devlieghere   return LLDB_RECORD_RESULT(sb_block);
2505569e64eSGreg Clayton }
2515569e64eSGreg Clayton 
252b9c1b51eSKate Stone lldb::LanguageType SBFunction::GetLanguage() {
253*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::LanguageType, SBFunction, GetLanguage);
254*baf5664fSJonas Devlieghere 
255b9c1b51eSKate Stone   if (m_opaque_ptr) {
2566cd8e0c9SEnrico Granata     if (m_opaque_ptr->GetCompileUnit())
2576cd8e0c9SEnrico Granata       return m_opaque_ptr->GetCompileUnit()->GetLanguage();
2586cd8e0c9SEnrico Granata   }
2596cd8e0c9SEnrico Granata   return lldb::eLanguageTypeUnknown;
2606cd8e0c9SEnrico Granata }
2615569e64eSGreg Clayton 
262b9c1b51eSKate Stone bool SBFunction::GetIsOptimized() {
263*baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBFunction, GetIsOptimized);
264*baf5664fSJonas Devlieghere 
265b9c1b51eSKate Stone   if (m_opaque_ptr) {
2666ab659a9SJason Molenda     if (m_opaque_ptr->GetCompileUnit())
2676ab659a9SJason Molenda       return m_opaque_ptr->GetCompileUnit()->GetIsOptimized();
2686ab659a9SJason Molenda   }
2696ab659a9SJason Molenda   return false;
2706ab659a9SJason Molenda }
271