diff --git a/lldb/source/API/SBSymbolContext.cpp b/lldb/source/API/SBSymbolContext.cpp
index 481fa1a..4748836 100644
--- a/lldb/source/API/SBSymbolContext.cpp
+++ b/lldb/source/API/SBSymbolContext.cpp
@@ -18,270 +18,199 @@
 using namespace lldb;
 using namespace lldb_private;
 
+SBSymbolContext::SBSymbolContext() : m_opaque_ap() {}
 
-
-SBSymbolContext::SBSymbolContext () :
-    m_opaque_ap ()
-{
+SBSymbolContext::SBSymbolContext(const SymbolContext *sc_ptr) : m_opaque_ap() {
+  if (sc_ptr)
+    m_opaque_ap.reset(new SymbolContext(*sc_ptr));
 }
 
-SBSymbolContext::SBSymbolContext (const SymbolContext *sc_ptr) :
-    m_opaque_ap ()
-{
-    if (sc_ptr)
-        m_opaque_ap.reset (new SymbolContext (*sc_ptr));
+SBSymbolContext::SBSymbolContext(const SBSymbolContext &rhs) : m_opaque_ap() {
+  if (rhs.IsValid()) {
+    if (m_opaque_ap.get())
+      *m_opaque_ap = *rhs.m_opaque_ap;
+    else
+      ref() = *rhs.m_opaque_ap;
+  }
 }
 
-SBSymbolContext::SBSymbolContext (const SBSymbolContext& rhs) :
-    m_opaque_ap ()
-{
+SBSymbolContext::~SBSymbolContext() {}
+
+const SBSymbolContext &SBSymbolContext::operator=(const SBSymbolContext &rhs) {
+  if (this != &rhs) {
     if (rhs.IsValid())
-    {
-        if (m_opaque_ap.get())
-            *m_opaque_ap = *rhs.m_opaque_ap;
-        else
-            ref() = *rhs.m_opaque_ap;
-    }
+      m_opaque_ap.reset(
+          new lldb_private::SymbolContext(*rhs.m_opaque_ap.get()));
+  }
+  return *this;
 }
 
-SBSymbolContext::~SBSymbolContext ()
-{
-}
-
-const SBSymbolContext &
-SBSymbolContext::operator = (const SBSymbolContext &rhs)
-{
-    if (this != &rhs)
-    {
-        if (rhs.IsValid())
-            m_opaque_ap.reset (new lldb_private::SymbolContext(*rhs.m_opaque_ap.get()));
-    }
-    return *this;
-}
-
-void
-SBSymbolContext::SetSymbolContext (const SymbolContext *sc_ptr)
-{
-    if (sc_ptr)
-    {
-        if (m_opaque_ap.get())
-            *m_opaque_ap = *sc_ptr;
-        else
-            m_opaque_ap.reset (new SymbolContext (*sc_ptr));
-    }
+void SBSymbolContext::SetSymbolContext(const SymbolContext *sc_ptr) {
+  if (sc_ptr) {
+    if (m_opaque_ap.get())
+      *m_opaque_ap = *sc_ptr;
     else
-    {
-        if (m_opaque_ap.get())
-            m_opaque_ap->Clear(true);
-    }
-}
-
-bool
-SBSymbolContext::IsValid () const
-{
-    return m_opaque_ap.get() != NULL;
-}
-
-
-
-SBModule
-SBSymbolContext::GetModule ()
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-
-    SBModule sb_module;
-    ModuleSP module_sp;
+      m_opaque_ap.reset(new SymbolContext(*sc_ptr));
+  } else {
     if (m_opaque_ap.get())
-    {
-        module_sp = m_opaque_ap->module_sp;
-        sb_module.SetSP (module_sp);
-    }
-
-    if (log)
-    {
-        SBStream sstr;
-        sb_module.GetDescription (sstr);
-        log->Printf ("SBSymbolContext(%p)::GetModule () => SBModule(%p): %s",
-                     static_cast<void*>(m_opaque_ap.get()),
-                     static_cast<void*>(module_sp.get()), sstr.GetData());
-    }
-
-    return sb_module;
+      m_opaque_ap->Clear(true);
+  }
 }
 
-SBCompileUnit
-SBSymbolContext::GetCompileUnit ()
-{
-    return SBCompileUnit (m_opaque_ap.get() ? m_opaque_ap->comp_unit : NULL);
+bool SBSymbolContext::IsValid() const { return m_opaque_ap.get() != NULL; }
+
+SBModule SBSymbolContext::GetModule() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  SBModule sb_module;
+  ModuleSP module_sp;
+  if (m_opaque_ap.get()) {
+    module_sp = m_opaque_ap->module_sp;
+    sb_module.SetSP(module_sp);
+  }
+
+  if (log) {
+    SBStream sstr;
+    sb_module.GetDescription(sstr);
+    log->Printf("SBSymbolContext(%p)::GetModule () => SBModule(%p): %s",
+                static_cast<void *>(m_opaque_ap.get()),
+                static_cast<void *>(module_sp.get()), sstr.GetData());
+  }
+
+  return sb_module;
 }
 
-SBFunction
-SBSymbolContext::GetFunction ()
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-
-    Function *function = NULL;
-
-    if (m_opaque_ap.get())
-        function = m_opaque_ap->function;
-
-    SBFunction sb_function (function);
-
-    if (log)
-        log->Printf ("SBSymbolContext(%p)::GetFunction () => SBFunction(%p)",
-                     static_cast<void*>(m_opaque_ap.get()),
-                     static_cast<void*>(function));
-
-    return sb_function;
+SBCompileUnit SBSymbolContext::GetCompileUnit() {
+  return SBCompileUnit(m_opaque_ap.get() ? m_opaque_ap->comp_unit : NULL);
 }
 
-SBBlock
-SBSymbolContext::GetBlock ()
-{
-    return SBBlock (m_opaque_ap.get() ? m_opaque_ap->block : NULL);
+SBFunction SBSymbolContext::GetFunction() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  Function *function = NULL;
+
+  if (m_opaque_ap.get())
+    function = m_opaque_ap->function;
+
+  SBFunction sb_function(function);
+
+  if (log)
+    log->Printf("SBSymbolContext(%p)::GetFunction () => SBFunction(%p)",
+                static_cast<void *>(m_opaque_ap.get()),
+                static_cast<void *>(function));
+
+  return sb_function;
 }
 
-SBLineEntry
-SBSymbolContext::GetLineEntry ()
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-
-    SBLineEntry sb_line_entry;
-    if (m_opaque_ap.get())
-        sb_line_entry.SetLineEntry (m_opaque_ap->line_entry);
-
-    if (log)
-    {
-        log->Printf ("SBSymbolContext(%p)::GetLineEntry () => SBLineEntry(%p)",
-                     static_cast<void*>(m_opaque_ap.get()),
-                     static_cast<void*>(sb_line_entry.get()));
-    }
-
-    return sb_line_entry;
+SBBlock SBSymbolContext::GetBlock() {
+  return SBBlock(m_opaque_ap.get() ? m_opaque_ap->block : NULL);
 }
 
-SBSymbol
-SBSymbolContext::GetSymbol ()
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+SBLineEntry SBSymbolContext::GetLineEntry() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
 
-    Symbol *symbol = NULL;
+  SBLineEntry sb_line_entry;
+  if (m_opaque_ap.get())
+    sb_line_entry.SetLineEntry(m_opaque_ap->line_entry);
 
-    if (m_opaque_ap.get())
-        symbol = m_opaque_ap->symbol;
+  if (log) {
+    log->Printf("SBSymbolContext(%p)::GetLineEntry () => SBLineEntry(%p)",
+                static_cast<void *>(m_opaque_ap.get()),
+                static_cast<void *>(sb_line_entry.get()));
+  }
 
-    SBSymbol sb_symbol (symbol);
-
-    if (log)
-        log->Printf ("SBSymbolContext(%p)::GetSymbol () => SBSymbol(%p)",
-                     static_cast<void*>(m_opaque_ap.get()),
-                     static_cast<void*>(symbol));
-
-    return sb_symbol;
+  return sb_line_entry;
 }
 
-void
-SBSymbolContext::SetModule (lldb::SBModule module)
-{
-    ref().module_sp = module.GetSP();
+SBSymbol SBSymbolContext::GetSymbol() {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  Symbol *symbol = NULL;
+
+  if (m_opaque_ap.get())
+    symbol = m_opaque_ap->symbol;
+
+  SBSymbol sb_symbol(symbol);
+
+  if (log)
+    log->Printf("SBSymbolContext(%p)::GetSymbol () => SBSymbol(%p)",
+                static_cast<void *>(m_opaque_ap.get()),
+                static_cast<void *>(symbol));
+
+  return sb_symbol;
 }
 
-void
-SBSymbolContext::SetCompileUnit (lldb::SBCompileUnit compile_unit)
-{
-    ref().comp_unit = compile_unit.get();
+void SBSymbolContext::SetModule(lldb::SBModule module) {
+  ref().module_sp = module.GetSP();
 }
 
-void 
-SBSymbolContext::SetFunction (lldb::SBFunction function)
-{
-    ref().function = function.get();
+void SBSymbolContext::SetCompileUnit(lldb::SBCompileUnit compile_unit) {
+  ref().comp_unit = compile_unit.get();
 }
 
-void 
-SBSymbolContext::SetBlock (lldb::SBBlock block)
-{
-    ref().block = block.GetPtr();
+void SBSymbolContext::SetFunction(lldb::SBFunction function) {
+  ref().function = function.get();
 }
 
-void 
-SBSymbolContext::SetLineEntry (lldb::SBLineEntry line_entry)
-{
-    if (line_entry.IsValid())
-        ref().line_entry = line_entry.ref();
-    else
-        ref().line_entry.Clear();
+void SBSymbolContext::SetBlock(lldb::SBBlock block) {
+  ref().block = block.GetPtr();
 }
 
-void 
-SBSymbolContext::SetSymbol (lldb::SBSymbol symbol)
-{
-    ref().symbol = symbol.get();
+void SBSymbolContext::SetLineEntry(lldb::SBLineEntry line_entry) {
+  if (line_entry.IsValid())
+    ref().line_entry = line_entry.ref();
+  else
+    ref().line_entry.Clear();
 }
 
-
-lldb_private::SymbolContext*
-SBSymbolContext::operator->() const
-{
-    return m_opaque_ap.get();
+void SBSymbolContext::SetSymbol(lldb::SBSymbol symbol) {
+  ref().symbol = symbol.get();
 }
 
-
-const lldb_private::SymbolContext&
-SBSymbolContext::operator*() const
-{
-    assert (m_opaque_ap.get());
-    return *m_opaque_ap.get();
+lldb_private::SymbolContext *SBSymbolContext::operator->() const {
+  return m_opaque_ap.get();
 }
 
-
-lldb_private::SymbolContext&
-SBSymbolContext::operator*()
-{
-    if (m_opaque_ap.get() == NULL)
-        m_opaque_ap.reset (new SymbolContext);
-    return *m_opaque_ap.get();
+const lldb_private::SymbolContext &SBSymbolContext::operator*() const {
+  assert(m_opaque_ap.get());
+  return *m_opaque_ap.get();
 }
 
-lldb_private::SymbolContext&
-SBSymbolContext::ref()
-{
-    if (m_opaque_ap.get() == NULL)
-        m_opaque_ap.reset (new SymbolContext);
-    return *m_opaque_ap.get();
+lldb_private::SymbolContext &SBSymbolContext::operator*() {
+  if (m_opaque_ap.get() == NULL)
+    m_opaque_ap.reset(new SymbolContext);
+  return *m_opaque_ap.get();
 }
 
-lldb_private::SymbolContext *
-SBSymbolContext::get() const
-{
-    return m_opaque_ap.get();
+lldb_private::SymbolContext &SBSymbolContext::ref() {
+  if (m_opaque_ap.get() == NULL)
+    m_opaque_ap.reset(new SymbolContext);
+  return *m_opaque_ap.get();
 }
 
-bool
-SBSymbolContext::GetDescription (SBStream &description)
-{
-    Stream &strm = description.ref();
+lldb_private::SymbolContext *SBSymbolContext::get() const {
+  return m_opaque_ap.get();
+}
 
-    if (m_opaque_ap.get())
-    {
-        m_opaque_ap->GetDescription (&strm, lldb::eDescriptionLevelFull, NULL);
-    }
-    else
-        strm.PutCString ("No value");
+bool SBSymbolContext::GetDescription(SBStream &description) {
+  Stream &strm = description.ref();
 
-    return true;
+  if (m_opaque_ap.get()) {
+    m_opaque_ap->GetDescription(&strm, lldb::eDescriptionLevelFull, NULL);
+  } else
+    strm.PutCString("No value");
+
+  return true;
 }
 
 SBSymbolContext
-SBSymbolContext::GetParentOfInlinedScope (const SBAddress &curr_frame_pc, 
-                                          SBAddress &parent_frame_addr) const
-{
-    SBSymbolContext sb_sc;
-    if (m_opaque_ap.get() && curr_frame_pc.IsValid())
-    {
-        if (m_opaque_ap->GetParentOfInlinedScope (curr_frame_pc.ref(), sb_sc.ref(), parent_frame_addr.ref()))
-            return sb_sc;
-    }
-    return SBSymbolContext();
+SBSymbolContext::GetParentOfInlinedScope(const SBAddress &curr_frame_pc,
+                                         SBAddress &parent_frame_addr) const {
+  SBSymbolContext sb_sc;
+  if (m_opaque_ap.get() && curr_frame_pc.IsValid()) {
+    if (m_opaque_ap->GetParentOfInlinedScope(curr_frame_pc.ref(), sb_sc.ref(),
+                                             parent_frame_addr.ref()))
+      return sb_sc;
+  }
+  return SBSymbolContext();
 }
-
