130fdc8d8SChris Lattner //===-- SBFunction.cpp ------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
930fdc8d8SChris Lattner #include "lldb/API/SBFunction.h"
1030fdc8d8SChris Lattner #include "lldb/API/SBProcess.h"
11dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
121d273166SGreg Clayton #include "lldb/Core/Disassembler.h"
131d273166SGreg Clayton #include "lldb/Core/Module.h"
141d273166SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
1530fdc8d8SChris Lattner #include "lldb/Symbol/Function.h"
1605faeb71SGreg Clayton #include "lldb/Symbol/Type.h"
17fe68904fSGreg Clayton #include "lldb/Symbol/VariableList.h"
181d273166SGreg Clayton #include "lldb/Target/ExecutionContext.h"
191d273166SGreg Clayton #include "lldb/Target/Target.h"
206f9e6901SZachary Turner #include "lldb/Utility/Log.h"
2130fdc8d8SChris Lattner 
2230fdc8d8SChris Lattner using namespace lldb;
231d273166SGreg Clayton using namespace lldb_private;
2430fdc8d8SChris Lattner 
25b9c1b51eSKate Stone SBFunction::SBFunction() : m_opaque_ptr(NULL) {}
2630fdc8d8SChris Lattner 
27b9c1b51eSKate Stone SBFunction::SBFunction(lldb_private::Function *lldb_object_ptr)
28b9c1b51eSKate Stone     : m_opaque_ptr(lldb_object_ptr) {}
2930fdc8d8SChris Lattner 
30b9c1b51eSKate Stone SBFunction::SBFunction(const lldb::SBFunction &rhs)
31b9c1b51eSKate Stone     : m_opaque_ptr(rhs.m_opaque_ptr) {}
32efabb123SGreg Clayton 
33b9c1b51eSKate Stone const SBFunction &SBFunction::operator=(const SBFunction &rhs) {
34efabb123SGreg Clayton   m_opaque_ptr = rhs.m_opaque_ptr;
35efabb123SGreg Clayton   return *this;
36efabb123SGreg Clayton }
37efabb123SGreg Clayton 
38b9c1b51eSKate Stone SBFunction::~SBFunction() { m_opaque_ptr = NULL; }
3930fdc8d8SChris Lattner 
40b9c1b51eSKate Stone bool SBFunction::IsValid() const { return m_opaque_ptr != NULL; }
4130fdc8d8SChris Lattner 
42b9c1b51eSKate Stone const char *SBFunction::GetName() const {
43cfd1acedSGreg Clayton   const char *cstr = NULL;
446611103cSGreg Clayton   if (m_opaque_ptr)
45ddaf6a72SGreg Clayton     cstr = m_opaque_ptr->GetName().AsCString();
46ceb6b139SCaroline Tice 
475160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
48b9c1b51eSKate Stone   if (log) {
49cfd1acedSGreg Clayton     if (cstr)
50324a1036SSaleem Abdulrasool       log->Printf("SBFunction(%p)::GetName () => \"%s\"",
51324a1036SSaleem Abdulrasool                   static_cast<void *>(m_opaque_ptr), cstr);
52cfd1acedSGreg Clayton     else
53324a1036SSaleem Abdulrasool       log->Printf("SBFunction(%p)::GetName () => NULL",
54324a1036SSaleem Abdulrasool                   static_cast<void *>(m_opaque_ptr));
55cfd1acedSGreg Clayton   }
56cfd1acedSGreg Clayton   return cstr;
5730fdc8d8SChris Lattner }
5830fdc8d8SChris Lattner 
59b9c1b51eSKate Stone const char *SBFunction::GetDisplayName() const {
60c1f705c2SEnrico Granata   const char *cstr = NULL;
61c1f705c2SEnrico Granata   if (m_opaque_ptr)
62b9c1b51eSKate Stone     cstr = m_opaque_ptr->GetMangled()
63b9c1b51eSKate Stone                .GetDisplayDemangledName(m_opaque_ptr->GetLanguage())
64b9c1b51eSKate Stone                .AsCString();
65c1f705c2SEnrico Granata 
66c1f705c2SEnrico Granata   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
67b9c1b51eSKate Stone   if (log) {
68c1f705c2SEnrico Granata     if (cstr)
69c1f705c2SEnrico Granata       log->Printf("SBFunction(%p)::GetDisplayName () => \"%s\"",
70c1f705c2SEnrico Granata                   static_cast<void *>(m_opaque_ptr), cstr);
71c1f705c2SEnrico Granata     else
72c1f705c2SEnrico Granata       log->Printf("SBFunction(%p)::GetDisplayName () => NULL",
73c1f705c2SEnrico Granata                   static_cast<void *>(m_opaque_ptr));
74c1f705c2SEnrico Granata   }
75c1f705c2SEnrico Granata   return cstr;
76c1f705c2SEnrico Granata }
77c1f705c2SEnrico Granata 
78b9c1b51eSKate Stone const char *SBFunction::GetMangledName() const {
79cfd1acedSGreg Clayton   const char *cstr = NULL;
806611103cSGreg Clayton   if (m_opaque_ptr)
81cfd1acedSGreg Clayton     cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString();
825160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
83b9c1b51eSKate Stone   if (log) {
84cfd1acedSGreg Clayton     if (cstr)
85324a1036SSaleem Abdulrasool       log->Printf("SBFunction(%p)::GetMangledName () => \"%s\"",
86324a1036SSaleem Abdulrasool                   static_cast<void *>(m_opaque_ptr), cstr);
87cfd1acedSGreg Clayton     else
88324a1036SSaleem Abdulrasool       log->Printf("SBFunction(%p)::GetMangledName () => NULL",
89324a1036SSaleem Abdulrasool                   static_cast<void *>(m_opaque_ptr));
90cfd1acedSGreg Clayton   }
91cfd1acedSGreg Clayton   return cstr;
9230fdc8d8SChris Lattner }
9330fdc8d8SChris Lattner 
94b9c1b51eSKate Stone bool SBFunction::operator==(const SBFunction &rhs) const {
956611103cSGreg Clayton   return m_opaque_ptr == rhs.m_opaque_ptr;
9630fdc8d8SChris Lattner }
9730fdc8d8SChris Lattner 
98b9c1b51eSKate Stone bool SBFunction::operator!=(const SBFunction &rhs) const {
996611103cSGreg Clayton   return m_opaque_ptr != rhs.m_opaque_ptr;
10030fdc8d8SChris Lattner }
101dde9cff3SCaroline Tice 
102b9c1b51eSKate Stone bool SBFunction::GetDescription(SBStream &s) {
103b9c1b51eSKate Stone   if (m_opaque_ptr) {
104d01b2953SDaniel Malea     s.Printf("SBFunction: id = 0x%8.8" PRIx64 ", name = %s",
105b9c1b51eSKate Stone              m_opaque_ptr->GetID(), m_opaque_ptr->GetName().AsCString());
10605faeb71SGreg Clayton     Type *func_type = m_opaque_ptr->GetType();
10705faeb71SGreg Clayton     if (func_type)
10805faeb71SGreg Clayton       s.Printf(", type = %s", func_type->GetName().AsCString());
109dde9cff3SCaroline Tice     return true;
110dde9cff3SCaroline Tice   }
11105faeb71SGreg Clayton   s.Printf("No value");
11205faeb71SGreg Clayton   return false;
11305faeb71SGreg Clayton }
1141d273166SGreg Clayton 
115b9c1b51eSKate Stone SBInstructionList SBFunction::GetInstructions(SBTarget target) {
1160f063ba6SJim Ingham   return GetInstructions(target, NULL);
1170f063ba6SJim Ingham }
1180f063ba6SJim Ingham 
119b9c1b51eSKate Stone SBInstructionList SBFunction::GetInstructions(SBTarget target,
120b9c1b51eSKate Stone                                               const char *flavor) {
1211d273166SGreg Clayton   SBInstructionList sb_instructions;
122b9c1b51eSKate Stone   if (m_opaque_ptr) {
1231d273166SGreg Clayton     ExecutionContext exe_ctx;
124b9556accSGreg Clayton     TargetSP target_sp(target.GetSP());
125bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
126b9c1b51eSKate Stone     if (target_sp) {
127bb19a13cSSaleem Abdulrasool       lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
128b9556accSGreg Clayton       target_sp->CalculateExecutionContext(exe_ctx);
129b9556accSGreg Clayton       exe_ctx.SetProcessSP(target_sp->GetProcessSP());
1301d273166SGreg Clayton     }
131b9c1b51eSKate Stone     ModuleSP module_sp(
132b9c1b51eSKate Stone         m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule());
133b9c1b51eSKate Stone     if (module_sp) {
1346b3e6d54SJason Molenda       const bool prefer_file_cache = false;
135b9c1b51eSKate Stone       sb_instructions.SetDisassembler(Disassembler::DisassembleRange(
136b9c1b51eSKate Stone           module_sp->GetArchitecture(), NULL, flavor, exe_ctx,
137b9c1b51eSKate Stone           m_opaque_ptr->GetAddressRange(), prefer_file_cache));
1381d273166SGreg Clayton     }
1391d273166SGreg Clayton   }
1401d273166SGreg Clayton   return sb_instructions;
1411d273166SGreg Clayton }
1421d273166SGreg Clayton 
143b9c1b51eSKate Stone lldb_private::Function *SBFunction::get() { return m_opaque_ptr; }
1441d273166SGreg Clayton 
145b9c1b51eSKate Stone void SBFunction::reset(lldb_private::Function *lldb_object_ptr) {
14672eff18aSGreg Clayton   m_opaque_ptr = lldb_object_ptr;
14772eff18aSGreg Clayton }
14872eff18aSGreg Clayton 
149b9c1b51eSKate Stone SBAddress SBFunction::GetStartAddress() {
15093d00df5SGreg Clayton   SBAddress addr;
15193d00df5SGreg Clayton   if (m_opaque_ptr)
15293d00df5SGreg Clayton     addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress());
15393d00df5SGreg Clayton   return addr;
15493d00df5SGreg Clayton }
15593d00df5SGreg Clayton 
156b9c1b51eSKate Stone SBAddress SBFunction::GetEndAddress() {
15793d00df5SGreg Clayton   SBAddress addr;
158b9c1b51eSKate Stone   if (m_opaque_ptr) {
15993d00df5SGreg Clayton     addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize();
160b9c1b51eSKate Stone     if (byte_size > 0) {
16193d00df5SGreg Clayton       addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress());
16293d00df5SGreg Clayton       addr->Slide(byte_size);
16393d00df5SGreg Clayton     }
16493d00df5SGreg Clayton   }
16593d00df5SGreg Clayton   return addr;
16693d00df5SGreg Clayton }
16793d00df5SGreg Clayton 
168b9c1b51eSKate Stone const char *SBFunction::GetArgumentName(uint32_t arg_idx) {
169b9c1b51eSKate Stone   if (m_opaque_ptr) {
170fe68904fSGreg Clayton     Block &block = m_opaque_ptr->GetBlock(true);
171fe68904fSGreg Clayton     VariableListSP variable_list_sp = block.GetBlockVariableList(true);
172b9c1b51eSKate Stone     if (variable_list_sp) {
173fe68904fSGreg Clayton       VariableList arguments;
174b9c1b51eSKate Stone       variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
175b9c1b51eSKate Stone                                                  arguments, true);
176fe68904fSGreg Clayton       lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx);
177fe68904fSGreg Clayton       if (variable_sp)
178fe68904fSGreg Clayton         return variable_sp->GetName().GetCString();
179fe68904fSGreg Clayton     }
180fe68904fSGreg Clayton   }
181fe68904fSGreg Clayton   return nullptr;
182fe68904fSGreg Clayton }
18393d00df5SGreg Clayton 
184b9c1b51eSKate Stone uint32_t SBFunction::GetPrologueByteSize() {
18593d00df5SGreg Clayton   if (m_opaque_ptr)
18693d00df5SGreg Clayton     return m_opaque_ptr->GetPrologueByteSize();
18793d00df5SGreg Clayton   return 0;
18893d00df5SGreg Clayton }
18993d00df5SGreg Clayton 
190b9c1b51eSKate Stone SBType SBFunction::GetType() {
1915569e64eSGreg Clayton   SBType sb_type;
192b9c1b51eSKate Stone   if (m_opaque_ptr) {
1935569e64eSGreg Clayton     Type *function_type = m_opaque_ptr->GetType();
1945569e64eSGreg Clayton     if (function_type)
1955569e64eSGreg Clayton       sb_type.ref().SetType(function_type->shared_from_this());
1965569e64eSGreg Clayton   }
1975569e64eSGreg Clayton   return sb_type;
1985569e64eSGreg Clayton }
1995569e64eSGreg Clayton 
200b9c1b51eSKate Stone SBBlock SBFunction::GetBlock() {
2015569e64eSGreg Clayton   SBBlock sb_block;
2025569e64eSGreg Clayton   if (m_opaque_ptr)
2035569e64eSGreg Clayton     sb_block.SetPtr(&m_opaque_ptr->GetBlock(true));
2045569e64eSGreg Clayton   return sb_block;
2055569e64eSGreg Clayton }
2065569e64eSGreg Clayton 
207b9c1b51eSKate Stone lldb::LanguageType SBFunction::GetLanguage() {
208b9c1b51eSKate Stone   if (m_opaque_ptr) {
2096cd8e0c9SEnrico Granata     if (m_opaque_ptr->GetCompileUnit())
2106cd8e0c9SEnrico Granata       return m_opaque_ptr->GetCompileUnit()->GetLanguage();
2116cd8e0c9SEnrico Granata   }
2126cd8e0c9SEnrico Granata   return lldb::eLanguageTypeUnknown;
2136cd8e0c9SEnrico Granata }
2145569e64eSGreg Clayton 
215b9c1b51eSKate Stone bool SBFunction::GetIsOptimized() {
216b9c1b51eSKate Stone   if (m_opaque_ptr) {
2176ab659a9SJason Molenda     if (m_opaque_ptr->GetCompileUnit())
2186ab659a9SJason Molenda       return m_opaque_ptr->GetCompileUnit()->GetIsOptimized();
2196ab659a9SJason Molenda   }
2206ab659a9SJason Molenda   return false;
2216ab659a9SJason Molenda }
222