diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp
index 598af27..06f8ad5 100644
--- a/lldb/source/Symbol/Function.cpp
+++ b/lldb/source/Symbol/Function.cpp
@@ -12,8 +12,8 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Host/Host.h"
-#include "lldb/Symbol/CompilerType.h"
 #include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/CompilerType.h"
 #include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/SymbolVendor.h"
@@ -28,685 +28,508 @@
 // It is designed to contain the name, linkage name, and declaration
 // location.
 //----------------------------------------------------------------------
-FunctionInfo::FunctionInfo (const char *name, const Declaration *decl_ptr) :
-    m_name(name),
-    m_declaration(decl_ptr)
-{
+FunctionInfo::FunctionInfo(const char *name, const Declaration *decl_ptr)
+    : m_name(name), m_declaration(decl_ptr) {}
+
+FunctionInfo::FunctionInfo(const ConstString &name, const Declaration *decl_ptr)
+    : m_name(name), m_declaration(decl_ptr) {}
+
+FunctionInfo::~FunctionInfo() {}
+
+void FunctionInfo::Dump(Stream *s, bool show_fullpaths) const {
+  if (m_name)
+    *s << ", name = \"" << m_name << "\"";
+  m_declaration.Dump(s, show_fullpaths);
 }
 
+int FunctionInfo::Compare(const FunctionInfo &a, const FunctionInfo &b) {
+  int result = ConstString::Compare(a.GetName(), b.GetName());
+  if (result)
+    return result;
 
-FunctionInfo::FunctionInfo (const ConstString& name, const Declaration *decl_ptr) :
-    m_name(name),
-    m_declaration(decl_ptr)
-{
+  return Declaration::Compare(a.m_declaration, b.m_declaration);
 }
 
+Declaration &FunctionInfo::GetDeclaration() { return m_declaration; }
 
-FunctionInfo::~FunctionInfo()
-{
+const Declaration &FunctionInfo::GetDeclaration() const {
+  return m_declaration;
 }
 
-void
-FunctionInfo::Dump(Stream *s, bool show_fullpaths) const
-{
-    if (m_name)
-        *s << ", name = \"" << m_name << "\"";
-    m_declaration.Dump(s, show_fullpaths);
+ConstString FunctionInfo::GetName() const { return m_name; }
+
+size_t FunctionInfo::MemorySize() const {
+  return m_name.MemorySize() + m_declaration.MemorySize();
 }
 
+InlineFunctionInfo::InlineFunctionInfo(const char *name, const char *mangled,
+                                       const Declaration *decl_ptr,
+                                       const Declaration *call_decl_ptr)
+    : FunctionInfo(name, decl_ptr), m_mangled(ConstString(mangled), true),
+      m_call_decl(call_decl_ptr) {}
 
-int
-FunctionInfo::Compare(const FunctionInfo& a, const FunctionInfo& b)
-{
-    int result = ConstString::Compare(a.GetName(), b.GetName());
-    if (result)
-        return result;
+InlineFunctionInfo::InlineFunctionInfo(const ConstString &name,
+                                       const Mangled &mangled,
+                                       const Declaration *decl_ptr,
+                                       const Declaration *call_decl_ptr)
+    : FunctionInfo(name, decl_ptr), m_mangled(mangled),
+      m_call_decl(call_decl_ptr) {}
 
-    return Declaration::Compare(a.m_declaration, b.m_declaration);
+InlineFunctionInfo::~InlineFunctionInfo() {}
+
+int InlineFunctionInfo::Compare(const InlineFunctionInfo &a,
+                                const InlineFunctionInfo &b) {
+
+  int result = FunctionInfo::Compare(a, b);
+  if (result)
+    return result;
+  // only compare the mangled names if both have them
+  return Mangled::Compare(a.m_mangled, a.m_mangled);
 }
 
-
-Declaration&
-FunctionInfo::GetDeclaration()
-{
-    return m_declaration;
+void InlineFunctionInfo::Dump(Stream *s, bool show_fullpaths) const {
+  FunctionInfo::Dump(s, show_fullpaths);
+  if (m_mangled)
+    m_mangled.Dump(s);
 }
 
-const Declaration&
-FunctionInfo::GetDeclaration() const
-{
-    return m_declaration;
+void InlineFunctionInfo::DumpStopContext(Stream *s,
+                                         LanguageType language) const {
+  //    s->Indent("[inlined] ");
+  s->Indent();
+  if (m_mangled)
+    s->PutCString(m_mangled.GetName(language).AsCString());
+  else
+    s->PutCString(m_name.AsCString());
 }
 
-ConstString
-FunctionInfo::GetName() const
-{
-    return m_name;
+ConstString InlineFunctionInfo::GetName(LanguageType language) const {
+  if (m_mangled)
+    return m_mangled.GetName(language);
+  return m_name;
 }
 
-size_t
-FunctionInfo::MemorySize() const
-{
-    return m_name.MemorySize() + m_declaration.MemorySize();
+ConstString InlineFunctionInfo::GetDisplayName(LanguageType language) const {
+  if (m_mangled)
+    return m_mangled.GetDisplayDemangledName(language);
+  return m_name;
 }
 
+Declaration &InlineFunctionInfo::GetCallSite() { return m_call_decl; }
 
-InlineFunctionInfo::InlineFunctionInfo
-(
-    const char *name,
-    const char *mangled,
-    const Declaration *decl_ptr,
-    const Declaration *call_decl_ptr
-) :
-    FunctionInfo(name, decl_ptr),
-    m_mangled(ConstString(mangled), true),
-    m_call_decl (call_decl_ptr)
-{
+const Declaration &InlineFunctionInfo::GetCallSite() const {
+  return m_call_decl;
 }
 
-InlineFunctionInfo::InlineFunctionInfo
-(
-    const ConstString& name,
-    const Mangled &mangled,
-    const Declaration *decl_ptr,
-    const Declaration *call_decl_ptr
-) :
-    FunctionInfo(name, decl_ptr),
-    m_mangled(mangled),
-    m_call_decl (call_decl_ptr)
-{
-}
+Mangled &InlineFunctionInfo::GetMangled() { return m_mangled; }
 
-InlineFunctionInfo::~InlineFunctionInfo()
-{
-}
+const Mangled &InlineFunctionInfo::GetMangled() const { return m_mangled; }
 
-int
-InlineFunctionInfo::Compare(const InlineFunctionInfo& a, const InlineFunctionInfo& b)
-{
-
-    int result = FunctionInfo::Compare(a, b);
-    if (result)
-        return result;
-    // only compare the mangled names if both have them
-    return Mangled::Compare(a.m_mangled, a.m_mangled);
-}
-
-void
-InlineFunctionInfo::Dump(Stream *s, bool show_fullpaths) const
-{
-    FunctionInfo::Dump(s, show_fullpaths);
-    if (m_mangled)
-        m_mangled.Dump(s);
-}
-
-void
-InlineFunctionInfo::DumpStopContext (Stream *s, LanguageType language) const
-{
-//    s->Indent("[inlined] ");
-    s->Indent();
-    if (m_mangled)
-        s->PutCString (m_mangled.GetName(language).AsCString());
-    else
-        s->PutCString (m_name.AsCString());
-}
-
-
-ConstString
-InlineFunctionInfo::GetName (LanguageType language) const
-{
-    if (m_mangled)
-        return m_mangled.GetName(language);
-    return m_name;
-}
-
-ConstString
-InlineFunctionInfo::GetDisplayName (LanguageType language) const
-{
-    if (m_mangled)
-        return m_mangled.GetDisplayDemangledName(language);
-    return m_name;
-}
-
-Declaration &
-InlineFunctionInfo::GetCallSite ()
-{
-    return m_call_decl;
-}
-
-const Declaration &
-InlineFunctionInfo::GetCallSite () const
-{
-    return m_call_decl;
-}
-
-
-Mangled&
-InlineFunctionInfo::GetMangled()
-{
-    return m_mangled;
-}
-
-const Mangled&
-InlineFunctionInfo::GetMangled() const
-{
-    return m_mangled;
-}
-
-size_t
-InlineFunctionInfo::MemorySize() const
-{
-    return FunctionInfo::MemorySize() + m_mangled.MemorySize();
+size_t InlineFunctionInfo::MemorySize() const {
+  return FunctionInfo::MemorySize() + m_mangled.MemorySize();
 }
 
 //----------------------------------------------------------------------
 //
 //----------------------------------------------------------------------
-Function::Function
-(
-    CompileUnit *comp_unit,
-    lldb::user_id_t func_uid,
-    lldb::user_id_t type_uid,
-    const Mangled &mangled,
-    Type * type,
-    const AddressRange& range
-) :
-    UserID (func_uid),
-    m_comp_unit (comp_unit),
-    m_type_uid (type_uid),
-    m_type (type),
-    m_mangled (mangled),
-    m_block (func_uid),
-    m_range (range),
-    m_frame_base (nullptr),
-    m_flags (),
-    m_prologue_byte_size (0)
-{
-    m_block.SetParentScope(this);
-    assert(comp_unit != nullptr);
+Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
+                   lldb::user_id_t type_uid, const Mangled &mangled, Type *type,
+                   const AddressRange &range)
+    : UserID(func_uid), m_comp_unit(comp_unit), m_type_uid(type_uid),
+      m_type(type), m_mangled(mangled), m_block(func_uid), m_range(range),
+      m_frame_base(nullptr), m_flags(), m_prologue_byte_size(0) {
+  m_block.SetParentScope(this);
+  assert(comp_unit != nullptr);
 }
 
-Function::Function
-(
-    CompileUnit *comp_unit,
-    lldb::user_id_t func_uid,
-    lldb::user_id_t type_uid,
-    const char *mangled,
-    Type *type,
-    const AddressRange &range
-) :
-    UserID (func_uid),
-    m_comp_unit (comp_unit),
-    m_type_uid (type_uid),
-    m_type (type),
-    m_mangled (ConstString(mangled), true),
-    m_block (func_uid),
-    m_range (range),
-    m_frame_base (nullptr),
-    m_flags (),
-    m_prologue_byte_size (0)
-{
-    m_block.SetParentScope(this);
-    assert(comp_unit != nullptr);
+Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
+                   lldb::user_id_t type_uid, const char *mangled, Type *type,
+                   const AddressRange &range)
+    : UserID(func_uid), m_comp_unit(comp_unit), m_type_uid(type_uid),
+      m_type(type), m_mangled(ConstString(mangled), true), m_block(func_uid),
+      m_range(range), m_frame_base(nullptr), m_flags(),
+      m_prologue_byte_size(0) {
+  m_block.SetParentScope(this);
+  assert(comp_unit != nullptr);
 }
 
+Function::~Function() {}
 
-Function::~Function()
-{
-}
+void Function::GetStartLineSourceInfo(FileSpec &source_file,
+                                      uint32_t &line_no) {
+  line_no = 0;
+  source_file.Clear();
 
-void
-Function::GetStartLineSourceInfo (FileSpec &source_file, uint32_t &line_no)
-{
-    line_no = 0;
-    source_file.Clear();
-    
-    if (m_comp_unit == nullptr)
-        return;
-        
-    if (m_type != nullptr && m_type->GetDeclaration().GetLine() != 0)
-    {
-        source_file = m_type->GetDeclaration().GetFile();
-        line_no = m_type->GetDeclaration().GetLine();
-    }
-    else 
-    {
-        LineTable *line_table = m_comp_unit->GetLineTable();
-        if (line_table == nullptr)
-            return;
-            
-        LineEntry line_entry;
-        if (line_table->FindLineEntryByAddress (GetAddressRange().GetBaseAddress(), line_entry, nullptr))
-        {
-            line_no = line_entry.line;
-            source_file = line_entry.file;
-        }
-    }
-}
+  if (m_comp_unit == nullptr)
+    return;
 
-void
-Function::GetEndLineSourceInfo (FileSpec &source_file, uint32_t &line_no)
-{
-    line_no = 0;
-    source_file.Clear();
-    
-    // The -1 is kind of cheesy, but I want to get the last line entry for the given function, not the 
-    // first entry of the next.
-    Address scratch_addr(GetAddressRange().GetBaseAddress());
-    scratch_addr.SetOffset (scratch_addr.GetOffset() + GetAddressRange().GetByteSize() - 1);
-    
+  if (m_type != nullptr && m_type->GetDeclaration().GetLine() != 0) {
+    source_file = m_type->GetDeclaration().GetFile();
+    line_no = m_type->GetDeclaration().GetLine();
+  } else {
     LineTable *line_table = m_comp_unit->GetLineTable();
     if (line_table == nullptr)
-        return;
-        
+      return;
+
     LineEntry line_entry;
-    if (line_table->FindLineEntryByAddress (scratch_addr, line_entry, nullptr))
-    {
-        line_no = line_entry.line;
-        source_file = line_entry.file;
+    if (line_table->FindLineEntryByAddress(GetAddressRange().GetBaseAddress(),
+                                           line_entry, nullptr)) {
+      line_no = line_entry.line;
+      source_file = line_entry.file;
     }
+  }
 }
 
-Block &
-Function::GetBlock (bool can_create)
-{
-    if (!m_block.BlockInfoHasBeenParsed() && can_create)
-    {
-        SymbolContext sc;
-        CalculateSymbolContext(&sc);
-        if (sc.module_sp)
-        {
-            sc.module_sp->GetSymbolVendor()->ParseFunctionBlocks(sc);
-        }
-        else
-        {
-            Host::SystemLog (Host::eSystemLogError, 
-                             "error: unable to find module shared pointer for function '%s' in %s\n", 
-                             GetName().GetCString(),
-                             m_comp_unit->GetPath().c_str());
-        }
-        m_block.SetBlockInfoHasBeenParsed (true, true);
+void Function::GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no) {
+  line_no = 0;
+  source_file.Clear();
+
+  // The -1 is kind of cheesy, but I want to get the last line entry for the
+  // given function, not the
+  // first entry of the next.
+  Address scratch_addr(GetAddressRange().GetBaseAddress());
+  scratch_addr.SetOffset(scratch_addr.GetOffset() +
+                         GetAddressRange().GetByteSize() - 1);
+
+  LineTable *line_table = m_comp_unit->GetLineTable();
+  if (line_table == nullptr)
+    return;
+
+  LineEntry line_entry;
+  if (line_table->FindLineEntryByAddress(scratch_addr, line_entry, nullptr)) {
+    line_no = line_entry.line;
+    source_file = line_entry.file;
+  }
+}
+
+Block &Function::GetBlock(bool can_create) {
+  if (!m_block.BlockInfoHasBeenParsed() && can_create) {
+    SymbolContext sc;
+    CalculateSymbolContext(&sc);
+    if (sc.module_sp) {
+      sc.module_sp->GetSymbolVendor()->ParseFunctionBlocks(sc);
+    } else {
+      Host::SystemLog(Host::eSystemLogError, "error: unable to find module "
+                                             "shared pointer for function '%s' "
+                                             "in %s\n",
+                      GetName().GetCString(), m_comp_unit->GetPath().c_str());
     }
-    return m_block;
+    m_block.SetBlockInfoHasBeenParsed(true, true);
+  }
+  return m_block;
 }
 
-CompileUnit*
-Function::GetCompileUnit()
-{
-    return m_comp_unit;
+CompileUnit *Function::GetCompileUnit() { return m_comp_unit; }
+
+const CompileUnit *Function::GetCompileUnit() const { return m_comp_unit; }
+
+void Function::GetDescription(Stream *s, lldb::DescriptionLevel level,
+                              Target *target) {
+  Type *func_type = GetType();
+  const char *name = func_type ? func_type->GetName().AsCString() : "<unknown>";
+
+  *s << "id = " << (const UserID &)*this << ", name = \"" << name
+     << "\", range = ";
+
+  Address::DumpStyle fallback_style;
+  if (level == eDescriptionLevelVerbose)
+    fallback_style = Address::DumpStyleModuleWithFileAddress;
+  else
+    fallback_style = Address::DumpStyleFileAddress;
+  GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress,
+                         fallback_style);
 }
 
-const CompileUnit*
-Function::GetCompileUnit() const
-{
-    return m_comp_unit;
+void Function::Dump(Stream *s, bool show_context) const {
+  s->Printf("%p: ", static_cast<const void *>(this));
+  s->Indent();
+  *s << "Function" << static_cast<const UserID &>(*this);
+
+  m_mangled.Dump(s);
+
+  if (m_type)
+    s->Printf(", type = %p", static_cast<void *>(m_type));
+  else if (m_type_uid != LLDB_INVALID_UID)
+    s->Printf(", type_uid = 0x%8.8" PRIx64, m_type_uid);
+
+  s->EOL();
+  // Dump the root object
+  if (m_block.BlockInfoHasBeenParsed())
+    m_block.Dump(s, m_range.GetBaseAddress().GetFileAddress(), INT_MAX,
+                 show_context);
 }
 
-
-void
-Function::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target)
-{
-    Type* func_type = GetType();
-    const char *name = func_type ? func_type->GetName().AsCString() : "<unknown>";
-    
-    *s << "id = " << (const UserID&)*this << ", name = \"" << name << "\", range = ";
-    
-    Address::DumpStyle fallback_style;
-    if (level == eDescriptionLevelVerbose)
-        fallback_style = Address::DumpStyleModuleWithFileAddress;
-    else
-        fallback_style = Address::DumpStyleFileAddress;
-    GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, fallback_style);
+void Function::CalculateSymbolContext(SymbolContext *sc) {
+  sc->function = this;
+  m_comp_unit->CalculateSymbolContext(sc);
 }
 
-void
-Function::Dump(Stream *s, bool show_context) const
-{
-    s->Printf("%p: ", static_cast<const void*>(this));
-    s->Indent();
-    *s << "Function" << static_cast<const UserID&>(*this);
+ModuleSP Function::CalculateSymbolContextModule() {
+  SectionSP section_sp(m_range.GetBaseAddress().GetSection());
+  if (section_sp)
+    return section_sp->GetModule();
 
-    m_mangled.Dump(s);
-
-    if (m_type)
-        s->Printf(", type = %p", static_cast<void*>(m_type));
-    else if (m_type_uid != LLDB_INVALID_UID)
-        s->Printf(", type_uid = 0x%8.8" PRIx64, m_type_uid);
-
-    s->EOL();
-    // Dump the root object
-    if (m_block.BlockInfoHasBeenParsed ())
-        m_block.Dump(s, m_range.GetBaseAddress().GetFileAddress(), INT_MAX, show_context);
+  return this->GetCompileUnit()->GetModule();
 }
 
-
-void
-Function::CalculateSymbolContext(SymbolContext* sc)
-{
-    sc->function = this;
-    m_comp_unit->CalculateSymbolContext(sc);
+CompileUnit *Function::CalculateSymbolContextCompileUnit() {
+  return this->GetCompileUnit();
 }
 
-ModuleSP
-Function::CalculateSymbolContextModule ()
-{
-    SectionSP section_sp (m_range.GetBaseAddress().GetSection());
-    if (section_sp)
-        return section_sp->GetModule();
-    
-    return this->GetCompileUnit()->GetModule();
+Function *Function::CalculateSymbolContextFunction() { return this; }
+
+lldb::DisassemblerSP Function::GetInstructions(const ExecutionContext &exe_ctx,
+                                               const char *flavor,
+                                               bool prefer_file_cache) {
+  ModuleSP module_sp(GetAddressRange().GetBaseAddress().GetModule());
+  if (module_sp) {
+    const bool prefer_file_cache = false;
+    return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr,
+                                          flavor, exe_ctx, GetAddressRange(),
+                                          prefer_file_cache);
+  }
+  return lldb::DisassemblerSP();
 }
 
-CompileUnit *
-Function::CalculateSymbolContextCompileUnit ()
-{
-    return this->GetCompileUnit();
+bool Function::GetDisassembly(const ExecutionContext &exe_ctx,
+                              const char *flavor, bool prefer_file_cache,
+                              Stream &strm) {
+  lldb::DisassemblerSP disassembler_sp =
+      GetInstructions(exe_ctx, flavor, prefer_file_cache);
+  if (disassembler_sp) {
+    const bool show_address = true;
+    const bool show_bytes = false;
+    disassembler_sp->GetInstructionList().Dump(&strm, show_address, show_bytes,
+                                               &exe_ctx);
+    return true;
+  }
+  return false;
 }
 
-Function *
-Function::CalculateSymbolContextFunction ()
-{
-    return this;
-}
-
-lldb::DisassemblerSP
-Function::GetInstructions (const ExecutionContext &exe_ctx,
-                           const char *flavor,
-                           bool prefer_file_cache)
-{
-    ModuleSP module_sp (GetAddressRange().GetBaseAddress().GetModule());
-    if (module_sp)
-    {
-        const bool prefer_file_cache = false;
-        return Disassembler::DisassembleRange (module_sp->GetArchitecture(),
-                                               nullptr,
-                                               flavor,
-                                               exe_ctx,
-                                               GetAddressRange(),
-                                               prefer_file_cache);
-    }
-    return lldb::DisassemblerSP();
-}
-
-bool
-Function::GetDisassembly (const ExecutionContext &exe_ctx,
-                          const char *flavor,
-                          bool prefer_file_cache,
-                          Stream &strm)
-{
-    lldb::DisassemblerSP disassembler_sp = GetInstructions (exe_ctx, flavor, prefer_file_cache);
-    if (disassembler_sp)
-    {
-        const bool show_address = true;
-        const bool show_bytes = false;
-        disassembler_sp->GetInstructionList().Dump (&strm, show_address, show_bytes, &exe_ctx);
-        return true;
-    }
-    return false;
-}
-
-
-//Symbol *
-//Function::CalculateSymbolContextSymbol ()
+// Symbol *
+// Function::CalculateSymbolContextSymbol ()
 //{
 //    return // TODO: find the symbol for the function???
 //}
 
-
-void
-Function::DumpSymbolContext(Stream *s)
-{
-    m_comp_unit->DumpSymbolContext(s);
-    s->Printf(", Function{0x%8.8" PRIx64 "}", GetID());
+void Function::DumpSymbolContext(Stream *s) {
+  m_comp_unit->DumpSymbolContext(s);
+  s->Printf(", Function{0x%8.8" PRIx64 "}", GetID());
 }
 
-size_t
-Function::MemorySize () const
-{
-    size_t mem_size = sizeof(Function) + m_block.MemorySize();
-    return mem_size;
+size_t Function::MemorySize() const {
+  size_t mem_size = sizeof(Function) + m_block.MemorySize();
+  return mem_size;
 }
 
-bool
-Function::GetIsOptimized ()
-{
-    bool result = false;
+bool Function::GetIsOptimized() {
+  bool result = false;
 
-    // Currently optimization is only indicted by the
-    // vendor extension DW_AT_APPLE_optimized which
-    // is set on a compile unit level.
-    if (m_comp_unit)
-    {
-        result = m_comp_unit->GetIsOptimized();
+  // Currently optimization is only indicted by the
+  // vendor extension DW_AT_APPLE_optimized which
+  // is set on a compile unit level.
+  if (m_comp_unit) {
+    result = m_comp_unit->GetIsOptimized();
+  }
+  return result;
+}
+
+bool Function::IsTopLevelFunction() {
+  bool result = false;
+
+  if (Language *language = Language::FindPlugin(GetLanguage()))
+    result = language->IsTopLevelFunction(*this);
+
+  return result;
+}
+
+ConstString Function::GetDisplayName() const {
+  if (!m_mangled)
+    return ConstString();
+  return m_mangled.GetDisplayDemangledName(GetLanguage());
+}
+
+CompilerDeclContext Function::GetDeclContext() {
+  ModuleSP module_sp = CalculateSymbolContextModule();
+
+  if (module_sp) {
+    SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
+
+    if (sym_vendor) {
+      SymbolFile *sym_file = sym_vendor->GetSymbolFile();
+
+      if (sym_file)
+        return sym_file->GetDeclContextForUID(GetID());
     }
-    return result;
+  }
+  return CompilerDeclContext();
 }
 
-bool
-Function::IsTopLevelFunction ()
-{
-    bool result = false;
-    
-    if (Language* language = Language::FindPlugin(GetLanguage()))
-        result = language->IsTopLevelFunction(*this);
-    
-    return result;
+Type *Function::GetType() {
+  if (m_type == nullptr) {
+    SymbolContext sc;
+
+    CalculateSymbolContext(&sc);
+
+    if (!sc.module_sp)
+      return nullptr;
+
+    SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor();
+
+    if (sym_vendor == nullptr)
+      return nullptr;
+
+    SymbolFile *sym_file = sym_vendor->GetSymbolFile();
+
+    if (sym_file == nullptr)
+      return nullptr;
+
+    m_type = sym_file->ResolveTypeUID(m_type_uid);
+  }
+  return m_type;
 }
 
-ConstString
-Function::GetDisplayName () const
-{
-    if (!m_mangled)
-        return ConstString();
-    return m_mangled.GetDisplayDemangledName(GetLanguage());
+const Type *Function::GetType() const { return m_type; }
+
+CompilerType Function::GetCompilerType() {
+  Type *function_type = GetType();
+  if (function_type)
+    return function_type->GetFullCompilerType();
+  return CompilerType();
 }
 
-CompilerDeclContext
-Function::GetDeclContext()
-{
-    ModuleSP module_sp = CalculateSymbolContextModule ();
+uint32_t Function::GetPrologueByteSize() {
+  if (m_prologue_byte_size == 0 &&
+      m_flags.IsClear(flagsCalculatedPrologueSize)) {
+    m_flags.Set(flagsCalculatedPrologueSize);
+    LineTable *line_table = m_comp_unit->GetLineTable();
+    uint32_t prologue_end_line_idx = 0;
 
-    if (module_sp)
-    {
-        SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
+    if (line_table) {
+      LineEntry first_line_entry;
+      uint32_t first_line_entry_idx = UINT32_MAX;
+      if (line_table->FindLineEntryByAddress(GetAddressRange().GetBaseAddress(),
+                                             first_line_entry,
+                                             &first_line_entry_idx)) {
+        // Make sure the first line entry isn't already the end of the prologue
+        addr_t prologue_end_file_addr = LLDB_INVALID_ADDRESS;
+        addr_t line_zero_end_file_addr = LLDB_INVALID_ADDRESS;
 
-        if (sym_vendor)
-        {
-            SymbolFile *sym_file = sym_vendor->GetSymbolFile();
-
-            if (sym_file)
-                return sym_file->GetDeclContextForUID (GetID());
-        }
-    }
-    return CompilerDeclContext();
-}
-
-Type*
-Function::GetType()
-{
-    if (m_type == nullptr)
-    {
-        SymbolContext sc;
-        
-        CalculateSymbolContext (&sc);
-        
-        if (!sc.module_sp)
-            return nullptr;
-        
-        SymbolVendor *sym_vendor = sc.module_sp->GetSymbolVendor();
-        
-        if (sym_vendor == nullptr)
-            return nullptr;
-        
-        SymbolFile *sym_file = sym_vendor->GetSymbolFile();
-        
-        if (sym_file == nullptr)
-            return nullptr;
-        
-        m_type = sym_file->ResolveTypeUID(m_type_uid);
-    }
-    return m_type;
-}
-
-const Type*
-Function::GetType() const
-{
-    return m_type;
-}
-
-CompilerType
-Function::GetCompilerType()
-{
-    Type *function_type = GetType();
-    if (function_type)
-        return function_type->GetFullCompilerType ();
-    return CompilerType();
-}
-
-uint32_t
-Function::GetPrologueByteSize ()
-{
-    if (m_prologue_byte_size == 0 && m_flags.IsClear(flagsCalculatedPrologueSize))
-    {
-        m_flags.Set(flagsCalculatedPrologueSize);
-        LineTable* line_table = m_comp_unit->GetLineTable ();
-        uint32_t prologue_end_line_idx = 0;
-        
-        if (line_table)
-        {
-            LineEntry first_line_entry;
-            uint32_t first_line_entry_idx = UINT32_MAX;
-            if (line_table->FindLineEntryByAddress(GetAddressRange().GetBaseAddress(), first_line_entry, &first_line_entry_idx))
-            {
-                // Make sure the first line entry isn't already the end of the prologue
-                addr_t prologue_end_file_addr = LLDB_INVALID_ADDRESS;
-                addr_t line_zero_end_file_addr = LLDB_INVALID_ADDRESS;
-                
-                if (first_line_entry.is_prologue_end)
-                {
-                    prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress();
-                    prologue_end_line_idx = first_line_entry_idx;
-                }
-                else
-                {
-                    // Check the first few instructions and look for one that has
-                    // is_prologue_end set to true.
-                    const uint32_t last_line_entry_idx = first_line_entry_idx + 6;
-                    for (uint32_t idx = first_line_entry_idx + 1; idx < last_line_entry_idx; ++idx)
-                    {
-                        LineEntry line_entry;
-                        if (line_table->GetLineEntryAtIndex (idx, line_entry))
-                        {
-                            if (line_entry.is_prologue_end)
-                            {
-                                prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress();
-                                prologue_end_line_idx = idx;
-                                break;
-                            }
-                        }
-                    }
-                }
-
-                // If we didn't find the end of the prologue in the line tables,
-                // then just use the end address of the first line table entry
-                if (prologue_end_file_addr == LLDB_INVALID_ADDRESS)
-                {
-                    // Check the first few instructions and look for one that has
-                    // a line number that's different than the first entry.
-                    uint32_t last_line_entry_idx = first_line_entry_idx + 6;
-                    for (uint32_t idx = first_line_entry_idx + 1; idx < last_line_entry_idx; ++idx)
-                    {
-                        LineEntry line_entry;
-                        if (line_table->GetLineEntryAtIndex (idx, line_entry))
-                        {
-                            if (line_entry.line != first_line_entry.line)
-                            {
-                                prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress();
-                                prologue_end_line_idx = idx;
-                                break;
-                            }
-                        }
-                    }
-
-                    if (prologue_end_file_addr == LLDB_INVALID_ADDRESS)
-                    {
-                        prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress() + first_line_entry.range.GetByteSize();
-                        prologue_end_line_idx = first_line_entry_idx;
-                    }
-                }
-                    
-                const addr_t func_start_file_addr = m_range.GetBaseAddress().GetFileAddress();
-                const addr_t func_end_file_addr = func_start_file_addr + m_range.GetByteSize();
-                
-                // Now calculate the offset to pass the subsequent line 0 entries.
-                uint32_t first_non_zero_line = prologue_end_line_idx;
-                while (1)
-                {
-                    LineEntry line_entry;
-                    if (line_table->GetLineEntryAtIndex(first_non_zero_line, line_entry))
-                    {
-                        if (line_entry.line != 0)
-                            break;
-                    }
-                    if (line_entry.range.GetBaseAddress().GetFileAddress() >= func_end_file_addr)
-                        break;
-
-                    first_non_zero_line++;
-                }
-                
-                if (first_non_zero_line > prologue_end_line_idx)
-                {
-                    LineEntry first_non_zero_entry;
-                    if (line_table->GetLineEntryAtIndex(first_non_zero_line, first_non_zero_entry))
-                    {
-                        line_zero_end_file_addr = first_non_zero_entry.range.GetBaseAddress().GetFileAddress();
-                    }
-                }
-
-                // Verify that this prologue end file address in the function's
-                // address range just to be sure
-                if (func_start_file_addr < prologue_end_file_addr && prologue_end_file_addr < func_end_file_addr)
-                {
-                    m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
-                }
-                
-                if (prologue_end_file_addr < line_zero_end_file_addr && line_zero_end_file_addr < func_end_file_addr)
-                {
-                    m_prologue_byte_size += line_zero_end_file_addr - prologue_end_file_addr;
-                }
+        if (first_line_entry.is_prologue_end) {
+          prologue_end_file_addr =
+              first_line_entry.range.GetBaseAddress().GetFileAddress();
+          prologue_end_line_idx = first_line_entry_idx;
+        } else {
+          // Check the first few instructions and look for one that has
+          // is_prologue_end set to true.
+          const uint32_t last_line_entry_idx = first_line_entry_idx + 6;
+          for (uint32_t idx = first_line_entry_idx + 1;
+               idx < last_line_entry_idx; ++idx) {
+            LineEntry line_entry;
+            if (line_table->GetLineEntryAtIndex(idx, line_entry)) {
+              if (line_entry.is_prologue_end) {
+                prologue_end_file_addr =
+                    line_entry.range.GetBaseAddress().GetFileAddress();
+                prologue_end_line_idx = idx;
+                break;
+              }
             }
+          }
         }
+
+        // If we didn't find the end of the prologue in the line tables,
+        // then just use the end address of the first line table entry
+        if (prologue_end_file_addr == LLDB_INVALID_ADDRESS) {
+          // Check the first few instructions and look for one that has
+          // a line number that's different than the first entry.
+          uint32_t last_line_entry_idx = first_line_entry_idx + 6;
+          for (uint32_t idx = first_line_entry_idx + 1;
+               idx < last_line_entry_idx; ++idx) {
+            LineEntry line_entry;
+            if (line_table->GetLineEntryAtIndex(idx, line_entry)) {
+              if (line_entry.line != first_line_entry.line) {
+                prologue_end_file_addr =
+                    line_entry.range.GetBaseAddress().GetFileAddress();
+                prologue_end_line_idx = idx;
+                break;
+              }
+            }
+          }
+
+          if (prologue_end_file_addr == LLDB_INVALID_ADDRESS) {
+            prologue_end_file_addr =
+                first_line_entry.range.GetBaseAddress().GetFileAddress() +
+                first_line_entry.range.GetByteSize();
+            prologue_end_line_idx = first_line_entry_idx;
+          }
+        }
+
+        const addr_t func_start_file_addr =
+            m_range.GetBaseAddress().GetFileAddress();
+        const addr_t func_end_file_addr =
+            func_start_file_addr + m_range.GetByteSize();
+
+        // Now calculate the offset to pass the subsequent line 0 entries.
+        uint32_t first_non_zero_line = prologue_end_line_idx;
+        while (1) {
+          LineEntry line_entry;
+          if (line_table->GetLineEntryAtIndex(first_non_zero_line,
+                                              line_entry)) {
+            if (line_entry.line != 0)
+              break;
+          }
+          if (line_entry.range.GetBaseAddress().GetFileAddress() >=
+              func_end_file_addr)
+            break;
+
+          first_non_zero_line++;
+        }
+
+        if (first_non_zero_line > prologue_end_line_idx) {
+          LineEntry first_non_zero_entry;
+          if (line_table->GetLineEntryAtIndex(first_non_zero_line,
+                                              first_non_zero_entry)) {
+            line_zero_end_file_addr =
+                first_non_zero_entry.range.GetBaseAddress().GetFileAddress();
+          }
+        }
+
+        // Verify that this prologue end file address in the function's
+        // address range just to be sure
+        if (func_start_file_addr < prologue_end_file_addr &&
+            prologue_end_file_addr < func_end_file_addr) {
+          m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
+        }
+
+        if (prologue_end_file_addr < line_zero_end_file_addr &&
+            line_zero_end_file_addr < func_end_file_addr) {
+          m_prologue_byte_size +=
+              line_zero_end_file_addr - prologue_end_file_addr;
+        }
+      }
     }
-    
-        return m_prologue_byte_size;
+  }
+
+  return m_prologue_byte_size;
 }
 
-lldb::LanguageType
-Function::GetLanguage() const
-{
-    if (m_comp_unit)
-        return m_comp_unit->GetLanguage();
-    else
-        return lldb::eLanguageTypeUnknown;
+lldb::LanguageType Function::GetLanguage() const {
+  if (m_comp_unit)
+    return m_comp_unit->GetLanguage();
+  else
+    return lldb::eLanguageTypeUnknown;
 }
 
-ConstString
-Function::GetName() const
-{
-    LanguageType language = lldb::eLanguageTypeUnknown;
-    if (m_comp_unit)
-        language = m_comp_unit->GetLanguage();
-    return m_mangled.GetName(language);
+ConstString Function::GetName() const {
+  LanguageType language = lldb::eLanguageTypeUnknown;
+  if (m_comp_unit)
+    language = m_comp_unit->GetLanguage();
+  return m_mangled.GetName(language);
 }
 
-ConstString
-Function::GetNameNoArguments() const
-{
-    LanguageType language = lldb::eLanguageTypeUnknown;
-    if (m_comp_unit)
-        language = m_comp_unit->GetLanguage();
-    return m_mangled.GetName(language, Mangled::ePreferDemangledWithoutArguments);
+ConstString Function::GetNameNoArguments() const {
+  LanguageType language = lldb::eLanguageTypeUnknown;
+  if (m_comp_unit)
+    language = m_comp_unit->GetLanguage();
+  return m_mangled.GetName(language, Mangled::ePreferDemangledWithoutArguments);
 }
-
-
-
