1254721Semaste//===-- Function.cpp --------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Symbol/Function.h"
11254721Semaste#include "lldb/Core/Module.h"
12254721Semaste#include "lldb/Core/Section.h"
13254721Semaste#include "lldb/Host/Host.h"
14254721Semaste#include "lldb/Symbol/ClangASTType.h"
15254721Semaste#include "lldb/Symbol/CompileUnit.h"
16254721Semaste#include "lldb/Symbol/LineTable.h"
17254721Semaste#include "lldb/Symbol/SymbolFile.h"
18254721Semaste#include "lldb/Symbol/SymbolVendor.h"
19254721Semaste#include "llvm/Support/Casting.h"
20254721Semaste
21254721Semasteusing namespace lldb;
22254721Semasteusing namespace lldb_private;
23254721Semaste
24254721Semaste//----------------------------------------------------------------------
25254721Semaste// Basic function information is contained in the FunctionInfo class.
26254721Semaste// It is designed to contain the name, linkage name, and declaration
27254721Semaste// location.
28254721Semaste//----------------------------------------------------------------------
29254721SemasteFunctionInfo::FunctionInfo (const char *name, const Declaration *decl_ptr) :
30254721Semaste    m_name(name),
31254721Semaste    m_declaration(decl_ptr)
32254721Semaste{
33254721Semaste}
34254721Semaste
35254721Semaste
36254721SemasteFunctionInfo::FunctionInfo (const ConstString& name, const Declaration *decl_ptr) :
37254721Semaste    m_name(name),
38254721Semaste    m_declaration(decl_ptr)
39254721Semaste{
40254721Semaste}
41254721Semaste
42254721Semaste
43254721SemasteFunctionInfo::~FunctionInfo()
44254721Semaste{
45254721Semaste}
46254721Semaste
47254721Semastevoid
48254721SemasteFunctionInfo::Dump(Stream *s, bool show_fullpaths) const
49254721Semaste{
50254721Semaste    if (m_name)
51254721Semaste        *s << ", name = \"" << m_name << "\"";
52254721Semaste    m_declaration.Dump(s, show_fullpaths);
53254721Semaste}
54254721Semaste
55254721Semaste
56254721Semasteint
57254721SemasteFunctionInfo::Compare(const FunctionInfo& a, const FunctionInfo& b)
58254721Semaste{
59254721Semaste    int result = ConstString::Compare(a.GetName(), b.GetName());
60254721Semaste    if (result)
61254721Semaste        return result;
62254721Semaste
63254721Semaste    return Declaration::Compare(a.m_declaration, b.m_declaration);
64254721Semaste}
65254721Semaste
66254721Semaste
67254721SemasteDeclaration&
68254721SemasteFunctionInfo::GetDeclaration()
69254721Semaste{
70254721Semaste    return m_declaration;
71254721Semaste}
72254721Semaste
73254721Semasteconst Declaration&
74254721SemasteFunctionInfo::GetDeclaration() const
75254721Semaste{
76254721Semaste    return m_declaration;
77254721Semaste}
78254721Semaste
79254721Semasteconst ConstString&
80254721SemasteFunctionInfo::GetName() const
81254721Semaste{
82254721Semaste    return m_name;
83254721Semaste}
84254721Semaste
85254721Semastesize_t
86254721SemasteFunctionInfo::MemorySize() const
87254721Semaste{
88254721Semaste    return m_name.MemorySize() + m_declaration.MemorySize();
89254721Semaste}
90254721Semaste
91254721Semaste
92254721SemasteInlineFunctionInfo::InlineFunctionInfo
93254721Semaste(
94254721Semaste    const char *name,
95254721Semaste    const char *mangled,
96254721Semaste    const Declaration *decl_ptr,
97254721Semaste    const Declaration *call_decl_ptr
98254721Semaste) :
99254721Semaste    FunctionInfo(name, decl_ptr),
100254721Semaste    m_mangled(ConstString(mangled), true),
101254721Semaste    m_call_decl (call_decl_ptr)
102254721Semaste{
103254721Semaste}
104254721Semaste
105254721SemasteInlineFunctionInfo::InlineFunctionInfo
106254721Semaste(
107254721Semaste    const ConstString& name,
108254721Semaste    const Mangled &mangled,
109254721Semaste    const Declaration *decl_ptr,
110254721Semaste    const Declaration *call_decl_ptr
111254721Semaste) :
112254721Semaste    FunctionInfo(name, decl_ptr),
113254721Semaste    m_mangled(mangled),
114254721Semaste    m_call_decl (call_decl_ptr)
115254721Semaste{
116254721Semaste}
117254721Semaste
118254721SemasteInlineFunctionInfo::~InlineFunctionInfo()
119254721Semaste{
120254721Semaste}
121254721Semaste
122254721Semasteint
123254721SemasteInlineFunctionInfo::Compare(const InlineFunctionInfo& a, const InlineFunctionInfo& b)
124254721Semaste{
125254721Semaste
126254721Semaste    int result = FunctionInfo::Compare(a, b);
127254721Semaste    if (result)
128254721Semaste        return result;
129254721Semaste    // only compare the mangled names if both have them
130254721Semaste    return Mangled::Compare(a.m_mangled, a.m_mangled);
131254721Semaste}
132254721Semaste
133254721Semastevoid
134254721SemasteInlineFunctionInfo::Dump(Stream *s, bool show_fullpaths) const
135254721Semaste{
136254721Semaste    FunctionInfo::Dump(s, show_fullpaths);
137254721Semaste    if (m_mangled)
138254721Semaste        m_mangled.Dump(s);
139254721Semaste}
140254721Semaste
141254721Semastevoid
142254721SemasteInlineFunctionInfo::DumpStopContext (Stream *s) const
143254721Semaste{
144254721Semaste//    s->Indent("[inlined] ");
145254721Semaste    s->Indent();
146254721Semaste    if (m_mangled)
147254721Semaste        s->PutCString (m_mangled.GetName().AsCString());
148254721Semaste    else
149254721Semaste        s->PutCString (m_name.AsCString());
150254721Semaste}
151254721Semaste
152254721Semaste
153254721Semasteconst ConstString &
154254721SemasteInlineFunctionInfo::GetName () const
155254721Semaste{
156254721Semaste    if (m_mangled)
157254721Semaste        return m_mangled.GetName();
158254721Semaste    return m_name;
159254721Semaste}
160254721Semaste
161254721Semaste
162254721SemasteDeclaration &
163254721SemasteInlineFunctionInfo::GetCallSite ()
164254721Semaste{
165254721Semaste    return m_call_decl;
166254721Semaste}
167254721Semaste
168254721Semasteconst Declaration &
169254721SemasteInlineFunctionInfo::GetCallSite () const
170254721Semaste{
171254721Semaste    return m_call_decl;
172254721Semaste}
173254721Semaste
174254721Semaste
175254721SemasteMangled&
176254721SemasteInlineFunctionInfo::GetMangled()
177254721Semaste{
178254721Semaste    return m_mangled;
179254721Semaste}
180254721Semaste
181254721Semasteconst Mangled&
182254721SemasteInlineFunctionInfo::GetMangled() const
183254721Semaste{
184254721Semaste    return m_mangled;
185254721Semaste}
186254721Semaste
187254721Semastesize_t
188254721SemasteInlineFunctionInfo::MemorySize() const
189254721Semaste{
190254721Semaste    return FunctionInfo::MemorySize() + m_mangled.MemorySize();
191254721Semaste}
192254721Semaste
193254721Semaste//----------------------------------------------------------------------
194254721Semaste//
195254721Semaste//----------------------------------------------------------------------
196254721SemasteFunction::Function
197254721Semaste(
198254721Semaste    CompileUnit *comp_unit,
199254721Semaste    lldb::user_id_t func_uid,
200254721Semaste    lldb::user_id_t type_uid,
201254721Semaste    const Mangled &mangled,
202254721Semaste    Type * type,
203254721Semaste    const AddressRange& range
204254721Semaste) :
205254721Semaste    UserID (func_uid),
206254721Semaste    m_comp_unit (comp_unit),
207254721Semaste    m_type_uid (type_uid),
208254721Semaste    m_type (type),
209254721Semaste    m_mangled (mangled),
210254721Semaste    m_block (func_uid),
211254721Semaste    m_range (range),
212254721Semaste    m_frame_base (),
213254721Semaste    m_flags (),
214254721Semaste    m_prologue_byte_size (0)
215254721Semaste{
216254721Semaste    m_block.SetParentScope(this);
217254721Semaste    assert(comp_unit != NULL);
218254721Semaste}
219254721Semaste
220254721SemasteFunction::Function
221254721Semaste(
222254721Semaste    CompileUnit *comp_unit,
223254721Semaste    lldb::user_id_t func_uid,
224254721Semaste    lldb::user_id_t type_uid,
225254721Semaste    const char *mangled,
226254721Semaste    Type *type,
227254721Semaste    const AddressRange &range
228254721Semaste) :
229254721Semaste    UserID (func_uid),
230254721Semaste    m_comp_unit (comp_unit),
231254721Semaste    m_type_uid (type_uid),
232254721Semaste    m_type (type),
233254721Semaste    m_mangled (ConstString(mangled), true),
234254721Semaste    m_block (func_uid),
235254721Semaste    m_range (range),
236254721Semaste    m_frame_base (),
237254721Semaste    m_flags (),
238254721Semaste    m_prologue_byte_size (0)
239254721Semaste{
240254721Semaste    m_block.SetParentScope(this);
241254721Semaste    assert(comp_unit != NULL);
242254721Semaste}
243254721Semaste
244254721Semaste
245254721SemasteFunction::~Function()
246254721Semaste{
247254721Semaste}
248254721Semaste
249254721Semastevoid
250254721SemasteFunction::GetStartLineSourceInfo (FileSpec &source_file, uint32_t &line_no)
251254721Semaste{
252254721Semaste    line_no = 0;
253254721Semaste    source_file.Clear();
254254721Semaste
255254721Semaste    if (m_comp_unit == NULL)
256254721Semaste        return;
257254721Semaste
258254721Semaste    if (m_type != NULL && m_type->GetDeclaration().GetLine() != 0)
259254721Semaste    {
260254721Semaste        source_file = m_type->GetDeclaration().GetFile();
261254721Semaste        line_no = m_type->GetDeclaration().GetLine();
262254721Semaste    }
263254721Semaste    else
264254721Semaste    {
265254721Semaste        LineTable *line_table = m_comp_unit->GetLineTable();
266254721Semaste        if (line_table == NULL)
267254721Semaste            return;
268254721Semaste
269254721Semaste        LineEntry line_entry;
270254721Semaste        if (line_table->FindLineEntryByAddress (GetAddressRange().GetBaseAddress(), line_entry, NULL))
271254721Semaste        {
272254721Semaste            line_no = line_entry.line;
273254721Semaste            source_file = line_entry.file;
274254721Semaste        }
275254721Semaste    }
276254721Semaste}
277254721Semaste
278254721Semastevoid
279254721SemasteFunction::GetEndLineSourceInfo (FileSpec &source_file, uint32_t &line_no)
280254721Semaste{
281254721Semaste    line_no = 0;
282254721Semaste    source_file.Clear();
283254721Semaste
284254721Semaste    // The -1 is kind of cheesy, but I want to get the last line entry for the given function, not the
285254721Semaste    // first entry of the next.
286254721Semaste    Address scratch_addr(GetAddressRange().GetBaseAddress());
287254721Semaste    scratch_addr.SetOffset (scratch_addr.GetOffset() + GetAddressRange().GetByteSize() - 1);
288254721Semaste
289254721Semaste    LineTable *line_table = m_comp_unit->GetLineTable();
290254721Semaste    if (line_table == NULL)
291254721Semaste        return;
292254721Semaste
293254721Semaste    LineEntry line_entry;
294254721Semaste    if (line_table->FindLineEntryByAddress (scratch_addr, line_entry, NULL))
295254721Semaste    {
296254721Semaste        line_no = line_entry.line;
297254721Semaste        source_file = line_entry.file;
298254721Semaste    }
299254721Semaste}
300254721Semaste
301254721SemasteBlock &
302254721SemasteFunction::GetBlock (bool can_create)
303254721Semaste{
304254721Semaste    if (!m_block.BlockInfoHasBeenParsed() && can_create)
305254721Semaste    {
306254721Semaste        SymbolContext sc;
307254721Semaste        CalculateSymbolContext(&sc);
308254721Semaste        if (sc.module_sp)
309254721Semaste        {
310254721Semaste            sc.module_sp->GetSymbolVendor()->ParseFunctionBlocks(sc);
311254721Semaste        }
312254721Semaste        else
313254721Semaste        {
314254721Semaste            Host::SystemLog (Host::eSystemLogError,
315254721Semaste                             "error: unable to find module shared pointer for function '%s' in %s\n",
316254721Semaste                             GetName().GetCString(),
317254721Semaste                             m_comp_unit->GetPath().c_str());
318254721Semaste        }
319254721Semaste        m_block.SetBlockInfoHasBeenParsed (true, true);
320254721Semaste    }
321254721Semaste    return m_block;
322254721Semaste}
323254721Semaste
324254721SemasteCompileUnit*
325254721SemasteFunction::GetCompileUnit()
326254721Semaste{
327254721Semaste    return m_comp_unit;
328254721Semaste}
329254721Semaste
330254721Semasteconst CompileUnit*
331254721SemasteFunction::GetCompileUnit() const
332254721Semaste{
333254721Semaste    return m_comp_unit;
334254721Semaste}
335254721Semaste
336254721Semaste
337254721Semastevoid
338254721SemasteFunction::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target)
339254721Semaste{
340254721Semaste    Type* func_type = GetType();
341254721Semaste    const char *name = func_type ? func_type->GetName().AsCString() : "<unknown>";
342254721Semaste
343254721Semaste    *s << "id = " << (const UserID&)*this << ", name = \"" << name << "\", range = ";
344254721Semaste
345254721Semaste    Address::DumpStyle fallback_style;
346254721Semaste    if (level == eDescriptionLevelVerbose)
347254721Semaste        fallback_style = Address::DumpStyleModuleWithFileAddress;
348254721Semaste    else
349254721Semaste        fallback_style = Address::DumpStyleFileAddress;
350254721Semaste    GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, fallback_style);
351254721Semaste}
352254721Semaste
353254721Semastevoid
354254721SemasteFunction::Dump(Stream *s, bool show_context) const
355254721Semaste{
356254721Semaste    s->Printf("%p: ", this);
357254721Semaste    s->Indent();
358254721Semaste    *s << "Function" << (const UserID&)*this;
359254721Semaste
360254721Semaste    m_mangled.Dump(s);
361254721Semaste
362254721Semaste    if (m_type)
363254721Semaste    {
364254721Semaste        s->Printf(", type = %p", m_type);
365254721Semaste    }
366254721Semaste    else if (m_type_uid != LLDB_INVALID_UID)
367254721Semaste    {
368254721Semaste        s->Printf(", type_uid = 0x%8.8" PRIx64, m_type_uid);
369254721Semaste    }
370254721Semaste
371254721Semaste    s->EOL();
372254721Semaste    // Dump the root object
373254721Semaste    if (m_block.BlockInfoHasBeenParsed ())
374254721Semaste        m_block.Dump(s, m_range.GetBaseAddress().GetFileAddress(), INT_MAX, show_context);
375254721Semaste}
376254721Semaste
377254721Semaste
378254721Semastevoid
379254721SemasteFunction::CalculateSymbolContext(SymbolContext* sc)
380254721Semaste{
381254721Semaste    sc->function = this;
382254721Semaste    m_comp_unit->CalculateSymbolContext(sc);
383254721Semaste}
384254721Semaste
385254721SemasteModuleSP
386254721SemasteFunction::CalculateSymbolContextModule ()
387254721Semaste{
388254721Semaste    SectionSP section_sp (m_range.GetBaseAddress().GetSection());
389254721Semaste    if (section_sp)
390254721Semaste        return section_sp->GetModule();
391254721Semaste
392254721Semaste    return this->GetCompileUnit()->GetModule();
393254721Semaste}
394254721Semaste
395254721SemasteCompileUnit *
396254721SemasteFunction::CalculateSymbolContextCompileUnit ()
397254721Semaste{
398254721Semaste    return this->GetCompileUnit();
399254721Semaste}
400254721Semaste
401254721SemasteFunction *
402254721SemasteFunction::CalculateSymbolContextFunction ()
403254721Semaste{
404254721Semaste    return this;
405254721Semaste}
406254721Semaste
407254721Semaste//Symbol *
408254721Semaste//Function::CalculateSymbolContextSymbol ()
409254721Semaste//{
410254721Semaste//    return // TODO: find the symbol for the function???
411254721Semaste//}
412254721Semaste
413254721Semaste
414254721Semastevoid
415254721SemasteFunction::DumpSymbolContext(Stream *s)
416254721Semaste{
417254721Semaste    m_comp_unit->DumpSymbolContext(s);
418254721Semaste    s->Printf(", Function{0x%8.8" PRIx64 "}", GetID());
419254721Semaste}
420254721Semaste
421254721Semastesize_t
422254721SemasteFunction::MemorySize () const
423254721Semaste{
424254721Semaste    size_t mem_size = sizeof(Function) + m_block.MemorySize();
425254721Semaste    return mem_size;
426254721Semaste}
427254721Semaste
428254721Semasteclang::DeclContext *
429254721SemasteFunction::GetClangDeclContext()
430254721Semaste{
431254721Semaste    SymbolContext sc;
432254721Semaste
433254721Semaste    CalculateSymbolContext (&sc);
434254721Semaste
435254721Semaste    if (!sc.module_sp)
436254721Semaste        return NULL;
437254721Semaste
438254721Semaste    SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor();
439254721Semaste
440254721Semaste    if (!sym_vendor)
441254721Semaste        return NULL;
442254721Semaste
443254721Semaste    SymbolFile *sym_file = sym_vendor->GetSymbolFile();
444254721Semaste
445254721Semaste    if (!sym_file)
446254721Semaste        return NULL;
447254721Semaste
448254721Semaste    return sym_file->GetClangDeclContextForTypeUID (sc, m_uid);
449254721Semaste}
450254721Semaste
451254721SemasteType*
452254721SemasteFunction::GetType()
453254721Semaste{
454254721Semaste    if (m_type == NULL)
455254721Semaste    {
456254721Semaste        SymbolContext sc;
457254721Semaste
458254721Semaste        CalculateSymbolContext (&sc);
459254721Semaste
460254721Semaste        if (!sc.module_sp)
461254721Semaste            return NULL;
462254721Semaste
463254721Semaste        SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor();
464254721Semaste
465254721Semaste        if (sym_vendor == NULL)
466254721Semaste            return NULL;
467254721Semaste
468254721Semaste        SymbolFile *sym_file = sym_vendor->GetSymbolFile();
469254721Semaste
470254721Semaste        if (sym_file == NULL)
471254721Semaste            return NULL;
472254721Semaste
473254721Semaste        m_type = sym_file->ResolveTypeUID(m_type_uid);
474254721Semaste    }
475254721Semaste    return m_type;
476254721Semaste}
477254721Semaste
478254721Semasteconst Type*
479254721SemasteFunction::GetType() const
480254721Semaste{
481254721Semaste    return m_type;
482254721Semaste}
483254721Semaste
484254721SemasteClangASTType
485254721SemasteFunction::GetClangType()
486254721Semaste{
487254721Semaste    Type *function_type = GetType();
488254721Semaste    if (function_type)
489254721Semaste        return function_type->GetClangFullType();
490254721Semaste    return ClangASTType();
491254721Semaste}
492254721Semaste
493254721Semasteuint32_t
494254721SemasteFunction::GetPrologueByteSize ()
495254721Semaste{
496254721Semaste    if (m_prologue_byte_size == 0 && m_flags.IsClear(flagsCalculatedPrologueSize))
497254721Semaste    {
498254721Semaste        m_flags.Set(flagsCalculatedPrologueSize);
499254721Semaste        LineTable* line_table = m_comp_unit->GetLineTable ();
500254721Semaste        if (line_table)
501254721Semaste        {
502254721Semaste            LineEntry first_line_entry;
503254721Semaste            uint32_t first_line_entry_idx = UINT32_MAX;
504254721Semaste            if (line_table->FindLineEntryByAddress(GetAddressRange().GetBaseAddress(), first_line_entry, &first_line_entry_idx))
505254721Semaste            {
506254721Semaste                // Make sure the first line entry isn't already the end of the prologue
507254721Semaste                addr_t prologue_end_file_addr = LLDB_INVALID_ADDRESS;
508254721Semaste                if (first_line_entry.is_prologue_end)
509254721Semaste                {
510254721Semaste                    prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress();
511254721Semaste                }
512254721Semaste                else
513254721Semaste                {
514254721Semaste                    // Check the first few instructions and look for one that has
515254721Semaste                    // is_prologue_end set to true.
516254721Semaste                    const uint32_t last_line_entry_idx = first_line_entry_idx + 6;
517254721Semaste                    for (uint32_t idx = first_line_entry_idx + 1; idx < last_line_entry_idx; ++idx)
518254721Semaste                    {
519254721Semaste                        LineEntry line_entry;
520254721Semaste                        if (line_table->GetLineEntryAtIndex (idx, line_entry))
521254721Semaste                        {
522254721Semaste                            if (line_entry.is_prologue_end)
523254721Semaste                            {
524254721Semaste                                prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress();
525254721Semaste                                break;
526254721Semaste                            }
527254721Semaste                        }
528254721Semaste                    }
529254721Semaste                }
530254721Semaste
531254721Semaste                // If we didn't find the end of the prologue in the line tables,
532254721Semaste                // then just use the end address of the first line table entry
533254721Semaste                if (prologue_end_file_addr == LLDB_INVALID_ADDRESS)
534254721Semaste                {
535254721Semaste                    // Check the first few instructions and look for one that has
536254721Semaste                    // a line number that's different than the first entry.
537254721Semaste                    const uint32_t last_line_entry_idx = first_line_entry_idx + 6;
538254721Semaste                    for (uint32_t idx = first_line_entry_idx + 1; idx < last_line_entry_idx; ++idx)
539254721Semaste                    {
540254721Semaste                        LineEntry line_entry;
541254721Semaste                        if (line_table->GetLineEntryAtIndex (idx, line_entry))
542254721Semaste                        {
543254721Semaste                            if (line_entry.line != first_line_entry.line)
544254721Semaste                            {
545254721Semaste                                prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress();
546254721Semaste                                break;
547254721Semaste                            }
548254721Semaste                        }
549254721Semaste                    }
550254721Semaste
551254721Semaste                    if (prologue_end_file_addr == LLDB_INVALID_ADDRESS)
552254721Semaste                    {
553254721Semaste                        prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress() + first_line_entry.range.GetByteSize();
554254721Semaste                    }
555254721Semaste                }
556254721Semaste                const addr_t func_start_file_addr = m_range.GetBaseAddress().GetFileAddress();
557254721Semaste                const addr_t func_end_file_addr = func_start_file_addr + m_range.GetByteSize();
558254721Semaste
559254721Semaste                // Verify that this prologue end file address in the function's
560254721Semaste                // address range just to be sure
561254721Semaste                if (func_start_file_addr < prologue_end_file_addr && prologue_end_file_addr < func_end_file_addr)
562254721Semaste                {
563254721Semaste                    m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
564254721Semaste                }
565254721Semaste            }
566254721Semaste        }
567254721Semaste    }
568254721Semaste    return m_prologue_byte_size;
569254721Semaste}
570254721Semaste
571254721Semaste
572254721Semaste
573