130fdc8d8SChris Lattner //===-- SBFunction.cpp ------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "lldb/API/SBFunction.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"
21*6f9e6901SZachary Turner #include "lldb/Utility/Log.h"
2230fdc8d8SChris Lattner 
2330fdc8d8SChris Lattner using namespace lldb;
241d273166SGreg Clayton using namespace lldb_private;
2530fdc8d8SChris Lattner 
26b9c1b51eSKate Stone SBFunction::SBFunction() : m_opaque_ptr(NULL) {}
2730fdc8d8SChris Lattner 
28b9c1b51eSKate Stone SBFunction::SBFunction(lldb_private::Function *lldb_object_ptr)
29b9c1b51eSKate Stone     : m_opaque_ptr(lldb_object_ptr) {}
3030fdc8d8SChris Lattner 
31b9c1b51eSKate Stone SBFunction::SBFunction(const lldb::SBFunction &rhs)
32b9c1b51eSKate Stone     : m_opaque_ptr(rhs.m_opaque_ptr) {}
33efabb123SGreg Clayton 
34b9c1b51eSKate Stone const SBFunction &SBFunction::operator=(const SBFunction &rhs) {
35efabb123SGreg Clayton   m_opaque_ptr = rhs.m_opaque_ptr;
36efabb123SGreg Clayton   return *this;
37efabb123SGreg Clayton }
38efabb123SGreg Clayton 
39b9c1b51eSKate Stone SBFunction::~SBFunction() { m_opaque_ptr = NULL; }
4030fdc8d8SChris Lattner 
41b9c1b51eSKate Stone bool SBFunction::IsValid() const { return m_opaque_ptr != NULL; }
4230fdc8d8SChris Lattner 
43b9c1b51eSKate Stone const char *SBFunction::GetName() const {
44cfd1acedSGreg Clayton   const char *cstr = NULL;
456611103cSGreg Clayton   if (m_opaque_ptr)
46ddaf6a72SGreg Clayton     cstr = m_opaque_ptr->GetName().AsCString();
47ceb6b139SCaroline Tice 
485160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
49b9c1b51eSKate Stone   if (log) {
50cfd1acedSGreg Clayton     if (cstr)
51324a1036SSaleem Abdulrasool       log->Printf("SBFunction(%p)::GetName () => \"%s\"",
52324a1036SSaleem Abdulrasool                   static_cast<void *>(m_opaque_ptr), cstr);
53cfd1acedSGreg Clayton     else
54324a1036SSaleem Abdulrasool       log->Printf("SBFunction(%p)::GetName () => NULL",
55324a1036SSaleem Abdulrasool                   static_cast<void *>(m_opaque_ptr));
56cfd1acedSGreg Clayton   }
57cfd1acedSGreg Clayton   return cstr;
5830fdc8d8SChris Lattner }
5930fdc8d8SChris Lattner 
60b9c1b51eSKate Stone const char *SBFunction::GetDisplayName() const {
61c1f705c2SEnrico Granata   const char *cstr = NULL;
62c1f705c2SEnrico Granata   if (m_opaque_ptr)
63b9c1b51eSKate Stone     cstr = m_opaque_ptr->GetMangled()
64b9c1b51eSKate Stone                .GetDisplayDemangledName(m_opaque_ptr->GetLanguage())
65b9c1b51eSKate Stone                .AsCString();
66c1f705c2SEnrico Granata 
67c1f705c2SEnrico Granata   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
68b9c1b51eSKate Stone   if (log) {
69c1f705c2SEnrico Granata     if (cstr)
70c1f705c2SEnrico Granata       log->Printf("SBFunction(%p)::GetDisplayName () => \"%s\"",
71c1f705c2SEnrico Granata                   static_cast<void *>(m_opaque_ptr), cstr);
72c1f705c2SEnrico Granata     else
73c1f705c2SEnrico Granata       log->Printf("SBFunction(%p)::GetDisplayName () => NULL",
74c1f705c2SEnrico Granata                   static_cast<void *>(m_opaque_ptr));
75c1f705c2SEnrico Granata   }
76c1f705c2SEnrico Granata   return cstr;
77c1f705c2SEnrico Granata }
78c1f705c2SEnrico Granata 
79b9c1b51eSKate Stone const char *SBFunction::GetMangledName() const {
80cfd1acedSGreg Clayton   const char *cstr = NULL;
816611103cSGreg Clayton   if (m_opaque_ptr)
82cfd1acedSGreg Clayton     cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString();
835160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
84b9c1b51eSKate Stone   if (log) {
85cfd1acedSGreg Clayton     if (cstr)
86324a1036SSaleem Abdulrasool       log->Printf("SBFunction(%p)::GetMangledName () => \"%s\"",
87324a1036SSaleem Abdulrasool                   static_cast<void *>(m_opaque_ptr), cstr);
88cfd1acedSGreg Clayton     else
89324a1036SSaleem Abdulrasool       log->Printf("SBFunction(%p)::GetMangledName () => NULL",
90324a1036SSaleem Abdulrasool                   static_cast<void *>(m_opaque_ptr));
91cfd1acedSGreg Clayton   }
92cfd1acedSGreg Clayton   return cstr;
9330fdc8d8SChris Lattner }
9430fdc8d8SChris Lattner 
95b9c1b51eSKate Stone bool SBFunction::operator==(const SBFunction &rhs) const {
966611103cSGreg Clayton   return m_opaque_ptr == rhs.m_opaque_ptr;
9730fdc8d8SChris Lattner }
9830fdc8d8SChris Lattner 
99b9c1b51eSKate Stone bool SBFunction::operator!=(const SBFunction &rhs) const {
1006611103cSGreg Clayton   return m_opaque_ptr != rhs.m_opaque_ptr;
10130fdc8d8SChris Lattner }
102dde9cff3SCaroline Tice 
103b9c1b51eSKate Stone bool SBFunction::GetDescription(SBStream &s) {
104b9c1b51eSKate Stone   if (m_opaque_ptr) {
105d01b2953SDaniel Malea     s.Printf("SBFunction: id = 0x%8.8" PRIx64 ", name = %s",
106b9c1b51eSKate Stone              m_opaque_ptr->GetID(), m_opaque_ptr->GetName().AsCString());
10705faeb71SGreg Clayton     Type *func_type = m_opaque_ptr->GetType();
10805faeb71SGreg Clayton     if (func_type)
10905faeb71SGreg Clayton       s.Printf(", type = %s", func_type->GetName().AsCString());
110dde9cff3SCaroline Tice     return true;
111dde9cff3SCaroline Tice   }
11205faeb71SGreg Clayton   s.Printf("No value");
11305faeb71SGreg Clayton   return false;
11405faeb71SGreg Clayton }
1151d273166SGreg Clayton 
116b9c1b51eSKate Stone SBInstructionList SBFunction::GetInstructions(SBTarget target) {
1170f063ba6SJim Ingham   return GetInstructions(target, NULL);
1180f063ba6SJim Ingham }
1190f063ba6SJim Ingham 
120b9c1b51eSKate Stone SBInstructionList SBFunction::GetInstructions(SBTarget target,
121b9c1b51eSKate Stone                                               const char *flavor) {
1221d273166SGreg Clayton   SBInstructionList sb_instructions;
123b9c1b51eSKate Stone   if (m_opaque_ptr) {
1241d273166SGreg Clayton     ExecutionContext exe_ctx;
125b9556accSGreg Clayton     TargetSP target_sp(target.GetSP());
126bb19a13cSSaleem Abdulrasool     std::unique_lock<std::recursive_mutex> lock;
127b9c1b51eSKate Stone     if (target_sp) {
128bb19a13cSSaleem Abdulrasool       lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
129b9556accSGreg Clayton       target_sp->CalculateExecutionContext(exe_ctx);
130b9556accSGreg Clayton       exe_ctx.SetProcessSP(target_sp->GetProcessSP());
1311d273166SGreg Clayton     }
132b9c1b51eSKate Stone     ModuleSP module_sp(
133b9c1b51eSKate Stone         m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule());
134b9c1b51eSKate Stone     if (module_sp) {
1356b3e6d54SJason Molenda       const bool prefer_file_cache = false;
136b9c1b51eSKate Stone       sb_instructions.SetDisassembler(Disassembler::DisassembleRange(
137b9c1b51eSKate Stone           module_sp->GetArchitecture(), NULL, flavor, exe_ctx,
138b9c1b51eSKate Stone           m_opaque_ptr->GetAddressRange(), prefer_file_cache));
1391d273166SGreg Clayton     }
1401d273166SGreg Clayton   }
1411d273166SGreg Clayton   return sb_instructions;
1421d273166SGreg Clayton }
1431d273166SGreg Clayton 
144b9c1b51eSKate Stone lldb_private::Function *SBFunction::get() { return m_opaque_ptr; }
1451d273166SGreg Clayton 
146b9c1b51eSKate Stone void SBFunction::reset(lldb_private::Function *lldb_object_ptr) {
14772eff18aSGreg Clayton   m_opaque_ptr = lldb_object_ptr;
14872eff18aSGreg Clayton }
14972eff18aSGreg Clayton 
150b9c1b51eSKate Stone SBAddress SBFunction::GetStartAddress() {
15193d00df5SGreg Clayton   SBAddress addr;
15293d00df5SGreg Clayton   if (m_opaque_ptr)
15393d00df5SGreg Clayton     addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress());
15493d00df5SGreg Clayton   return addr;
15593d00df5SGreg Clayton }
15693d00df5SGreg Clayton 
157b9c1b51eSKate Stone SBAddress SBFunction::GetEndAddress() {
15893d00df5SGreg Clayton   SBAddress addr;
159b9c1b51eSKate Stone   if (m_opaque_ptr) {
16093d00df5SGreg Clayton     addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize();
161b9c1b51eSKate Stone     if (byte_size > 0) {
16293d00df5SGreg Clayton       addr.SetAddress(&m_opaque_ptr->GetAddressRange().GetBaseAddress());
16393d00df5SGreg Clayton       addr->Slide(byte_size);
16493d00df5SGreg Clayton     }
16593d00df5SGreg Clayton   }
16693d00df5SGreg Clayton   return addr;
16793d00df5SGreg Clayton }
16893d00df5SGreg Clayton 
169b9c1b51eSKate Stone const char *SBFunction::GetArgumentName(uint32_t arg_idx) {
170b9c1b51eSKate Stone   if (m_opaque_ptr) {
171fe68904fSGreg Clayton     Block &block = m_opaque_ptr->GetBlock(true);
172fe68904fSGreg Clayton     VariableListSP variable_list_sp = block.GetBlockVariableList(true);
173b9c1b51eSKate Stone     if (variable_list_sp) {
174fe68904fSGreg Clayton       VariableList arguments;
175b9c1b51eSKate Stone       variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
176b9c1b51eSKate Stone                                                  arguments, true);
177fe68904fSGreg Clayton       lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx);
178fe68904fSGreg Clayton       if (variable_sp)
179fe68904fSGreg Clayton         return variable_sp->GetName().GetCString();
180fe68904fSGreg Clayton     }
181fe68904fSGreg Clayton   }
182fe68904fSGreg Clayton   return nullptr;
183fe68904fSGreg Clayton }
18493d00df5SGreg Clayton 
185b9c1b51eSKate Stone uint32_t SBFunction::GetPrologueByteSize() {
18693d00df5SGreg Clayton   if (m_opaque_ptr)
18793d00df5SGreg Clayton     return m_opaque_ptr->GetPrologueByteSize();
18893d00df5SGreg Clayton   return 0;
18993d00df5SGreg Clayton }
19093d00df5SGreg Clayton 
191b9c1b51eSKate Stone SBType SBFunction::GetType() {
1925569e64eSGreg Clayton   SBType sb_type;
193b9c1b51eSKate Stone   if (m_opaque_ptr) {
1945569e64eSGreg Clayton     Type *function_type = m_opaque_ptr->GetType();
1955569e64eSGreg Clayton     if (function_type)
1965569e64eSGreg Clayton       sb_type.ref().SetType(function_type->shared_from_this());
1975569e64eSGreg Clayton   }
1985569e64eSGreg Clayton   return sb_type;
1995569e64eSGreg Clayton }
2005569e64eSGreg Clayton 
201b9c1b51eSKate Stone SBBlock SBFunction::GetBlock() {
2025569e64eSGreg Clayton   SBBlock sb_block;
2035569e64eSGreg Clayton   if (m_opaque_ptr)
2045569e64eSGreg Clayton     sb_block.SetPtr(&m_opaque_ptr->GetBlock(true));
2055569e64eSGreg Clayton   return sb_block;
2065569e64eSGreg Clayton }
2075569e64eSGreg Clayton 
208b9c1b51eSKate Stone lldb::LanguageType SBFunction::GetLanguage() {
209b9c1b51eSKate Stone   if (m_opaque_ptr) {
2106cd8e0c9SEnrico Granata     if (m_opaque_ptr->GetCompileUnit())
2116cd8e0c9SEnrico Granata       return m_opaque_ptr->GetCompileUnit()->GetLanguage();
2126cd8e0c9SEnrico Granata   }
2136cd8e0c9SEnrico Granata   return lldb::eLanguageTypeUnknown;
2146cd8e0c9SEnrico Granata }
2155569e64eSGreg Clayton 
216b9c1b51eSKate Stone bool SBFunction::GetIsOptimized() {
217b9c1b51eSKate Stone   if (m_opaque_ptr) {
2186ab659a9SJason Molenda     if (m_opaque_ptr->GetCompileUnit())
2196ab659a9SJason Molenda       return m_opaque_ptr->GetCompileUnit()->GetIsOptimized();
2206ab659a9SJason Molenda   }
2216ab659a9SJason Molenda   return false;
2226ab659a9SJason Molenda }
223