blob: 33cc0c4e264c217e924e8c39cf7392ca73d37ac6 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Function.cpp --------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Symbol/Function.h"
Greg Clayton44d93782014-01-27 23:43:24 +000011#include "lldb/Core/Disassembler.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "lldb/Core/Module.h"
13#include "lldb/Core/Section.h"
Greg Claytone38a5ed2012-01-05 03:57:59 +000014#include "lldb/Host/Host.h"
Greg Claytona1e5dc82015-08-11 22:53:00 +000015#include "lldb/Symbol/CompilerType.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Symbol/CompileUnit.h"
17#include "lldb/Symbol/LineTable.h"
Sean Callanan72e49402011-08-05 23:43:37 +000018#include "lldb/Symbol/SymbolFile.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Symbol/SymbolVendor.h"
Enrico Granata6754e042015-09-30 23:12:22 +000020#include "lldb/Target/Language.h"
Sean Callanancc427fa2011-07-30 02:42:06 +000021#include "llvm/Support/Casting.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022
Greg Claytonc9800662010-09-10 01:30:46 +000023using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024using namespace lldb_private;
25
26//----------------------------------------------------------------------
27// Basic function information is contained in the FunctionInfo class.
28// It is designed to contain the name, linkage name, and declaration
29// location.
30//----------------------------------------------------------------------
31FunctionInfo::FunctionInfo (const char *name, const Declaration *decl_ptr) :
32 m_name(name),
33 m_declaration(decl_ptr)
34{
35}
36
37
38FunctionInfo::FunctionInfo (const ConstString& name, const Declaration *decl_ptr) :
39 m_name(name),
40 m_declaration(decl_ptr)
41{
42}
43
44
45FunctionInfo::~FunctionInfo()
46{
47}
48
49void
Greg Clayton6dbd3982010-09-15 05:51:24 +000050FunctionInfo::Dump(Stream *s, bool show_fullpaths) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051{
52 if (m_name)
53 *s << ", name = \"" << m_name << "\"";
Greg Clayton6dbd3982010-09-15 05:51:24 +000054 m_declaration.Dump(s, show_fullpaths);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055}
56
57
58int
59FunctionInfo::Compare(const FunctionInfo& a, const FunctionInfo& b)
60{
61 int result = ConstString::Compare(a.GetName(), b.GetName());
62 if (result)
63 return result;
64
65 return Declaration::Compare(a.m_declaration, b.m_declaration);
66}
67
68
69Declaration&
70FunctionInfo::GetDeclaration()
71{
72 return m_declaration;
73}
74
75const Declaration&
76FunctionInfo::GetDeclaration() const
77{
78 return m_declaration;
79}
80
Greg Claytonddaf6a72015-07-08 22:32:23 +000081ConstString
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082FunctionInfo::GetName() const
83{
84 return m_name;
85}
86
87size_t
88FunctionInfo::MemorySize() const
89{
90 return m_name.MemorySize() + m_declaration.MemorySize();
91}
92
93
94InlineFunctionInfo::InlineFunctionInfo
95(
96 const char *name,
97 const char *mangled,
98 const Declaration *decl_ptr,
99 const Declaration *call_decl_ptr
100) :
101 FunctionInfo(name, decl_ptr),
Greg Clayton037520e2012-07-18 23:18:10 +0000102 m_mangled(ConstString(mangled), true),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103 m_call_decl (call_decl_ptr)
104{
105}
106
107InlineFunctionInfo::InlineFunctionInfo
108(
109 const ConstString& name,
110 const Mangled &mangled,
111 const Declaration *decl_ptr,
112 const Declaration *call_decl_ptr
113) :
114 FunctionInfo(name, decl_ptr),
115 m_mangled(mangled),
116 m_call_decl (call_decl_ptr)
117{
118}
119
120InlineFunctionInfo::~InlineFunctionInfo()
121{
122}
123
124int
125InlineFunctionInfo::Compare(const InlineFunctionInfo& a, const InlineFunctionInfo& b)
126{
127
128 int result = FunctionInfo::Compare(a, b);
129 if (result)
130 return result;
131 // only compare the mangled names if both have them
132 return Mangled::Compare(a.m_mangled, a.m_mangled);
133}
134
135void
Greg Clayton6dbd3982010-09-15 05:51:24 +0000136InlineFunctionInfo::Dump(Stream *s, bool show_fullpaths) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137{
Greg Clayton6dbd3982010-09-15 05:51:24 +0000138 FunctionInfo::Dump(s, show_fullpaths);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139 if (m_mangled)
140 m_mangled.Dump(s);
141}
142
143void
Greg Claytonddaf6a72015-07-08 22:32:23 +0000144InlineFunctionInfo::DumpStopContext (Stream *s, LanguageType language) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145{
146// s->Indent("[inlined] ");
147 s->Indent();
148 if (m_mangled)
Greg Claytonddaf6a72015-07-08 22:32:23 +0000149 s->PutCString (m_mangled.GetName(language).AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150 else
151 s->PutCString (m_name.AsCString());
152}
153
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000154
Greg Claytonddaf6a72015-07-08 22:32:23 +0000155ConstString
156InlineFunctionInfo::GetName (LanguageType language) const
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000157{
158 if (m_mangled)
Greg Claytonddaf6a72015-07-08 22:32:23 +0000159 return m_mangled.GetName(language);
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000160 return m_name;
161}
162
Enrico Granatac1f705c2015-07-06 18:28:46 +0000163ConstString
Greg Claytonddaf6a72015-07-08 22:32:23 +0000164InlineFunctionInfo::GetDisplayName (LanguageType language) const
Enrico Granatac1f705c2015-07-06 18:28:46 +0000165{
166 if (m_mangled)
Greg Claytonddaf6a72015-07-08 22:32:23 +0000167 return m_mangled.GetDisplayDemangledName(language);
Enrico Granatac1f705c2015-07-06 18:28:46 +0000168 return m_name;
169}
Greg Clayton1b72fcb2010-08-24 00:45:41 +0000170
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171Declaration &
172InlineFunctionInfo::GetCallSite ()
173{
174 return m_call_decl;
175}
176
177const Declaration &
178InlineFunctionInfo::GetCallSite () const
179{
180 return m_call_decl;
181}
182
183
184Mangled&
185InlineFunctionInfo::GetMangled()
186{
187 return m_mangled;
188}
189
190const Mangled&
191InlineFunctionInfo::GetMangled() const
192{
193 return m_mangled;
194}
195
196size_t
197InlineFunctionInfo::MemorySize() const
198{
199 return FunctionInfo::MemorySize() + m_mangled.MemorySize();
200}
201
202//----------------------------------------------------------------------
203//
204//----------------------------------------------------------------------
205Function::Function
206(
207 CompileUnit *comp_unit,
208 lldb::user_id_t func_uid,
209 lldb::user_id_t type_uid,
210 const Mangled &mangled,
211 Type * type,
212 const AddressRange& range
213) :
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000214 UserID (func_uid),
215 m_comp_unit (comp_unit),
216 m_type_uid (type_uid),
217 m_type (type),
218 m_mangled (mangled),
219 m_block (func_uid),
220 m_range (range),
Tamas Berghammer35d9d2d2015-08-25 11:46:06 +0000221 m_frame_base (nullptr),
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000222 m_flags (),
223 m_prologue_byte_size (0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224{
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000225 m_block.SetParentScope(this);
Ed Masted4612ad2014-04-20 13:17:36 +0000226 assert(comp_unit != nullptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000227}
228
229Function::Function
230(
231 CompileUnit *comp_unit,
232 lldb::user_id_t func_uid,
233 lldb::user_id_t type_uid,
234 const char *mangled,
235 Type *type,
236 const AddressRange &range
237) :
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000238 UserID (func_uid),
239 m_comp_unit (comp_unit),
240 m_type_uid (type_uid),
241 m_type (type),
Greg Clayton037520e2012-07-18 23:18:10 +0000242 m_mangled (ConstString(mangled), true),
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000243 m_block (func_uid),
244 m_range (range),
Tamas Berghammer35d9d2d2015-08-25 11:46:06 +0000245 m_frame_base (nullptr),
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000246 m_flags (),
247 m_prologue_byte_size (0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000248{
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000249 m_block.SetParentScope(this);
Ed Masted4612ad2014-04-20 13:17:36 +0000250 assert(comp_unit != nullptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251}
252
253
254Function::~Function()
255{
256}
257
Jim Ingham99760332010-08-20 01:15:01 +0000258void
259Function::GetStartLineSourceInfo (FileSpec &source_file, uint32_t &line_no)
260{
261 line_no = 0;
262 source_file.Clear();
263
Ed Masted4612ad2014-04-20 13:17:36 +0000264 if (m_comp_unit == nullptr)
Jim Ingham99760332010-08-20 01:15:01 +0000265 return;
266
Ed Masted4612ad2014-04-20 13:17:36 +0000267 if (m_type != nullptr && m_type->GetDeclaration().GetLine() != 0)
Jim Ingham99760332010-08-20 01:15:01 +0000268 {
269 source_file = m_type->GetDeclaration().GetFile();
270 line_no = m_type->GetDeclaration().GetLine();
271 }
272 else
273 {
274 LineTable *line_table = m_comp_unit->GetLineTable();
Ed Masted4612ad2014-04-20 13:17:36 +0000275 if (line_table == nullptr)
Jim Ingham99760332010-08-20 01:15:01 +0000276 return;
277
278 LineEntry line_entry;
Ed Masted4612ad2014-04-20 13:17:36 +0000279 if (line_table->FindLineEntryByAddress (GetAddressRange().GetBaseAddress(), line_entry, nullptr))
Jim Ingham99760332010-08-20 01:15:01 +0000280 {
281 line_no = line_entry.line;
282 source_file = line_entry.file;
283 }
284 }
285}
286
287void
288Function::GetEndLineSourceInfo (FileSpec &source_file, uint32_t &line_no)
289{
290 line_no = 0;
291 source_file.Clear();
292
293 // The -1 is kind of cheesy, but I want to get the last line entry for the given function, not the
294 // first entry of the next.
295 Address scratch_addr(GetAddressRange().GetBaseAddress());
296 scratch_addr.SetOffset (scratch_addr.GetOffset() + GetAddressRange().GetByteSize() - 1);
297
298 LineTable *line_table = m_comp_unit->GetLineTable();
Ed Masted4612ad2014-04-20 13:17:36 +0000299 if (line_table == nullptr)
Jim Ingham99760332010-08-20 01:15:01 +0000300 return;
301
302 LineEntry line_entry;
Ed Masted4612ad2014-04-20 13:17:36 +0000303 if (line_table->FindLineEntryByAddress (scratch_addr, line_entry, nullptr))
Jim Ingham99760332010-08-20 01:15:01 +0000304 {
305 line_no = line_entry.line;
306 source_file = line_entry.file;
307 }
308}
309
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000310Block &
311Function::GetBlock (bool can_create)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312{
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000313 if (!m_block.BlockInfoHasBeenParsed() && can_create)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314 {
315 SymbolContext sc;
316 CalculateSymbolContext(&sc);
Greg Clayton17cc8b92011-06-24 03:47:23 +0000317 if (sc.module_sp)
318 {
319 sc.module_sp->GetSymbolVendor()->ParseFunctionBlocks(sc);
320 }
321 else
322 {
Greg Claytone38a5ed2012-01-05 03:57:59 +0000323 Host::SystemLog (Host::eSystemLogError,
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000324 "error: unable to find module shared pointer for function '%s' in %s\n",
Greg Claytone38a5ed2012-01-05 03:57:59 +0000325 GetName().GetCString(),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000326 m_comp_unit->GetPath().c_str());
Greg Clayton17cc8b92011-06-24 03:47:23 +0000327 }
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000328 m_block.SetBlockInfoHasBeenParsed (true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000329 }
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000330 return m_block;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331}
332
333CompileUnit*
334Function::GetCompileUnit()
335{
336 return m_comp_unit;
337}
338
339const CompileUnit*
340Function::GetCompileUnit() const
341{
342 return m_comp_unit;
343}
344
Greg Clayton0c5cd902010-06-28 21:30:43 +0000345
346void
Greg Claytonf5e56de2010-09-14 23:36:40 +0000347Function::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target)
Greg Clayton0c5cd902010-06-28 21:30:43 +0000348{
349 Type* func_type = GetType();
Jim Ingham28eb5712012-10-12 17:34:26 +0000350 const char *name = func_type ? func_type->GetName().AsCString() : "<unknown>";
351
352 *s << "id = " << (const UserID&)*this << ", name = \"" << name << "\", range = ";
Greg Claytonc9800662010-09-10 01:30:46 +0000353
354 Address::DumpStyle fallback_style;
355 if (level == eDescriptionLevelVerbose)
356 fallback_style = Address::DumpStyleModuleWithFileAddress;
357 else
358 fallback_style = Address::DumpStyleFileAddress;
Greg Claytonf5e56de2010-09-14 23:36:40 +0000359 GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, fallback_style);
Greg Clayton0c5cd902010-06-28 21:30:43 +0000360}
361
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362void
363Function::Dump(Stream *s, bool show_context) const
364{
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000365 s->Printf("%p: ", static_cast<const void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366 s->Indent();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000367 *s << "Function" << static_cast<const UserID&>(*this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368
369 m_mangled.Dump(s);
370
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000371 if (m_type)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000372 s->Printf(", type = %p", static_cast<void*>(m_type));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373 else if (m_type_uid != LLDB_INVALID_UID)
Daniel Malead01b2952012-11-29 21:49:15 +0000374 s->Printf(", type_uid = 0x%8.8" PRIx64, m_type_uid);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375
376 s->EOL();
377 // Dump the root object
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000378 if (m_block.BlockInfoHasBeenParsed ())
379 m_block.Dump(s, m_range.GetBaseAddress().GetFileAddress(), INT_MAX, show_context);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380}
381
382
383void
384Function::CalculateSymbolContext(SymbolContext* sc)
385{
386 sc->function = this;
387 m_comp_unit->CalculateSymbolContext(sc);
388}
389
Greg Claytone72dfb32012-02-24 01:59:29 +0000390ModuleSP
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000391Function::CalculateSymbolContextModule ()
392{
Greg Claytone72dfb32012-02-24 01:59:29 +0000393 SectionSP section_sp (m_range.GetBaseAddress().GetSection());
394 if (section_sp)
Greg Clayton9422dd62013-03-04 21:46:16 +0000395 return section_sp->GetModule();
Jim Ingham881ec852011-10-07 22:20:35 +0000396
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000397 return this->GetCompileUnit()->GetModule();
398}
399
400CompileUnit *
401Function::CalculateSymbolContextCompileUnit ()
402{
403 return this->GetCompileUnit();
404}
405
406Function *
407Function::CalculateSymbolContextFunction ()
408{
409 return this;
410}
411
Greg Clayton44d93782014-01-27 23:43:24 +0000412lldb::DisassemblerSP
413Function::GetInstructions (const ExecutionContext &exe_ctx,
414 const char *flavor,
415 bool prefer_file_cache)
416{
417 ModuleSP module_sp (GetAddressRange().GetBaseAddress().GetModule());
418 if (module_sp)
419 {
420 const bool prefer_file_cache = false;
421 return Disassembler::DisassembleRange (module_sp->GetArchitecture(),
Ed Masted4612ad2014-04-20 13:17:36 +0000422 nullptr,
Greg Clayton44d93782014-01-27 23:43:24 +0000423 flavor,
424 exe_ctx,
425 GetAddressRange(),
426 prefer_file_cache);
427 }
428 return lldb::DisassemblerSP();
429}
430
431bool
432Function::GetDisassembly (const ExecutionContext &exe_ctx,
433 const char *flavor,
434 bool prefer_file_cache,
435 Stream &strm)
436{
437 lldb::DisassemblerSP disassembler_sp = GetInstructions (exe_ctx, flavor, prefer_file_cache);
438 if (disassembler_sp)
439 {
440 const bool show_address = true;
441 const bool show_bytes = false;
442 disassembler_sp->GetInstructionList().Dump (&strm, show_address, show_bytes, &exe_ctx);
443 return true;
444 }
445 return false;
446}
447
448
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000449//Symbol *
450//Function::CalculateSymbolContextSymbol ()
451//{
452// return // TODO: find the symbol for the function???
453//}
454
455
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456void
457Function::DumpSymbolContext(Stream *s)
458{
459 m_comp_unit->DumpSymbolContext(s);
Daniel Malead01b2952012-11-29 21:49:15 +0000460 s->Printf(", Function{0x%8.8" PRIx64 "}", GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461}
462
463size_t
464Function::MemorySize () const
465{
Greg Clayton0b76a2c2010-08-21 02:22:51 +0000466 size_t mem_size = sizeof(Function) + m_block.MemorySize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467 return mem_size;
468}
469
Jason Molenda6ab659a2015-07-29 00:42:47 +0000470bool
471Function::GetIsOptimized ()
472{
473 bool result = false;
474
475 // Currently optimization is only indicted by the
476 // vendor extension DW_AT_APPLE_optimized which
477 // is set on a compile unit level.
478 if (m_comp_unit)
479 {
480 result = m_comp_unit->GetIsOptimized();
481 }
482 return result;
483}
484
Enrico Granata6754e042015-09-30 23:12:22 +0000485bool
486Function::IsTopLevelFunction ()
487{
488 bool result = false;
489
490 if (Language* language = Language::FindPlugin(GetLanguage()))
491 result = language->IsTopLevelFunction(*this);
492
493 return result;
494}
495
Enrico Granatac1f705c2015-07-06 18:28:46 +0000496ConstString
497Function::GetDisplayName () const
498{
499 if (!m_mangled)
500 return ConstString();
Greg Claytonddaf6a72015-07-08 22:32:23 +0000501 return m_mangled.GetDisplayDemangledName(GetLanguage());
Enrico Granatac1f705c2015-07-06 18:28:46 +0000502}
503
Greg Clayton99558cc42015-08-24 23:46:31 +0000504CompilerDeclContext
505Function::GetDeclContext()
Sean Callanan72e49402011-08-05 23:43:37 +0000506{
Greg Clayton99558cc42015-08-24 23:46:31 +0000507 ModuleSP module_sp = CalculateSymbolContextModule ();
508
509 if (module_sp)
510 {
511 SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
512
513 if (sym_vendor)
514 {
515 SymbolFile *sym_file = sym_vendor->GetSymbolFile();
516
517 if (sym_file)
518 return sym_file->GetDeclContextForUID (GetID());
519 }
520 }
521 return CompilerDeclContext();
Sean Callanan72e49402011-08-05 23:43:37 +0000522}
523
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524Type*
525Function::GetType()
526{
Ed Masted4612ad2014-04-20 13:17:36 +0000527 if (m_type == nullptr)
Greg Clayton2bc22f82011-09-30 03:20:47 +0000528 {
529 SymbolContext sc;
530
531 CalculateSymbolContext (&sc);
532
533 if (!sc.module_sp)
Ed Masted4612ad2014-04-20 13:17:36 +0000534 return nullptr;
Greg Clayton2bc22f82011-09-30 03:20:47 +0000535
536 SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor();
537
Ed Masted4612ad2014-04-20 13:17:36 +0000538 if (sym_vendor == nullptr)
539 return nullptr;
Greg Clayton2bc22f82011-09-30 03:20:47 +0000540
541 SymbolFile *sym_file = sym_vendor->GetSymbolFile();
542
Ed Masted4612ad2014-04-20 13:17:36 +0000543 if (sym_file == nullptr)
544 return nullptr;
Greg Clayton2bc22f82011-09-30 03:20:47 +0000545
Greg Clayton5cf58b92011-10-05 22:22:08 +0000546 m_type = sym_file->ResolveTypeUID(m_type_uid);
Greg Clayton2bc22f82011-09-30 03:20:47 +0000547 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000548 return m_type;
549}
550
551const Type*
552Function::GetType() const
553{
554 return m_type;
555}
556
Greg Claytona1e5dc82015-08-11 22:53:00 +0000557CompilerType
Greg Clayton99558cc42015-08-24 23:46:31 +0000558Function::GetCompilerType()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000559{
Greg Clayton57ee3062013-07-11 22:46:58 +0000560 Type *function_type = GetType();
561 if (function_type)
Greg Clayton99558cc42015-08-24 23:46:31 +0000562 return function_type->GetFullCompilerType ();
Greg Claytona1e5dc82015-08-11 22:53:00 +0000563 return CompilerType();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000564}
565
566uint32_t
567Function::GetPrologueByteSize ()
568{
569 if (m_prologue_byte_size == 0 && m_flags.IsClear(flagsCalculatedPrologueSize))
570 {
571 m_flags.Set(flagsCalculatedPrologueSize);
572 LineTable* line_table = m_comp_unit->GetLineTable ();
573 if (line_table)
574 {
Greg Clayton83b6fab2012-04-26 01:01:34 +0000575 LineEntry first_line_entry;
576 uint32_t first_line_entry_idx = UINT32_MAX;
577 if (line_table->FindLineEntryByAddress(GetAddressRange().GetBaseAddress(), first_line_entry, &first_line_entry_idx))
Greg Claytonc3b84992010-11-11 20:13:30 +0000578 {
Greg Clayton83b6fab2012-04-26 01:01:34 +0000579 // Make sure the first line entry isn't already the end of the prologue
580 addr_t prologue_end_file_addr = LLDB_INVALID_ADDRESS;
581 if (first_line_entry.is_prologue_end)
582 {
583 prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress();
584 }
585 else
586 {
587 // Check the first few instructions and look for one that has
588 // is_prologue_end set to true.
589 const uint32_t last_line_entry_idx = first_line_entry_idx + 6;
Greg Clayton83b6fab2012-04-26 01:01:34 +0000590 for (uint32_t idx = first_line_entry_idx + 1; idx < last_line_entry_idx; ++idx)
591 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000592 LineEntry line_entry;
Greg Clayton83b6fab2012-04-26 01:01:34 +0000593 if (line_table->GetLineEntryAtIndex (idx, line_entry))
594 {
595 if (line_entry.is_prologue_end)
596 {
597 prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress();
598 break;
599 }
600 }
601 }
602 }
Michael Sartaina7499c92013-07-01 19:45:50 +0000603
Greg Clayton83b6fab2012-04-26 01:01:34 +0000604 // If we didn't find the end of the prologue in the line tables,
605 // then just use the end address of the first line table entry
606 if (prologue_end_file_addr == LLDB_INVALID_ADDRESS)
607 {
Michael Sartaina7499c92013-07-01 19:45:50 +0000608 // Check the first few instructions and look for one that has
609 // a line number that's different than the first entry.
610 const uint32_t last_line_entry_idx = first_line_entry_idx + 6;
611 for (uint32_t idx = first_line_entry_idx + 1; idx < last_line_entry_idx; ++idx)
612 {
613 LineEntry line_entry;
614 if (line_table->GetLineEntryAtIndex (idx, line_entry))
615 {
616 if (line_entry.line != first_line_entry.line)
617 {
618 prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress();
619 break;
620 }
621 }
622 }
623
624 if (prologue_end_file_addr == LLDB_INVALID_ADDRESS)
625 {
626 prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress() + first_line_entry.range.GetByteSize();
627 }
Greg Clayton83b6fab2012-04-26 01:01:34 +0000628 }
Greg Claytonc3b84992010-11-11 20:13:30 +0000629 const addr_t func_start_file_addr = m_range.GetBaseAddress().GetFileAddress();
Greg Clayton83b6fab2012-04-26 01:01:34 +0000630 const addr_t func_end_file_addr = func_start_file_addr + m_range.GetByteSize();
631
632 // Verify that this prologue end file address in the function's
633 // address range just to be sure
634 if (func_start_file_addr < prologue_end_file_addr && prologue_end_file_addr < func_end_file_addr)
635 {
636 m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
637 }
Greg Claytonc3b84992010-11-11 20:13:30 +0000638 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000639 }
640 }
641 return m_prologue_byte_size;
642}
643
Greg Claytonddaf6a72015-07-08 22:32:23 +0000644lldb::LanguageType
645Function::GetLanguage() const
646{
647 if (m_comp_unit)
648 return m_comp_unit->GetLanguage();
649 else
650 return lldb::eLanguageTypeUnknown;
651}
652
653ConstString
654Function::GetName() const
655{
656 LanguageType language = lldb::eLanguageTypeUnknown;
657 if (m_comp_unit)
658 language = m_comp_unit->GetLanguage();
659 return m_mangled.GetName(language);
660}
661
662ConstString
663Function::GetNameNoArguments() const
664{
665 LanguageType language = lldb::eLanguageTypeUnknown;
666 if (m_comp_unit)
667 language = m_comp_unit->GetLanguage();
668 return m_mangled.GetName(language, Mangled::ePreferDemangledWithoutArguments);
669}
670
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000671
672