[Lldb-commits] [lldb] r167218 [3/3] - in /lldb/branches/windows: ./ examples/plugins/commands/ examples/python/ examples/summaries/cocoa/ examples/synthetic/ examples/synthetic/bitfield/ include/lldb/ include/lldb/API/ include/lldb/Breakpoint/ include/lldb/Core/ include/lldb/Expression/ include/lldb/Host/ include/lldb/Interpreter/ include/lldb/Symbol/ include/lldb/Target/ lib/ lldb.xcodeproj/ scripts/ scripts/Python/ scripts/Python/interface/ source/API/ source/Breakpoint/ source/Commands/ source/Core/ source/Expressio...

Carlo Kok ck at remobjects.com
Thu Nov 1 00:04:05 PDT 2012


Modified: lldb/branches/windows/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/branches/windows/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Thu Nov  1 02:04:04 2012
@@ -1482,7 +1482,7 @@
         const char             *property_setter_name,
         const char             *property_getter_name,
         uint32_t                property_attributes,
-        uint64_t                metadata = 0
+        const ClangASTMetadata       *metadata
     ) :
         m_ast                   (ast),
         m_class_opaque_type     (class_opaque_type),
@@ -1491,9 +1491,32 @@
         m_ivar_decl             (ivar_decl),
         m_property_setter_name  (property_setter_name),
         m_property_getter_name  (property_getter_name),
-        m_property_attributes   (property_attributes),
-        m_metadata              (metadata)
+        m_property_attributes   (property_attributes)
     {
+        if (metadata != NULL)
+        {
+            m_metadata_ap.reset(new ClangASTMetadata());
+            *(m_metadata_ap.get()) = *metadata;
+        }
+    }
+    
+    DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs)
+    {
+        m_ast                  = rhs.m_ast;
+        m_class_opaque_type    = rhs.m_class_opaque_type;
+        m_property_name        = rhs.m_property_name;
+        m_property_opaque_type = rhs.m_property_opaque_type;
+        m_ivar_decl            = rhs.m_ivar_decl;
+        m_property_setter_name = rhs.m_property_setter_name;
+        m_property_getter_name = rhs.m_property_getter_name;
+        m_property_attributes  = rhs.m_property_attributes;
+        
+        if (rhs.m_metadata_ap.get())
+        {
+            m_metadata_ap.reset (new ClangASTMetadata());
+            *(m_metadata_ap.get()) = *(rhs.m_metadata_ap.get());
+        }
+        
     }
     
     bool Finalize() const
@@ -1506,7 +1529,7 @@
                                                      m_property_setter_name,
                                                      m_property_getter_name,
                                                      m_property_attributes,
-                                                     m_metadata);
+                                                     m_metadata_ap.get());
     }
 private:
     clang::ASTContext      *m_ast;
@@ -1517,7 +1540,7 @@
     const char             *m_property_setter_name;
     const char             *m_property_getter_name;
     uint32_t                m_property_attributes;
-    uint64_t                m_metadata;
+    std::auto_ptr<ClangASTMetadata>        m_metadata_ap;
 };
 
 size_t
@@ -1740,7 +1763,7 @@
                                                                                         accessibility, 
                                                                                         bit_size);
                                 
-                                GetClangASTContext().SetMetadata((uintptr_t)field_decl, MakeUserID(die->GetOffset()));
+                                GetClangASTContext().SetMetadataAsUserID ((uintptr_t)field_decl, MakeUserID(die->GetOffset()));
                             }
                             else
                             {
@@ -1803,6 +1826,8 @@
                                 assert (ivar_decl != NULL);
                             }
                             
+                            ClangASTMetadata metadata;
+                            metadata.SetUserID (MakeUserID(die->GetOffset()));
                             delayed_properties.push_back(DelayedAddObjCClassProperty(GetClangASTContext().getASTContext(),
                                                                                      class_clang_type,
                                                                                      prop_name,
@@ -1811,10 +1836,10 @@
                                                                                      prop_setter_name,
                                                                                      prop_getter_name,
                                                                                      prop_attributes,
-                                                                                     MakeUserID(die->GetOffset())));
+                                                                                     &metadata));
                             
                             if (ivar_decl)
-                                GetClangASTContext().SetMetadata((uintptr_t)ivar_decl, MakeUserID(die->GetOffset()));
+                                GetClangASTContext().SetMetadataAsUserID ((uintptr_t)ivar_decl, MakeUserID(die->GetOffset()));
                         }
                     }
                 }
@@ -3906,7 +3931,7 @@
                             assert(param_var_decl);
                             function_param_decls.push_back(param_var_decl);
                             
-                            GetClangASTContext().SetMetadata((uintptr_t)param_var_decl, MakeUserID(die->GetOffset()));
+                            GetClangASTContext().SetMetadataAsUserID ((uintptr_t)param_var_decl, MakeUserID(die->GetOffset()));
                         }
                     }
                 }
@@ -4085,8 +4110,7 @@
                     if (upper_bound > lower_bound)
                         num_elements = upper_bound - lower_bound + 1;
 
-                    if (num_elements > 0)
-                        element_orders.push_back (num_elements);
+                    element_orders.push_back (num_elements);
                 }
             }
             break;
@@ -5553,20 +5577,22 @@
                                 clang_type = ast.CreateClassTemplateSpecializationType (class_specialization_decl);
                                 clang_type_was_created = true;
                                 
-                                GetClangASTContext().SetMetadata((uintptr_t)class_template_decl, MakeUserID(die->GetOffset()));
-                                GetClangASTContext().SetMetadata((uintptr_t)class_specialization_decl, MakeUserID(die->GetOffset()));
+                                GetClangASTContext().SetMetadataAsUserID ((uintptr_t)class_template_decl, MakeUserID(die->GetOffset()));
+                                GetClangASTContext().SetMetadataAsUserID ((uintptr_t)class_specialization_decl, MakeUserID(die->GetOffset()));
                             }
                         }
 
                         if (!clang_type_was_created)
                         {
                             clang_type_was_created = true;
+                            ClangASTMetadata metadata;
+                            metadata.SetUserID(MakeUserID(die->GetOffset()));
                             clang_type = ast.CreateRecordType (decl_ctx, 
                                                                accessibility, 
                                                                type_name_cstr, 
                                                                tag_decl_kind, 
                                                                class_language,
-                                                               MakeUserID(die->GetOffset()));
+                                                               &metadata);
                         }
                     }
 
@@ -5769,6 +5795,7 @@
                     bool is_artificial = false;
                     dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
                     dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
+                    dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
 
                     unsigned type_quals = 0;
                     clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
@@ -5822,6 +5849,10 @@
                                     abstract_origin_die_offset = form_value.Reference(dwarf_cu);
                                     break;
 
+                                case DW_AT_object_pointer:
+                                    object_pointer_die_offset = form_value.Reference(dwarf_cu);
+                                    break;
+
                                 case DW_AT_allocated:
                                 case DW_AT_associated:
                                 case DW_AT_address_class:
@@ -5832,7 +5863,6 @@
                                 case DW_AT_frame_base:
                                 case DW_AT_high_pc:
                                 case DW_AT_low_pc:
-                                case DW_AT_object_pointer:
                                 case DW_AT_prototyped:
                                 case DW_AT_pure:
                                 case DW_AT_ranges:
@@ -5852,6 +5882,17 @@
                         }
                     }
 
+                    std::string object_pointer_name;
+                    if (object_pointer_die_offset != DW_INVALID_OFFSET)
+                    {
+                        // Get the name from the object pointer die
+                        StreamString s;
+                        if (DWARFDebugInfoEntry::GetName (this, dwarf_cu, object_pointer_die_offset, s))
+                        {
+                            object_pointer_name.assign(s.GetData());
+                        }
+                    }
+                    
                     DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
 
                     clang_type_t return_clang_type = NULL;
@@ -5885,14 +5926,14 @@
                     if (die->HasChildren())
                     {
                         bool skip_artificial = true;
-                        ParseChildParameters (sc, 
+                        ParseChildParameters (sc,
                                               containing_decl_ctx,
-                                              dwarf_cu, 
-                                              die, 
+                                              dwarf_cu,
+                                              die,
                                               skip_artificial,
                                               is_static,
-                                              type_list, 
-                                              function_param_types, 
+                                              type_list,
+                                              function_param_types,
                                               function_param_decls,
                                               type_quals,
                                               template_param_infos);
@@ -5900,7 +5941,7 @@
 
                     // clang_type will get the function prototype clang type after this call
                     clang_type = ast.CreateFunctionType (return_clang_type, 
-                                                         function_param_types.size() == 0 ? NULL : &function_param_types[0], 
+                                                         function_param_types.data(),
                                                          function_param_types.size(), 
                                                          is_variadic, 
                                                          type_quals);
@@ -5948,7 +5989,7 @@
                                     if (type_handled)
                                     {
                                         LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
-                                        GetClangASTContext().SetMetadata((uintptr_t)objc_method_decl, MakeUserID(die->GetOffset()));
+                                        GetClangASTContext().SetMetadataAsUserID ((uintptr_t)objc_method_decl, MakeUserID(die->GetOffset()));
                                     }
                                 }
                             }
@@ -6074,13 +6115,29 @@
                                                                                                     is_explicit,
                                                                                                     is_attr_used,
                                                                                                     is_artificial);
-                                                    LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
+                                                    
+                                                    type_handled = cxx_method_decl != NULL;
+
+                                                    if (type_handled)
+                                                    {
+                                                        LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
 
-                                                    Host::SetCrashDescription (NULL);
+                                                        Host::SetCrashDescription (NULL);
 
-                                                    type_handled = cxx_method_decl != NULL;
-                                                    
-                                                    GetClangASTContext().SetMetadata((uintptr_t)cxx_method_decl, MakeUserID(die->GetOffset()));
+                                                        
+                                                        ClangASTMetadata metadata;
+                                                        metadata.SetUserID(MakeUserID(die->GetOffset()));
+                                                        
+                                                        if (!object_pointer_name.empty())
+                                                        {
+                                                            metadata.SetObjectPtrName(object_pointer_name.c_str());
+                                                            if (log)
+                                                                log->Printf ("Setting object pointer name: %s on method object 0x%ld.\n",
+                                                                             object_pointer_name.c_str(),
+                                                                             (uintptr_t) cxx_method_decl);
+                                                        }
+                                                        GetClangASTContext().SetMetadata ((uintptr_t)cxx_method_decl, metadata);
+                                                    }
                                                 }
                                             }
                                             else
@@ -6146,7 +6203,18 @@
                                                            &function_param_decls.front(), 
                                                            function_param_decls.size());
                             
-                            GetClangASTContext().SetMetadata((uintptr_t)function_decl, MakeUserID(die->GetOffset()));
+                            ClangASTMetadata metadata;
+                            metadata.SetUserID(MakeUserID(die->GetOffset()));
+                            
+                            if (!object_pointer_name.empty())
+                            {
+                                metadata.SetObjectPtrName(object_pointer_name.c_str());
+                                if (log)
+                                    log->Printf ("Setting object pointer name: %s on function object 0x%ld.\n",
+                                                 object_pointer_name.c_str(),
+                                                 (uintptr_t) function_decl);
+                            }
+                            GetClangASTContext().SetMetadata ((uintptr_t)function_decl, metadata);
                         }
                     }
                     type_sp.reset( new Type (MakeUserID(die->GetOffset()), 

Added: lldb/branches/windows/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp.orig
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp.orig?rev=167218&view=auto
==============================================================================
--- lldb/branches/windows/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp.orig (added)
+++ lldb/branches/windows/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp.orig Thu Nov  1 02:04:04 2012
@@ -0,0 +1,7304 @@
+//===-- SymbolFileDWARF.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFileDWARF.h"
+
+// Other libraries and framework includes
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Sema/DeclSpec.h"
+
+#include "llvm/Support/Casting.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/Core/Value.h"
+
+#include "lldb/Host/Host.h"
+
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/VariableList.h"
+
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
+
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugAbbrev.h"
+#include "DWARFDebugAranges.h"
+#include "DWARFDebugInfo.h"
+#include "DWARFDebugInfoEntry.h"
+#include "DWARFDebugLine.h"
+#include "DWARFDebugPubnames.h"
+#include "DWARFDebugRanges.h"
+#include "DWARFDeclContext.h"
+#include "DWARFDIECollection.h"
+#include "DWARFFormValue.h"
+#include "DWARFLocationList.h"
+#include "LogChannelDWARF.h"
+#include "SymbolFileDWARFDebugMap.h"
+
+#include <map>
+
+//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
+
+#ifdef ENABLE_DEBUG_PRINTF
+#include <stdio.h>
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#else
+#define DEBUG_PRINTF(fmt, ...)
+#endif
+
+#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
+
+using namespace lldb;
+using namespace lldb_private;
+
+//static inline bool
+//child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
+//{
+//    switch (tag)
+//    {
+//    default:
+//        break;
+//    case DW_TAG_subprogram:
+//    case DW_TAG_inlined_subroutine:
+//    case DW_TAG_class_type:
+//    case DW_TAG_structure_type:
+//    case DW_TAG_union_type:
+//        return true;
+//    }
+//    return false;
+//}
+//
+static AccessType
+DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
+{
+    switch (dwarf_accessibility)
+    {
+        case DW_ACCESS_public:      return eAccessPublic;
+        case DW_ACCESS_private:     return eAccessPrivate;
+        case DW_ACCESS_protected:   return eAccessProtected;
+        default:                    break;
+    }
+    return eAccessNone;
+}
+
+#if defined(LLDB_CONFIGURATION_DEBUG) or defined(LLDB_CONFIGURATION_RELEASE)
+
+class DIEStack
+{
+public:
+    
+    void Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
+    {
+        m_dies.push_back (DIEInfo(cu, die));
+    }
+
+    
+    void LogDIEs (Log *log, SymbolFileDWARF *dwarf)
+    {
+        StreamString log_strm;
+        const size_t n = m_dies.size();
+        log_strm.Printf("DIEStack[%llu]:\n", (uint64_t)n);
+        for (size_t i=0; i<n; i++)
+        {
+            DWARFCompileUnit *cu = m_dies[i].cu;
+            const DWARFDebugInfoEntry *die = m_dies[i].die;
+            std::string qualified_name;
+            die->GetQualifiedName(dwarf, cu, qualified_name);
+            log_strm.Printf ("[%llu] 0x%8.8x: %s name='%s'\n", 
+                             (uint64_t)i,
+                             die->GetOffset(), 
+                             DW_TAG_value_to_name(die->Tag()), 
+                             qualified_name.c_str());
+        }
+        log->PutCString(log_strm.GetData());
+    }
+    void Pop ()
+    {
+        m_dies.pop_back();
+    }
+    
+    class ScopedPopper
+    {
+    public:
+        ScopedPopper (DIEStack &die_stack) :
+            m_die_stack (die_stack),
+            m_valid (false)
+        {
+        }
+        
+        void
+        Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
+        {
+            m_valid = true;
+            m_die_stack.Push (cu, die);
+        }
+        
+        ~ScopedPopper ()
+        {
+            if (m_valid)
+                m_die_stack.Pop();
+        }
+        
+        
+        
+    protected:
+        DIEStack &m_die_stack;
+        bool m_valid;
+    };
+
+protected:
+    struct DIEInfo {
+        DIEInfo (DWARFCompileUnit *c, const DWARFDebugInfoEntry *d) :
+            cu(c),
+            die(d)
+        {
+        }
+        DWARFCompileUnit *cu;
+        const DWARFDebugInfoEntry *die;
+    };
+    typedef std::vector<DIEInfo> Stack;
+    Stack m_dies;
+};
+#endif
+
+void
+SymbolFileDWARF::Initialize()
+{
+    LogChannelDWARF::Initialize();
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   GetPluginDescriptionStatic(),
+                                   CreateInstance);
+}
+
+void
+SymbolFileDWARF::Terminate()
+{
+    PluginManager::UnregisterPlugin (CreateInstance);
+    LogChannelDWARF::Initialize();
+}
+
+
+const char *
+SymbolFileDWARF::GetPluginNameStatic()
+{
+    return "dwarf";
+}
+
+const char *
+SymbolFileDWARF::GetPluginDescriptionStatic()
+{
+    return "DWARF and DWARF3 debug symbol file reader.";
+}
+
+
+SymbolFile*
+SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
+{
+    return new SymbolFileDWARF(obj_file);
+}
+
+TypeList *          
+SymbolFileDWARF::GetTypeList ()
+{
+    if (GetDebugMapSymfile ())
+        return m_debug_map_symfile->GetTypeList();
+    return m_obj_file->GetModule()->GetTypeList();
+
+}
+
+//----------------------------------------------------------------------
+// Gets the first parent that is a lexical block, function or inlined
+// subroutine, or compile unit.
+//----------------------------------------------------------------------
+static const DWARFDebugInfoEntry *
+GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
+{
+    const DWARFDebugInfoEntry *die;
+    for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
+    {
+        dw_tag_t tag = die->Tag();
+
+        switch (tag)
+        {
+        case DW_TAG_compile_unit:
+        case DW_TAG_subprogram:
+        case DW_TAG_inlined_subroutine:
+        case DW_TAG_lexical_block:
+            return die;
+        }
+    }
+    return NULL;
+}
+
+
+SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
+    SymbolFile (objfile),
+    UserID (0),  // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
+    m_debug_map_module_wp (),
+    m_debug_map_symfile (NULL),
+    m_clang_tu_decl (NULL),
+    m_flags(),
+    m_data_debug_abbrev (),
+    m_data_debug_aranges (),
+    m_data_debug_frame (),
+    m_data_debug_info (),
+    m_data_debug_line (),
+    m_data_debug_loc (),
+    m_data_debug_ranges (),
+    m_data_debug_str (),
+    m_data_apple_names (),
+    m_data_apple_types (),
+    m_data_apple_namespaces (),
+    m_abbr(),
+    m_info(),
+    m_line(),
+    m_apple_names_ap (),
+    m_apple_types_ap (),
+    m_apple_namespaces_ap (),
+    m_apple_objc_ap (),
+    m_function_basename_index(),
+    m_function_fullname_index(),
+    m_function_method_index(),
+    m_function_selector_index(),
+    m_objc_class_selectors_index(),
+    m_global_index(),
+    m_type_index(),
+    m_namespace_index(),
+    m_indexed (false),
+    m_is_external_ast_source (false),
+    m_using_apple_tables (false),
+    m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
+    m_ranges(),
+    m_unique_ast_type_map ()
+{
+}
+
+SymbolFileDWARF::~SymbolFileDWARF()
+{
+    if (m_is_external_ast_source)
+    {
+        ModuleSP module_sp (m_obj_file->GetModule());
+        if (module_sp)
+            module_sp->GetClangASTContext().RemoveExternalSource ();
+    }
+}
+
+static const ConstString &
+GetDWARFMachOSegmentName ()
+{
+    static ConstString g_dwarf_section_name ("__DWARF");
+    return g_dwarf_section_name;
+}
+
+UniqueDWARFASTTypeMap &
+SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
+{
+    if (GetDebugMapSymfile ())
+        return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
+    return m_unique_ast_type_map;
+}
+
+ClangASTContext &       
+SymbolFileDWARF::GetClangASTContext ()
+{
+    if (GetDebugMapSymfile ())
+        return m_debug_map_symfile->GetClangASTContext ();
+
+    ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
+    if (!m_is_external_ast_source)
+    {
+        m_is_external_ast_source = true;
+        llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
+            new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
+                                                 SymbolFileDWARF::CompleteObjCInterfaceDecl,
+                                                 SymbolFileDWARF::FindExternalVisibleDeclsByName,
+                                                 SymbolFileDWARF::LayoutRecordType,
+                                                 this));
+        ast.SetExternalSource (ast_source_ap);
+    }
+    return ast;
+}
+
+void
+SymbolFileDWARF::InitializeObject()
+{
+    // Install our external AST source callbacks so we can complete Clang types.
+    ModuleSP module_sp (m_obj_file->GetModule());
+    if (module_sp)
+    {
+        const SectionList *section_list = m_obj_file->GetSectionList();
+
+        const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
+
+        // Memory map the DWARF mach-o segment so we have everything mmap'ed
+        // to keep our heap memory usage down.
+        if (section)
+            m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
+    }
+    get_apple_names_data();
+    if (m_data_apple_names.GetByteSize() > 0)
+    {
+        m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names"));
+        if (m_apple_names_ap->IsValid())
+            m_using_apple_tables = true;
+        else
+            m_apple_names_ap.reset();
+    }
+    get_apple_types_data();
+    if (m_data_apple_types.GetByteSize() > 0)
+    {
+        m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types"));
+        if (m_apple_types_ap->IsValid())
+            m_using_apple_tables = true;
+        else
+            m_apple_types_ap.reset();
+    }
+
+    get_apple_namespaces_data();
+    if (m_data_apple_namespaces.GetByteSize() > 0)
+    {
+        m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces"));
+        if (m_apple_namespaces_ap->IsValid())
+            m_using_apple_tables = true;
+        else
+            m_apple_namespaces_ap.reset();
+    }
+
+    get_apple_objc_data();
+    if (m_data_apple_objc.GetByteSize() > 0)
+    {
+        m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc"));
+        if (m_apple_objc_ap->IsValid())
+            m_using_apple_tables = true;
+        else
+            m_apple_objc_ap.reset();
+    }
+}
+
+bool
+SymbolFileDWARF::SupportedVersion(uint16_t version)
+{
+    return version == 2 || version == 3;
+}
+
+uint32_t
+SymbolFileDWARF::CalculateAbilities ()
+{
+    uint32_t abilities = 0;
+    if (m_obj_file != NULL)
+    {
+        const Section* section = NULL;
+        const SectionList *section_list = m_obj_file->GetSectionList();
+        if (section_list == NULL)
+            return 0;
+
+        uint64_t debug_abbrev_file_size = 0;
+        uint64_t debug_info_file_size = 0;
+        uint64_t debug_line_file_size = 0;
+
+        section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
+        
+        if (section)
+            section_list = &section->GetChildren ();
+        
+        section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
+        if (section != NULL)
+        {
+            debug_info_file_size = section->GetFileSize();
+
+            section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
+            if (section)
+                debug_abbrev_file_size = section->GetFileSize();
+            else
+                m_flags.Set (flagsGotDebugAbbrevData);
+
+            section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
+            if (!section)
+                m_flags.Set (flagsGotDebugArangesData);
+
+            section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
+            if (!section)
+                m_flags.Set (flagsGotDebugFrameData);
+
+            section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
+            if (section)
+                debug_line_file_size = section->GetFileSize();
+            else
+                m_flags.Set (flagsGotDebugLineData);
+
+            section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
+            if (!section)
+                m_flags.Set (flagsGotDebugLocData);
+
+            section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
+            if (!section)
+                m_flags.Set (flagsGotDebugMacInfoData);
+
+            section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
+            if (!section)
+                m_flags.Set (flagsGotDebugPubNamesData);
+
+            section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
+            if (!section)
+                m_flags.Set (flagsGotDebugPubTypesData);
+
+            section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
+            if (!section)
+                m_flags.Set (flagsGotDebugRangesData);
+
+            section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
+            if (!section)
+                m_flags.Set (flagsGotDebugStrData);
+        }
+        else
+        {
+            const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString();
+            if (symfile_dir_cstr)
+            {
+                if (strcasestr(symfile_dir_cstr, ".dsym"))
+                {
+                    if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo)
+                    {
+                        // We have a dSYM file that didn't have a any debug info.
+                        // If the string table has a size of 1, then it was made from
+                        // an executable with no debug info, or from an executable that
+                        // was stripped.
+                        section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
+                        if (section && section->GetFileSize() == 1)
+                        {
+                            m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info.");
+                        }
+                    }
+                }
+            }
+        }
+
+        if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
+            abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
+
+        if (debug_line_file_size > 0)
+            abilities |= LineTables;
+    }
+    return abilities;
+}
+
+const DataExtractor&
+SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
+{
+    if (m_flags.IsClear (got_flag))
+    {
+        m_flags.Set (got_flag);
+        const SectionList *section_list = m_obj_file->GetSectionList();
+        if (section_list)
+        {
+            SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
+            if (section_sp)
+            {
+                // See if we memory mapped the DWARF segment?
+                if (m_dwarf_data.GetByteSize())
+                {
+                    data.SetData(m_dwarf_data, section_sp->GetOffset (), section_sp->GetFileSize());
+                }
+                else
+                {
+                    if (m_obj_file->ReadSectionData (section_sp.get(), data) == 0)
+                        data.Clear();
+                }
+            }
+        }
+    }
+    return data;
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_abbrev_data()
+{
+    return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_aranges_data()
+{
+    return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_frame_data()
+{
+    return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_info_data()
+{
+    return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_line_data()
+{
+    return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_loc_data()
+{
+    return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_ranges_data()
+{
+    return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_debug_str_data()
+{
+    return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_apple_names_data()
+{
+    return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_apple_types_data()
+{
+    return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_apple_namespaces_data()
+{
+    return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
+}
+
+const DataExtractor&
+SymbolFileDWARF::get_apple_objc_data()
+{
+    return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc);
+}
+
+
+DWARFDebugAbbrev*
+SymbolFileDWARF::DebugAbbrev()
+{
+    if (m_abbr.get() == NULL)
+    {
+        const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
+        if (debug_abbrev_data.GetByteSize() > 0)
+        {
+            m_abbr.reset(new DWARFDebugAbbrev());
+            if (m_abbr.get())
+                m_abbr->Parse(debug_abbrev_data);
+        }
+    }
+    return m_abbr.get();
+}
+
+const DWARFDebugAbbrev*
+SymbolFileDWARF::DebugAbbrev() const
+{
+    return m_abbr.get();
+}
+
+
+DWARFDebugInfo*
+SymbolFileDWARF::DebugInfo()
+{
+    if (m_info.get() == NULL)
+    {
+        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
+        if (get_debug_info_data().GetByteSize() > 0)
+        {
+            m_info.reset(new DWARFDebugInfo());
+            if (m_info.get())
+            {
+                m_info->SetDwarfData(this);
+            }
+        }
+    }
+    return m_info.get();
+}
+
+const DWARFDebugInfo*
+SymbolFileDWARF::DebugInfo() const
+{
+    return m_info.get();
+}
+
+DWARFCompileUnit*
+SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
+{
+    DWARFDebugInfo* info = DebugInfo();
+    if (info)
+    {
+        if (GetDebugMapSymfile ())
+        {
+            // The debug map symbol file made the compile units for this DWARF
+            // file which is .o file with DWARF in it, and we should have
+            // only 1 compile unit which is at offset zero in the DWARF.
+            // TODO: modify to support LTO .o files where each .o file might
+            // have multiple DW_TAG_compile_unit tags.
+            return info->GetCompileUnit(0).get();
+        }
+        else
+        {
+            // Just a normal DWARF file whose user ID for the compile unit is
+            // the DWARF offset itself
+            return info->GetCompileUnit((dw_offset_t)comp_unit->GetID()).get();
+        }
+    }
+    return NULL;
+}
+
+
+DWARFDebugRanges*
+SymbolFileDWARF::DebugRanges()
+{
+    if (m_ranges.get() == NULL)
+    {
+        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
+        if (get_debug_ranges_data().GetByteSize() > 0)
+        {
+            m_ranges.reset(new DWARFDebugRanges());
+            if (m_ranges.get())
+                m_ranges->Extract(this);
+        }
+    }
+    return m_ranges.get();
+}
+
+const DWARFDebugRanges*
+SymbolFileDWARF::DebugRanges() const
+{
+    return m_ranges.get();
+}
+
+lldb::CompUnitSP
+SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
+{
+    CompUnitSP cu_sp;
+    if (dwarf_cu)
+    {
+        CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData();
+        if (comp_unit)
+        {
+            // We already parsed this compile unit, had out a shared pointer to it
+            cu_sp = comp_unit->shared_from_this();
+        }
+        else
+        {
+            if (GetDebugMapSymfile ())
+            {
+                // Let the debug map create the compile unit
+                cu_sp = m_debug_map_symfile->GetCompileUnit(this);
+                dwarf_cu->SetUserData(cu_sp.get());
+            }
+            else
+            {
+                ModuleSP module_sp (m_obj_file->GetModule());
+                if (module_sp)
+                {
+                    const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
+                    if (cu_die)
+                    {
+                        const char * cu_die_name = cu_die->GetName(this, dwarf_cu);
+                        const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, NULL);
+                        LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0);
+                        if (cu_die_name)
+                        {
+                            std::string ramapped_file;
+                            FileSpec cu_file_spec;
+
+                            if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
+                            {
+                                // If we have a full path to the compile unit, we don't need to resolve
+                                // the file.  This can be expensive e.g. when the source files are NFS mounted.
+                                if (module_sp->RemapSourceFile(cu_die_name, ramapped_file))
+                                    cu_file_spec.SetFile (ramapped_file.c_str(), false);
+                                else
+                                    cu_file_spec.SetFile (cu_die_name, false);
+                            }
+                            else
+                            {
+                                std::string fullpath(cu_comp_dir);
+                                if (*fullpath.rbegin() != '/')
+                                    fullpath += '/';
+                                fullpath += cu_die_name;
+                                if (module_sp->RemapSourceFile (fullpath.c_str(), ramapped_file))
+                                    cu_file_spec.SetFile (ramapped_file.c_str(), false);
+                                else
+                                    cu_file_spec.SetFile (fullpath.c_str(), false);
+                            }
+
+                            cu_sp.reset(new CompileUnit (module_sp,
+                                                         dwarf_cu,
+                                                         cu_file_spec, 
+                                                         MakeUserID(dwarf_cu->GetOffset()),
+                                                         cu_language));
+                            if (cu_sp)
+                            {
+                                dwarf_cu->SetUserData(cu_sp.get());
+                                
+                                // Figure out the compile unit index if we weren't given one
+                                if (cu_idx == UINT32_MAX)
+                                    DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
+                                
+                                m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return cu_sp;
+}
+
+uint32_t
+SymbolFileDWARF::GetNumCompileUnits()
+{
+    DWARFDebugInfo* info = DebugInfo();
+    if (info)
+        return info->GetNumCompileUnits();
+    return 0;
+}
+
+CompUnitSP
+SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
+{
+    CompUnitSP cu_sp;
+    DWARFDebugInfo* info = DebugInfo();
+    if (info)
+    {
+        DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
+        if (dwarf_cu)
+            cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
+    }
+    return cu_sp;
+}
+
+static void
+AddRangesToBlock (Block& block,
+                  DWARFDebugRanges::RangeList& ranges,
+                  addr_t block_base_addr)
+{
+    const size_t num_ranges = ranges.GetSize();
+    for (size_t i = 0; i<num_ranges; ++i)
+    {
+        const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
+        const addr_t range_base = range.GetRangeBase();
+        assert (range_base >= block_base_addr);
+        block.AddRange(Block::Range (range_base - block_base_addr, range.GetByteSize()));;
+    }
+    block.FinalizeRanges ();
+}
+
+
+Function *
+SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
+{
+    DWARFDebugRanges::RangeList func_ranges;
+    const char *name = NULL;
+    const char *mangled = NULL;
+    int decl_file = 0;
+    int decl_line = 0;
+    int decl_column = 0;
+    int call_file = 0;
+    int call_line = 0;
+    int call_column = 0;
+    DWARFExpression frame_base;
+
+    assert (die->Tag() == DW_TAG_subprogram);
+    
+    if (die->Tag() != DW_TAG_subprogram)
+        return NULL;
+
+    if (die->GetDIENamesAndRanges (this, 
+                                   dwarf_cu, 
+                                   name, 
+                                   mangled, 
+                                   func_ranges, 
+                                   decl_file, 
+                                   decl_line, 
+                                   decl_column, 
+                                   call_file, 
+                                   call_line, 
+                                   call_column, 
+                                   &frame_base))
+    {
+        // Union of all ranges in the function DIE (if the function is discontiguous)
+        AddressRange func_range;
+        lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0);
+        lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0);
+        if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
+        {
+            func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
+            if (func_range.GetBaseAddress().IsValid())
+                func_range.SetByteSize(highest_func_addr - lowest_func_addr);
+        }
+
+        if (func_range.GetBaseAddress().IsValid())
+        {
+            Mangled func_name;
+            if (mangled)
+                func_name.SetValue(ConstString(mangled), true);
+            else if (name)
+                func_name.SetValue(ConstString(name), false);
+
+            FunctionSP func_sp;
+            std::auto_ptr<Declaration> decl_ap;
+            if (decl_file != 0 || decl_line != 0 || decl_column != 0)
+                decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), 
+                                               decl_line, 
+                                               decl_column));
+
+            // Supply the type _only_ if it has already been parsed
+            Type *func_type = m_die_to_type.lookup (die);
+
+            assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
+
+            func_range.GetBaseAddress().ResolveLinkedAddress();
+
+            const user_id_t func_user_id = MakeUserID(die->GetOffset());
+            func_sp.reset(new Function (sc.comp_unit,
+                                        func_user_id,       // UserID is the DIE offset
+                                        func_user_id,
+                                        func_name,
+                                        func_type,
+                                        func_range));           // first address range
+
+            if (func_sp.get() != NULL)
+            {
+                if (frame_base.IsValid())
+                    func_sp->GetFrameBaseExpression() = frame_base;
+                sc.comp_unit->AddFunction(func_sp);
+                return func_sp.get();
+            }
+        }
+    }
+    return NULL;
+}
+
+lldb::LanguageType
+SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
+{
+    assert (sc.comp_unit);
+    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+    if (dwarf_cu)
+    {
+        const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly();
+        if (die)
+        {
+            const uint32_t language = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0);
+            if (language)
+                return (lldb::LanguageType)language;
+        }
+    }
+    return eLanguageTypeUnknown;
+}
+
+size_t
+SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
+{
+    assert (sc.comp_unit);
+    size_t functions_added = 0;
+    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+    if (dwarf_cu)
+    {
+        DWARFDIECollection function_dies;
+        const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
+        size_t func_idx;
+        for (func_idx = 0; func_idx < num_functions; ++func_idx)
+        {
+            const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
+            if (sc.comp_unit->FindFunctionByUID (MakeUserID(die->GetOffset())).get() == NULL)
+            {
+                if (ParseCompileUnitFunction(sc, dwarf_cu, die))
+                    ++functions_added;
+            }
+        }
+        //FixupTypes();
+    }
+    return functions_added;
+}
+
+bool
+SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
+{
+    assert (sc.comp_unit);
+    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+    assert (dwarf_cu);
+    const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+
+    if (cu_die)
+    {
+        const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, NULL);
+        dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
+
+        // All file indexes in DWARF are one based and a file of index zero is
+        // supposed to be the compile unit itself.
+        support_files.Append (*sc.comp_unit);
+
+        return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
+    }
+    return false;
+}
+
+struct ParseDWARFLineTableCallbackInfo
+{
+    LineTable* line_table;
+    const SectionList *section_list;
+    lldb::addr_t prev_sect_file_base_addr;
+    lldb::addr_t curr_sect_file_base_addr;
+    bool is_oso_for_debug_map;
+    bool prev_in_final_executable;
+    DWARFDebugLine::Row prev_row;
+    SectionSP prev_section_sp;
+    SectionSP curr_section_sp;
+};
+
+//----------------------------------------------------------------------
+// ParseStatementTableCallback
+//----------------------------------------------------------------------
+static void
+ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
+{
+    LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
+    if (state.row == DWARFDebugLine::State::StartParsingLineTable)
+    {
+        // Just started parsing the line table
+    }
+    else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
+    {
+        // Done parsing line table, nothing to do for the cleanup
+    }
+    else
+    {
+        ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
+        // We have a new row, lets append it
+
+        if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
+        {
+            info->prev_section_sp = info->curr_section_sp;
+            info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
+            // If this is an end sequence entry, then we subtract one from the
+            // address to make sure we get an address that is not the end of
+            // a section.
+            if (state.end_sequence && state.address != 0)
+                info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
+            else
+                info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
+
+            if (info->curr_section_sp.get())
+                info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
+            else
+                info->curr_sect_file_base_addr = 0;
+        }
+        if (info->curr_section_sp.get())
+        {
+            lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
+            // Check for the fancy section magic to determine if we
+
+            if (info->is_oso_for_debug_map)
+            {
+                // When this is a debug map object file that contains DWARF
+                // (referenced from an N_OSO debug map nlist entry) we will have
+                // a file address in the file range for our section from the
+                // original .o file, and a load address in the executable that
+                // contains the debug map.
+                //
+                // If the sections for the file range and load range are
+                // different, we have a remapped section for the function and
+                // this address is resolved. If they are the same, then the
+                // function for this address didn't make it into the final
+                // executable.
+                bool curr_in_final_executable = (bool) info->curr_section_sp->GetLinkedSection ();
+
+                // If we are doing DWARF with debug map, then we need to carefully
+                // add each line table entry as there may be gaps as functions
+                // get moved around or removed.
+                if (!info->prev_row.end_sequence && info->prev_section_sp.get())
+                {
+                    if (info->prev_in_final_executable)
+                    {
+                        bool terminate_previous_entry = false;
+                        if (!curr_in_final_executable)
+                        {
+                            // Check for the case where the previous line entry
+                            // in a function made it into the final executable,
+                            // yet the current line entry falls in a function
+                            // that didn't. The line table used to be contiguous
+                            // through this address range but now it isn't. We
+                            // need to terminate the previous line entry so
+                            // that we can reconstruct the line range correctly
+                            // for it and to keep the line table correct.
+                            terminate_previous_entry = true;
+                        }
+                        else if (info->curr_section_sp.get() != info->prev_section_sp.get())
+                        {
+                            // Check for cases where the line entries used to be
+                            // contiguous address ranges, but now they aren't.
+                            // This can happen when order files specify the
+                            // ordering of the functions.
+                            lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
+                            Section *curr_sect = info->curr_section_sp.get();
+                            Section *prev_sect = info->prev_section_sp.get();
+                            assert (curr_sect->GetLinkedSection());
+                            assert (prev_sect->GetLinkedSection());
+                            lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
+                            lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
+                            lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
+                            lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
+                            if (object_file_addr_delta != linked_file_addr_delta)
+                                terminate_previous_entry = true;
+                        }
+
+                        if (terminate_previous_entry)
+                        {
+                            line_table->InsertLineEntry (info->prev_section_sp,
+                                                         state.address - info->prev_sect_file_base_addr,
+                                                         info->prev_row.line,
+                                                         info->prev_row.column,
+                                                         info->prev_row.file,
+                                                         false,                 // is_stmt
+                                                         false,                 // basic_block
+                                                         false,                 // state.prologue_end
+                                                         false,                 // state.epilogue_begin
+                                                         true);                 // end_sequence);
+                        }
+                    }
+                }
+
+                if (curr_in_final_executable)
+                {
+                    line_table->InsertLineEntry (info->curr_section_sp,
+                                                 curr_line_section_offset,
+                                                 state.line,
+                                                 state.column,
+                                                 state.file,
+                                                 state.is_stmt,
+                                                 state.basic_block,
+                                                 state.prologue_end,
+                                                 state.epilogue_begin,
+                                                 state.end_sequence);
+                    info->prev_section_sp = info->curr_section_sp;
+                }
+                else
+                {
+                    // If the current address didn't make it into the final
+                    // executable, the current section will be the __text
+                    // segment in the .o file, so we need to clear this so
+                    // we can catch the next function that did make it into
+                    // the final executable.
+                    info->prev_section_sp.reset();
+                    info->curr_section_sp.reset();
+                }
+
+                info->prev_in_final_executable = curr_in_final_executable;
+            }
+            else
+            {
+                // We are not in an object file that contains DWARF for an
+                // N_OSO, this is just a normal DWARF file. The DWARF spec
+                // guarantees that the addresses will be in increasing order
+                // so, since we store line tables in file address order, we
+                // can always just append the line entry without needing to
+                // search for the correct insertion point (we don't need to
+                // use LineEntry::InsertLineEntry()).
+                line_table->AppendLineEntry (info->curr_section_sp,
+                                             curr_line_section_offset,
+                                             state.line,
+                                             state.column,
+                                             state.file,
+                                             state.is_stmt,
+                                             state.basic_block,
+                                             state.prologue_end,
+                                             state.epilogue_begin,
+                                             state.end_sequence);
+            }
+        }
+
+        info->prev_row = state;
+    }
+}
+
+bool
+SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
+{
+    assert (sc.comp_unit);
+    if (sc.comp_unit->GetLineTable() != NULL)
+        return true;
+
+    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+    if (dwarf_cu)
+    {
+        const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
+        if (dwarf_cu_die)
+        {
+            const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
+            if (cu_line_offset != DW_INVALID_OFFSET)
+            {
+                std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
+                if (line_table_ap.get())
+                {
+                    ParseDWARFLineTableCallbackInfo info = { 
+                        line_table_ap.get(), 
+                        m_obj_file->GetSectionList(), 
+                        0, 
+                        0, 
+                        GetDebugMapSymfile () != NULL,
+                        false, 
+                        DWARFDebugLine::Row(), 
+                        SectionSP(), 
+                        SectionSP()
+                    };
+                    uint32_t offset = cu_line_offset;
+                    DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
+                    sc.comp_unit->SetLineTable(line_table_ap.release());
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+size_t
+SymbolFileDWARF::ParseFunctionBlocks
+(
+    const SymbolContext& sc,
+    Block *parent_block,
+    DWARFCompileUnit* dwarf_cu,
+    const DWARFDebugInfoEntry *die,
+    addr_t subprogram_low_pc,
+    uint32_t depth
+)
+{
+    size_t blocks_added = 0;
+    while (die != NULL)
+    {
+        dw_tag_t tag = die->Tag();
+
+        switch (tag)
+        {
+        case DW_TAG_inlined_subroutine:
+        case DW_TAG_subprogram:
+        case DW_TAG_lexical_block:
+            {
+                Block *block = NULL;
+                if (tag == DW_TAG_subprogram)
+                {
+                    // Skip any DW_TAG_subprogram DIEs that are inside
+                    // of a normal or inlined functions. These will be 
+                    // parsed on their own as separate entities.
+
+                    if (depth > 0)
+                        break;
+
+                    block = parent_block;
+                }
+                else
+                {
+                    BlockSP block_sp(new Block (MakeUserID(die->GetOffset())));
+                    parent_block->AddChild(block_sp);
+                    block = block_sp.get();
+                }
+                DWARFDebugRanges::RangeList ranges;
+                const char *name = NULL;
+                const char *mangled_name = NULL;
+
+                int decl_file = 0;
+                int decl_line = 0;
+                int decl_column = 0;
+                int call_file = 0;
+                int call_line = 0;
+                int call_column = 0;
+                if (die->GetDIENamesAndRanges (this, 
+                                               dwarf_cu, 
+                                               name, 
+                                               mangled_name, 
+                                               ranges, 
+                                               decl_file, decl_line, decl_column,
+                                               call_file, call_line, call_column))
+                {
+                    if (tag == DW_TAG_subprogram)
+                    {
+                        assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
+                        subprogram_low_pc = ranges.GetMinRangeBase(0);
+                    }
+                    else if (tag == DW_TAG_inlined_subroutine)
+                    {
+                        // We get called here for inlined subroutines in two ways.  
+                        // The first time is when we are making the Function object 
+                        // for this inlined concrete instance.  Since we're creating a top level block at
+                        // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS.  So we need to 
+                        // adjust the containing address.
+                        // The second time is when we are parsing the blocks inside the function that contains
+                        // the inlined concrete instance.  Since these will be blocks inside the containing "real"
+                        // function the offset will be for that function.  
+                        if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
+                        {
+                            subprogram_low_pc = ranges.GetMinRangeBase(0);
+                        }
+                    }
+                    
+                    AddRangesToBlock (*block, ranges, subprogram_low_pc);
+
+                    if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
+                    {
+                        std::auto_ptr<Declaration> decl_ap;
+                        if (decl_file != 0 || decl_line != 0 || decl_column != 0)
+                            decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), 
+                                                          decl_line, decl_column));
+
+                        std::auto_ptr<Declaration> call_ap;
+                        if (call_file != 0 || call_line != 0 || call_column != 0)
+                            call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), 
+                                                          call_line, call_column));
+
+                        block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
+                    }
+
+                    ++blocks_added;
+
+                    if (die->HasChildren())
+                    {
+                        blocks_added += ParseFunctionBlocks (sc, 
+                                                             block, 
+                                                             dwarf_cu, 
+                                                             die->GetFirstChild(), 
+                                                             subprogram_low_pc, 
+                                                             depth + 1);
+                    }
+                }
+            }
+            break;
+        default:
+            break;
+        }
+
+        // Only parse siblings of the block if we are not at depth zero. A depth
+        // of zero indicates we are currently parsing the top level 
+        // DW_TAG_subprogram DIE
+        
+        if (depth == 0)
+            die = NULL;
+        else
+            die = die->GetSibling();
+    }
+    return blocks_added;
+}
+
+bool
+SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu,
+                                   const DWARFDebugInfoEntry *die,
+                                   ClangASTContext::TemplateParameterInfos &template_param_infos)
+{
+    const dw_tag_t tag = die->Tag();
+    
+    switch (tag)
+    {
+    case DW_TAG_template_type_parameter:
+    case DW_TAG_template_value_parameter:
+        {
+            const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
+
+            DWARFDebugInfoEntry::Attributes attributes;
+            const size_t num_attributes = die->GetAttributes (this, 
+                                                              dwarf_cu, 
+                                                              fixed_form_sizes, 
+                                                              attributes);
+            const char *name = NULL;
+            Type *lldb_type = NULL;
+            clang_type_t clang_type = NULL;
+            uint64_t uval64 = 0;
+            bool uval64_valid = false;
+            if (num_attributes > 0)
+            {
+                DWARFFormValue form_value;
+                for (size_t i=0; i<num_attributes; ++i)
+                {
+                    const dw_attr_t attr = attributes.AttributeAtIndex(i);
+                    
+                    switch (attr)
+                    {
+                        case DW_AT_name:
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                                name = form_value.AsCString(&get_debug_str_data());
+                            break;
+                            
+                        case DW_AT_type:
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                const dw_offset_t type_die_offset = form_value.Reference(dwarf_cu);
+                                lldb_type = ResolveTypeUID(type_die_offset);
+                                if (lldb_type)
+                                    clang_type = lldb_type->GetClangForwardType();
+                            }
+                            break;
+                            
+                        case DW_AT_const_value:
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                uval64_valid = true;
+                                uval64 = form_value.Unsigned();
+                            }
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                
+                if (name && lldb_type && clang_type)
+                {
+                    bool is_signed = false;
+                    template_param_infos.names.push_back(name);
+                    clang::QualType clang_qual_type (clang::QualType::getFromOpaquePtr (clang_type));
+                    if (tag == DW_TAG_template_value_parameter && ClangASTContext::IsIntegerType (clang_type, is_signed) && uval64_valid)
+                    {
+                        llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
+                        template_param_infos.args.push_back (clang::TemplateArgument (*GetClangASTContext().getASTContext(),
+                                                                                      llvm::APSInt(apint),
+                                                                                      clang_qual_type));
+                    }
+                    else
+                    {
+                        template_param_infos.args.push_back (clang::TemplateArgument (clang_qual_type));
+                    }
+                }
+                else
+                {
+                    return false;
+                }
+                
+            }
+        }
+        return true;
+
+    default:
+        break;
+    }
+    return false;
+}
+
+bool
+SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu,
+                                              const DWARFDebugInfoEntry *parent_die,
+                                              ClangASTContext::TemplateParameterInfos &template_param_infos)
+{
+
+    if (parent_die == NULL)
+        return false;
+    
+    Args template_parameter_names;
+    for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild(); 
+         die != NULL; 
+         die = die->GetSibling())
+    {
+        const dw_tag_t tag = die->Tag();
+        
+        switch (tag)
+        {
+            case DW_TAG_template_type_parameter:
+            case DW_TAG_template_value_parameter:
+                ParseTemplateDIE (dwarf_cu, die, template_param_infos);
+            break;
+                
+        default:
+            break;
+        }
+    }
+    if (template_param_infos.args.empty())
+        return false;
+    return template_param_infos.args.size() == template_param_infos.names.size();
+}
+
+clang::ClassTemplateDecl *
+SymbolFileDWARF::ParseClassTemplateDecl (clang::DeclContext *decl_ctx,
+                                         lldb::AccessType access_type,
+                                         const char *parent_name,
+                                         int tag_decl_kind,
+                                         const ClangASTContext::TemplateParameterInfos &template_param_infos)
+{
+    if (template_param_infos.IsValid())
+    {
+        std::string template_basename(parent_name);
+        template_basename.erase (template_basename.find('<'));
+        ClangASTContext &ast = GetClangASTContext();
+
+        return ast.CreateClassTemplateDecl (decl_ctx,
+                                            access_type,
+                                            template_basename.c_str(), 
+                                            tag_decl_kind, 
+                                            template_param_infos);
+    }
+    return NULL;
+}
+
+class SymbolFileDWARF::DelayedAddObjCClassProperty
+{
+public:
+    DelayedAddObjCClassProperty
+    (
+        clang::ASTContext      *ast,
+        lldb::clang_type_t      class_opaque_type, 
+        const char             *property_name,
+        lldb::clang_type_t      property_opaque_type,  // The property type is only required if you don't have an ivar decl
+        clang::ObjCIvarDecl    *ivar_decl,   
+        const char             *property_setter_name,
+        const char             *property_getter_name,
+        uint32_t                property_attributes,
+        const ClangASTMetadata       *metadata
+    ) :
+        m_ast                   (ast),
+        m_class_opaque_type     (class_opaque_type),
+        m_property_name         (property_name),
+        m_property_opaque_type  (property_opaque_type),
+        m_ivar_decl             (ivar_decl),
+        m_property_setter_name  (property_setter_name),
+        m_property_getter_name  (property_getter_name),
+        m_property_attributes   (property_attributes)
+    {
+        if (metadata != NULL)
+        {
+            m_metadata_ap.reset(new ClangASTMetadata());
+            *(m_metadata_ap.get()) = *metadata;
+        }
+    }
+    
+    DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs)
+    {
+        m_ast                  = rhs.m_ast;
+        m_class_opaque_type    = rhs.m_class_opaque_type;
+        m_property_name        = rhs.m_property_name;
+        m_property_opaque_type = rhs.m_property_opaque_type;
+        m_ivar_decl            = rhs.m_ivar_decl;
+        m_property_setter_name = rhs.m_property_setter_name;
+        m_property_getter_name = rhs.m_property_getter_name;
+        m_property_attributes  = rhs.m_property_attributes;
+        
+        if (rhs.m_metadata_ap.get())
+        {
+            m_metadata_ap.reset (new ClangASTMetadata());
+            *(m_metadata_ap.get()) = *(rhs.m_metadata_ap.get());
+        }
+        
+    }
+    
+    bool Finalize() const
+    {
+        return ClangASTContext::AddObjCClassProperty(m_ast,
+                                                     m_class_opaque_type,
+                                                     m_property_name,
+                                                     m_property_opaque_type,
+                                                     m_ivar_decl,
+                                                     m_property_setter_name,
+                                                     m_property_getter_name,
+                                                     m_property_attributes,
+                                                     m_metadata_ap.get());
+    }
+private:
+    clang::ASTContext      *m_ast;
+    lldb::clang_type_t      m_class_opaque_type;
+    const char             *m_property_name;
+    lldb::clang_type_t      m_property_opaque_type;
+    clang::ObjCIvarDecl    *m_ivar_decl;
+    const char             *m_property_setter_name;
+    const char             *m_property_getter_name;
+    uint32_t                m_property_attributes;
+    std::auto_ptr<ClangASTMetadata>        m_metadata_ap;
+};
+
+size_t
+SymbolFileDWARF::ParseChildMembers
+(
+    const SymbolContext& sc,
+    DWARFCompileUnit* dwarf_cu,
+    const DWARFDebugInfoEntry *parent_die,
+    clang_type_t class_clang_type,
+    const LanguageType class_language,
+    std::vector<clang::CXXBaseSpecifier *>& base_classes,
+    std::vector<int>& member_accessibilities,
+    DWARFDIECollection& member_function_dies,
+    DelayedPropertyList& delayed_properties,
+    AccessType& default_accessibility,
+    bool &is_a_class,
+    LayoutInfo &layout_info
+)
+{
+    if (parent_die == NULL)
+        return 0;
+
+    size_t count = 0;
+    const DWARFDebugInfoEntry *die;
+    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
+    uint32_t member_idx = 0;
+
+    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
+    {
+        dw_tag_t tag = die->Tag();
+
+        switch (tag)
+        {
+        case DW_TAG_member:
+        case DW_TAG_APPLE_property:
+            {
+                DWARFDebugInfoEntry::Attributes attributes;
+                const size_t num_attributes = die->GetAttributes (this, 
+                                                                  dwarf_cu, 
+                                                                  fixed_form_sizes, 
+                                                                  attributes);
+                if (num_attributes > 0)
+                {
+                    Declaration decl;
+                    //DWARFExpression location;
+                    const char *name = NULL;
+                    const char *prop_name = NULL;
+                    const char *prop_getter_name = NULL;
+                    const char *prop_setter_name = NULL;
+                    uint32_t        prop_attributes = 0;
+                    
+                    
+                    bool is_artificial = false;
+                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
+                    AccessType accessibility = eAccessNone;
+                    uint32_t member_byte_offset = UINT32_MAX;
+                    size_t byte_size = 0;
+                    size_t bit_offset = 0;
+                    size_t bit_size = 0;
+                    uint32_t i;
+                    for (i=0; i<num_attributes && !is_artificial; ++i)
+                    {
+                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
+                        DWARFFormValue form_value;
+                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                        {
+                            switch (attr)
+                            {
+                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
+                            case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
+                            case DW_AT_bit_offset:  bit_offset = form_value.Unsigned(); break;
+                            case DW_AT_bit_size:    bit_size = form_value.Unsigned(); break;
+                            case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
+                            case DW_AT_data_member_location:
+                                if (form_value.BlockData())
+                                {
+                                    Value initialValue(0);
+                                    Value memberOffset(0);
+                                    const DataExtractor& debug_info_data = get_debug_info_data();
+                                    uint32_t block_length = form_value.Unsigned();
+                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
+                                    if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
+                                                                  NULL, // clang::ASTContext *
+                                                                  NULL, // ClangExpressionVariableList *
+                                                                  NULL, // ClangExpressionDeclMap *
+                                                                  NULL, // RegisterContext *
+                                                                  debug_info_data, 
+                                                                  block_offset, 
+                                                                  block_length, 
+                                                                  eRegisterKindDWARF, 
+                                                                  &initialValue, 
+                                                                  memberOffset, 
+                                                                  NULL))
+                                    {
+                                        member_byte_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
+                                    }
+                                }
+                                break;
+
+                            case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
+                            case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;                            
+                            case DW_AT_APPLE_property_name:      prop_name = form_value.AsCString(&get_debug_str_data()); break;
+                            case DW_AT_APPLE_property_getter:    prop_getter_name = form_value.AsCString(&get_debug_str_data()); break;
+                            case DW_AT_APPLE_property_setter:    prop_setter_name = form_value.AsCString(&get_debug_str_data()); break;
+                            case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break;
+
+                            default:
+                            case DW_AT_declaration:
+                            case DW_AT_description:
+                            case DW_AT_mutable:
+                            case DW_AT_visibility:
+                            case DW_AT_sibling:
+                                break;
+                            }
+                        }
+                    }
+                                        
+                    if (prop_name)
+                    {
+                        ConstString fixed_getter;
+                        ConstString fixed_setter;
+
+                        // Check if the property getter/setter were provided as full
+                        // names.  We want basenames, so we extract them.
+                        
+                        if (prop_getter_name && prop_getter_name[0] == '-')
+                        {
+                            ObjCLanguageRuntime::ParseMethodName (prop_getter_name,
+                                                                  NULL,
+                                                                  &fixed_getter,
+                                                                  NULL,
+                                                                  NULL);
+                            prop_getter_name = fixed_getter.GetCString();
+                        }
+                        
+                        if (prop_setter_name && prop_setter_name[0] == '-')
+                        {
+                            ObjCLanguageRuntime::ParseMethodName (prop_setter_name,
+                                                                  NULL,
+                                                                  &fixed_setter,
+                                                                  NULL,
+                                                                  NULL);
+                            prop_setter_name = fixed_setter.GetCString();
+                        }
+                        
+                        // If the names haven't been provided, they need to be
+                        // filled in.
+                        
+                        if (!prop_getter_name)
+                        {
+                            prop_getter_name = prop_name;
+                        }
+                        if (!prop_setter_name && prop_name[0] && !(prop_attributes & DW_APPLE_PROPERTY_readonly))
+                        {
+                            StreamString ss;
+                            
+                            ss.Printf("set%c%s:",
+                                      toupper(prop_name[0]),
+                                      &prop_name[1]);
+                            
+                            fixed_setter.SetCString(ss.GetData());
+                            prop_setter_name = fixed_setter.GetCString();
+                        }
+                    }
+                    
+                    // Clang has a DWARF generation bug where sometimes it
+                    // represents fields that are references with bad byte size
+                    // and bit size/offset information such as:
+                    //
+                    //  DW_AT_byte_size( 0x00 )
+                    //  DW_AT_bit_size( 0x40 )
+                    //  DW_AT_bit_offset( 0xffffffffffffffc0 )
+                    //
+                    // So check the bit offset to make sure it is sane, and if 
+                    // the values are not sane, remove them. If we don't do this
+                    // then we will end up with a crash if we try to use this 
+                    // type in an expression when clang becomes unhappy with its
+                    // recycled debug info.
+                    
+                    if (bit_offset > 128)
+                    {
+                        bit_size = 0;
+                        bit_offset = 0;
+                    }
+
+                    // FIXME: Make Clang ignore Objective-C accessibility for expressions
+                    if (class_language == eLanguageTypeObjC ||
+                        class_language == eLanguageTypeObjC_plus_plus)
+                        accessibility = eAccessNone; 
+                    
+                    if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
+                    {
+                        // Not all compilers will mark the vtable pointer
+                        // member as artificial (llvm-gcc). We can't have
+                        // the virtual members in our classes otherwise it
+                        // throws off all child offsets since we end up
+                        // having and extra pointer sized member in our 
+                        // class layouts.
+                        is_artificial = true;
+                    }
+
+                    if (is_artificial == false)
+                    {
+                        Type *member_type = ResolveTypeUID(encoding_uid);
+                        clang::FieldDecl *field_decl = NULL;
+                        if (tag == DW_TAG_member)
+                        {
+                            if (member_type)
+                            {
+                                if (accessibility == eAccessNone)
+                                    accessibility = default_accessibility;
+                                member_accessibilities.push_back(accessibility);
+
+                                field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type, 
+                                                                                        name, 
+                                                                                        member_type->GetClangLayoutType(), 
+                                                                                        accessibility, 
+                                                                                        bit_size);
+                                
+                                GetClangASTContext().SetMetadataAsUserID ((uintptr_t)field_decl, MakeUserID(die->GetOffset()));
+                            }
+                            else
+                            {
+                                if (name)
+                                    GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member '%s' refers to type 0x%8.8llx which was unable to be parsed",
+                                                                               MakeUserID(die->GetOffset()),
+                                                                               name,
+                                                                               encoding_uid);
+                                else
+                                    GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member refers to type 0x%8.8llx which was unable to be parsed",
+                                                                               MakeUserID(die->GetOffset()),
+                                                                               encoding_uid);
+                            }
+
+                            if (member_byte_offset != UINT32_MAX || bit_size != 0)
+                            {
+                                /////////////////////////////////////////////////////////////
+                                // How to locate a field given the DWARF debug information
+                                //
+                                // AT_byte_size indicates the size of the word in which the
+                                // bit offset must be interpreted.
+                                //
+                                // AT_data_member_location indicates the byte offset of the
+                                // word from the base address of the structure.
+                                //
+                                // AT_bit_offset indicates how many bits into the word
+                                // (according to the host endianness) the low-order bit of
+                                // the field starts.  AT_bit_offset can be negative.
+                                //
+                                // AT_bit_size indicates the size of the field in bits.
+                                /////////////////////////////////////////////////////////////
+                                                        
+                                ByteOrder object_endian = GetObjectFile()->GetModule()->GetArchitecture().GetDefaultEndian();
+
+                                uint64_t total_bit_offset = 0;
+                                
+                                total_bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
+                                
+                                if (object_endian == eByteOrderLittle)
+                                {  
+                                    total_bit_offset += byte_size * 8;
+                                    total_bit_offset -= (bit_offset + bit_size);
+                                }
+                                else
+                                {
+                                    total_bit_offset += bit_offset;
+                                }
+                                                            
+                                layout_info.field_offsets.insert(std::make_pair(field_decl, total_bit_offset));
+                            }
+                        }
+                        
+                        if (prop_name != NULL)
+                        {
+                            clang::ObjCIvarDecl *ivar_decl = NULL;
+                            
+                            if (field_decl)
+                            {
+                                ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
+                                assert (ivar_decl != NULL);
+                            }
+                            
+                            ClangASTMetadata metadata;
+                            metadata.SetUserID (MakeUserID(die->GetOffset()));
+                            delayed_properties.push_back(DelayedAddObjCClassProperty(GetClangASTContext().getASTContext(),
+                                                                                     class_clang_type,
+                                                                                     prop_name,
+                                                                                     member_type->GetClangLayoutType(),
+                                                                                     ivar_decl,
+                                                                                     prop_setter_name,
+                                                                                     prop_getter_name,
+                                                                                     prop_attributes,
+                                                                                     &metadata));
+                            
+                            if (ivar_decl)
+                                GetClangASTContext().SetMetadataAsUserID ((uintptr_t)ivar_decl, MakeUserID(die->GetOffset()));
+                        }
+                    }
+                }
+                ++member_idx;
+            }
+            break;
+
+        case DW_TAG_subprogram:
+            // Let the type parsing code handle this one for us. 
+            member_function_dies.Append (die);
+            break;
+
+        case DW_TAG_inheritance:
+            {
+                is_a_class = true;
+                if (default_accessibility == eAccessNone)
+                    default_accessibility = eAccessPrivate;
+                // TODO: implement DW_TAG_inheritance type parsing
+                DWARFDebugInfoEntry::Attributes attributes;
+                const size_t num_attributes = die->GetAttributes (this, 
+                                                                  dwarf_cu, 
+                                                                  fixed_form_sizes, 
+                                                                  attributes);
+                if (num_attributes > 0)
+                {
+                    Declaration decl;
+                    DWARFExpression location;
+                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
+                    AccessType accessibility = default_accessibility;
+                    bool is_virtual = false;
+                    bool is_base_of_class = true;
+                    //off_t member_offset = 0;
+                    uint32_t i;
+                    for (i=0; i<num_attributes; ++i)
+                    {
+                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
+                        DWARFFormValue form_value;
+                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                        {
+                            switch (attr)
+                            {
+                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                            case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
+//                            case DW_AT_data_member_location:
+//                                if (form_value.BlockData())
+//                                {
+//                                    Value initialValue(0);
+//                                    Value memberOffset(0);
+//                                    const DataExtractor& debug_info_data = get_debug_info_data();
+//                                    uint32_t block_length = form_value.Unsigned();
+//                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
+//                                    if (DWARFExpression::Evaluate (NULL, 
+//                                                                   NULL, 
+//                                                                   NULL, 
+//                                                                   NULL, 
+//                                                                   NULL,
+//                                                                   debug_info_data, 
+//                                                                   block_offset, 
+//                                                                   block_length, 
+//                                                                   eRegisterKindDWARF, 
+//                                                                   &initialValue, 
+//                                                                   memberOffset, 
+//                                                                   NULL))
+//                                    {
+//                                        member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
+//                                    }
+//                                }
+//                                break;
+
+                            case DW_AT_accessibility:
+                                accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
+                                break;
+
+                            case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
+                            default:
+                            case DW_AT_sibling:
+                                break;
+                            }
+                        }
+                    }
+
+                    Type *base_class_type = ResolveTypeUID(encoding_uid);
+                    assert(base_class_type);
+                    
+                    clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
+                    assert (base_class_clang_type);
+                    if (class_language == eLanguageTypeObjC)
+                    {
+                        GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
+                    }
+                    else
+                    {
+                        base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type, 
+                                                                                               accessibility, 
+                                                                                               is_virtual, 
+                                                                                               is_base_of_class));
+                    }
+                }
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
+    
+    return count;
+}
+
+
+clang::DeclContext*
+SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
+{
+    DWARFDebugInfo* debug_info = DebugInfo();
+    if (debug_info && UserIDMatches(type_uid))
+    {
+        DWARFCompileUnitSP cu_sp;
+        const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
+        if (die)
+            return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
+    }
+    return NULL;
+}
+
+clang::DeclContext*
+SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
+{
+    if (UserIDMatches(type_uid))
+        return GetClangDeclContextForDIEOffset (sc, type_uid);
+    return NULL;
+}
+
+Type*
+SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
+{
+    if (UserIDMatches(type_uid))
+    {
+        DWARFDebugInfo* debug_info = DebugInfo();
+        if (debug_info)
+        {
+            DWARFCompileUnitSP cu_sp;
+            const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
+            const bool assert_not_being_parsed = true;
+            return ResolveTypeUID (cu_sp.get(), type_die, assert_not_being_parsed);
+        }
+    }
+    return NULL;
+}
+
+Type*
+SymbolFileDWARF::ResolveTypeUID (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* die, bool assert_not_being_parsed)
+{    
+    if (die != NULL)
+    {
+        LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+        if (log)
+            GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                      "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'", 
+                                                      die->GetOffset(), 
+                                                      DW_TAG_value_to_name(die->Tag()), 
+                                                      die->GetName(this, cu));
+
+        // We might be coming in in the middle of a type tree (a class
+        // withing a class, an enum within a class), so parse any needed
+        // parent DIEs before we get to this one...
+        const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
+        switch (decl_ctx_die->Tag())
+        {
+            case DW_TAG_structure_type:
+            case DW_TAG_union_type:
+            case DW_TAG_class_type:
+            {
+                // Get the type, which could be a forward declaration
+                if (log)
+                    GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                              "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x", 
+                                                              die->GetOffset(), 
+                                                              DW_TAG_value_to_name(die->Tag()), 
+                                                              die->GetName(this, cu), 
+                                                              decl_ctx_die->GetOffset());
+//
+//                Type *parent_type = ResolveTypeUID (cu, decl_ctx_die, assert_not_being_parsed);
+//                if (child_requires_parent_class_union_or_struct_to_be_completed(die->Tag()))
+//                {
+//                    if (log)
+//                        GetObjectFile()->GetModule()->LogMessage (log.get(), 
+//                                                                  "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent full type for 0x%8.8x since die is a function", 
+//                                                                  die->GetOffset(), 
+//                                                                  DW_TAG_value_to_name(die->Tag()), 
+//                                                                  die->GetName(this, cu), 
+//                                                                  decl_ctx_die->GetOffset());
+//                    // Ask the type to complete itself if it already hasn't since if we
+//                    // want a function (method or static) from a class, the class must 
+//                    // create itself and add it's own methods and class functions.
+//                    if (parent_type)
+//                        parent_type->GetClangFullType();
+//                }
+            }
+            break;
+
+            default:
+                break;
+        }
+        return ResolveType (cu, die);
+    }
+    return NULL;
+}
+
+// This function is used when SymbolFileDWARFDebugMap owns a bunch of
+// SymbolFileDWARF objects to detect if this DWARF file is the one that
+// can resolve a clang_type.
+bool
+SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
+{
+    clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
+    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
+    return die != NULL;
+}
+
+
+lldb::clang_type_t
+SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
+{
+    // We have a struct/union/class/enum that needs to be fully resolved.
+    clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
+    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
+    if (die == NULL)
+    {
+        // We have already resolved this type...
+        return clang_type;
+    }
+    // Once we start resolving this type, remove it from the forward declaration
+    // map in case anyone child members or other types require this type to get resolved.
+    // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
+    // are done.
+    m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
+    
+
+    // Disable external storage for this type so we don't get anymore 
+    // clang::ExternalASTSource queries for this type.
+    ClangASTContext::SetHasExternalStorage (clang_type, false);
+
+    DWARFDebugInfo* debug_info = DebugInfo();
+
+    DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
+    Type *type = m_die_to_type.lookup (die);
+
+    const dw_tag_t tag = die->Tag();
+
+    LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
+    if (log)
+    {
+        GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log.get(),
+                                                                  "0x%8.8llx: %s '%s' resolving forward declaration...",
+                                                                  MakeUserID(die->GetOffset()),
+                                                                  DW_TAG_value_to_name(tag),
+                                                                  type->GetName().AsCString());
+    
+    }
+    assert (clang_type);
+    DWARFDebugInfoEntry::Attributes attributes;
+
+    ClangASTContext &ast = GetClangASTContext();
+
+    switch (tag)
+    {
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_class_type:
+        {
+            LayoutInfo layout_info;
+            
+            {
+                if (die->HasChildren())
+                {
+                    
+                    LanguageType class_language = eLanguageTypeUnknown;
+                    bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
+                    if (is_objc_class)
+                    {
+                        class_language = eLanguageTypeObjC;
+                        // For objective C we don't start the definition when
+                        // the class is created.
+                        ast.StartTagDeclarationDefinition (clang_type);
+                    }
+                    
+                    int tag_decl_kind = -1;
+                    AccessType default_accessibility = eAccessNone;
+                    if (tag == DW_TAG_structure_type)
+                    {
+                        tag_decl_kind = clang::TTK_Struct;
+                        default_accessibility = eAccessPublic;
+                    }
+                    else if (tag == DW_TAG_union_type)
+                    {
+                        tag_decl_kind = clang::TTK_Union;
+                        default_accessibility = eAccessPublic;
+                    }
+                    else if (tag == DW_TAG_class_type)
+                    {
+                        tag_decl_kind = clang::TTK_Class;
+                        default_accessibility = eAccessPrivate;
+                    }
+                    
+                    SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
+                    std::vector<clang::CXXBaseSpecifier *> base_classes;
+                    std::vector<int> member_accessibilities;
+                    bool is_a_class = false;
+                    // Parse members and base classes first
+                    DWARFDIECollection member_function_dies;
+                                        
+                    DelayedPropertyList delayed_properties;
+                    
+                    ParseChildMembers (sc, 
+                                       dwarf_cu,
+                                       die, 
+                                       clang_type,
+                                       class_language,
+                                       base_classes, 
+                                       member_accessibilities,
+                                       member_function_dies,
+                                       delayed_properties,
+                                       default_accessibility, 
+                                       is_a_class,
+                                       layout_info);
+                    
+                    // Now parse any methods if there were any...
+                    size_t num_functions = member_function_dies.Size();                
+                    if (num_functions > 0)
+                    {
+                        for (size_t i=0; i<num_functions; ++i)
+                        {
+                            ResolveType(dwarf_cu, member_function_dies.GetDIEPtrAtIndex(i));
+                        }
+                    }
+                    
+                    if (class_language == eLanguageTypeObjC)
+                    {
+                        std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(ast.getASTContext(), clang_type));
+                        if (!class_str.empty())
+                        {
+                            
+                            DIEArray method_die_offsets;
+                            if (m_using_apple_tables)
+                            {
+                                if (m_apple_objc_ap.get())
+                                    m_apple_objc_ap->FindByName(class_str.c_str(), method_die_offsets);
+                            }
+                            else
+                            {
+                                if (!m_indexed)
+                                    Index ();
+                                
+                                ConstString class_name (class_str.c_str());
+                                m_objc_class_selectors_index.Find (class_name, method_die_offsets);
+                            }
+                            
+                            if (!method_die_offsets.empty())
+                            {
+                                DWARFDebugInfo* debug_info = DebugInfo();
+                                
+                                DWARFCompileUnit* method_cu = NULL;
+                                const size_t num_matches = method_die_offsets.size();
+                                for (size_t i=0; i<num_matches; ++i)
+                                {
+                                    const dw_offset_t die_offset = method_die_offsets[i];
+                                    DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);
+                                    
+                                    if (method_die)
+                                        ResolveType (method_cu, method_die);
+                                    else
+                                    {
+                                        if (m_using_apple_tables)
+                                        {
+                                            GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_objc accelerator table had bad die 0x%8.8x for '%s')\n",
+                                                                                                       die_offset, class_str.c_str());
+                                        }
+                                    }            
+                                }
+                            }
+                            
+                            for (DelayedPropertyList::const_iterator pi = delayed_properties.begin(), pe = delayed_properties.end();
+                                 pi != pe;
+                                 ++pi)
+                                pi->Finalize();
+                        }
+                    }
+                    
+                    // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
+                    // need to tell the clang type it is actually a class.
+                    if (class_language != eLanguageTypeObjC)
+                    {
+                        if (is_a_class && tag_decl_kind != clang::TTK_Class)
+                            ast.SetTagTypeKind (clang_type, clang::TTK_Class);
+                    }
+                    
+                    // Since DW_TAG_structure_type gets used for both classes
+                    // and structures, we may need to set any DW_TAG_member
+                    // fields to have a "private" access if none was specified.
+                    // When we parsed the child members we tracked that actual
+                    // accessibility value for each DW_TAG_member in the
+                    // "member_accessibilities" array. If the value for the
+                    // member is zero, then it was set to the "default_accessibility"
+                    // which for structs was "public". Below we correct this
+                    // by setting any fields to "private" that weren't correctly
+                    // set.
+                    if (is_a_class && !member_accessibilities.empty())
+                    {
+                        // This is a class and all members that didn't have
+                        // their access specified are private.
+                        ast.SetDefaultAccessForRecordFields (clang_type, 
+                                                             eAccessPrivate, 
+                                                             &member_accessibilities.front(), 
+                                                             member_accessibilities.size());
+                    }
+                    
+                    if (!base_classes.empty())
+                    {
+                        ast.SetBaseClassesForClassType (clang_type, 
+                                                        &base_classes.front(), 
+                                                        base_classes.size());
+                        
+                        // Clang will copy each CXXBaseSpecifier in "base_classes"
+                        // so we have to free them all.
+                        ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), 
+                                                                    base_classes.size());
+                    }
+                }
+            }
+            
+            ast.BuildIndirectFields (clang_type);
+            
+            ast.CompleteTagDeclarationDefinition (clang_type);
+            
+            if (!layout_info.field_offsets.empty())
+            {
+                if (type)
+                    layout_info.bit_size = type->GetByteSize() * 8;
+                if (layout_info.bit_size == 0)
+                    layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, 0) * 8;
+                clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+                const clang::RecordType *record_type = clang::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
+                if (record_type)
+                {
+                    const clang::RecordDecl *record_decl = record_type->getDecl();
+                    
+                    if (log)
+                    {
+                        GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                                  "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %llu, alignment = %llu, field_offsets[%u], base_offsets[0], vbase_offsets[0])",
+                                                                  clang_type,
+                                                                  record_decl,
+                                                                  layout_info.bit_size,
+                                                                  layout_info.alignment,
+                                                                  (uint32_t)layout_info.field_offsets.size());
+                        
+                        llvm::DenseMap <const clang::FieldDecl *, uint64_t>::const_iterator pos, end = layout_info.field_offsets.end();
+                        for (pos = layout_info.field_offsets.begin(); pos != end; ++pos)
+                        {
+                            GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                                      "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field = { bit_offset=%u, name='%s' }",
+                                                                      clang_type,
+                                                                      (uint32_t)pos->second,
+                                                                      pos->first->getNameAsString().c_str());
+                        }
+                    }
+                    m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
+                }
+            }
+        }
+
+        return clang_type;
+
+    case DW_TAG_enumeration_type:
+        ast.StartTagDeclarationDefinition (clang_type);
+        if (die->HasChildren())
+        {
+            SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
+            ParseChildEnumerators(sc, clang_type, type->GetByteSize(), dwarf_cu, die);
+        }
+        ast.CompleteTagDeclarationDefinition (clang_type);
+        return clang_type;
+
+    default:
+        assert(false && "not a forward clang type decl!");
+        break;
+    }
+    return NULL;
+}
+
+Type*
+SymbolFileDWARF::ResolveType (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
+{
+    if (type_die != NULL)
+    {
+        Type *type = m_die_to_type.lookup (type_die);
+
+        if (type == NULL)
+            type = GetTypeForDIE (dwarf_cu, type_die).get();
+
+        if (assert_not_being_parsed)
+        { 
+            if (type != DIE_IS_BEING_PARSED)
+                return type;
+            
+            GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
+                                                       type_die->GetOffset(), 
+                                                       DW_TAG_value_to_name(type_die->Tag()), 
+                                                       type_die->GetName(this, dwarf_cu));
+
+        }
+        else
+            return type;
+    }
+    return NULL;
+}
+
+CompileUnit*
+SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
+{
+    // Check if the symbol vendor already knows about this compile unit?
+    if (dwarf_cu->GetUserData() == NULL)
+    {
+        // The symbol vendor doesn't know about this compile unit, we
+        // need to parse and add it to the symbol vendor object.
+        return ParseCompileUnit(dwarf_cu, cu_idx).get();
+    }
+    return (CompileUnit*)dwarf_cu->GetUserData();
+}
+
+bool
+SymbolFileDWARF::GetFunction (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
+{
+    sc.Clear();
+    // Check if the symbol vendor already knows about this compile unit?
+    sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
+
+    sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(func_die->GetOffset())).get();
+    if (sc.function == NULL)
+        sc.function = ParseCompileUnitFunction(sc, dwarf_cu, func_die);
+        
+    if (sc.function)
+    {        
+        sc.module_sp = sc.function->CalculateSymbolContextModule();
+        return true;
+    }
+    
+    return false;
+}
+
+uint32_t
+SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
+{
+    Timer scoped_timer(__PRETTY_FUNCTION__,
+                       "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
+                       so_addr.GetSection().get(),
+                       so_addr.GetOffset(),
+                       resolve_scope);
+    uint32_t resolved = 0;
+    if (resolve_scope & (   eSymbolContextCompUnit |
+                            eSymbolContextFunction |
+                            eSymbolContextBlock |
+                            eSymbolContextLineEntry))
+    {
+        lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
+
+        DWARFDebugInfo* debug_info = DebugInfo();
+        if (debug_info)
+        {
+            const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
+            if (cu_offset != DW_INVALID_OFFSET)
+            {
+                uint32_t cu_idx = DW_INVALID_INDEX;
+                DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
+                if (dwarf_cu)
+                {
+                    sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
+                    if (sc.comp_unit)
+                    {
+                        resolved |= eSymbolContextCompUnit;
+
+                        if (resolve_scope & eSymbolContextLineEntry)
+                        {
+                            LineTable *line_table = sc.comp_unit->GetLineTable();
+                            if (line_table != NULL)
+                            {
+                                if (so_addr.IsLinkedAddress())
+                                {
+                                    Address linked_addr (so_addr);
+                                    linked_addr.ResolveLinkedAddress();
+                                    if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
+                                    {
+                                        resolved |= eSymbolContextLineEntry;
+                                    }
+                                }
+                                else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
+                                {
+                                    resolved |= eSymbolContextLineEntry;
+                                }
+                            }
+                        }
+
+                        if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
+                        {
+                            DWARFDebugInfoEntry *function_die = NULL;
+                            DWARFDebugInfoEntry *block_die = NULL;
+                            if (resolve_scope & eSymbolContextBlock)
+                            {
+                                dwarf_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
+                            }
+                            else
+                            {
+                                dwarf_cu->LookupAddress(file_vm_addr, &function_die, NULL);
+                            }
+
+                            if (function_die != NULL)
+                            {
+                                sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
+                                if (sc.function == NULL)
+                                    sc.function = ParseCompileUnitFunction(sc, dwarf_cu, function_die);
+                            }
+                            else
+                            {
+                                // We might have had a compile unit that had discontiguous
+                                // address ranges where the gaps are symbols that don't have
+                                // any debug info. Discontiguous compile unit address ranges
+                                // should only happen when there aren't other functions from
+                                // other compile units in these gaps. This helps keep the size
+                                // of the aranges down.
+                                sc.comp_unit = NULL;
+                                resolved &= ~eSymbolContextCompUnit;
+                            }
+
+                            if (sc.function != NULL)
+                            {
+                                resolved |= eSymbolContextFunction;
+
+                                if (resolve_scope & eSymbolContextBlock)
+                                {
+                                    Block& block = sc.function->GetBlock (true);
+
+                                    if (block_die != NULL)
+                                        sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
+                                    else
+                                        sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
+                                    if (sc.block)
+                                        resolved |= eSymbolContextBlock;
+                                }
+                            }
+                        }
+                    }
+                    else
+                    {
+                        GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.",
+                                                                     cu_offset,
+                                                                     cu_idx);
+                    }
+                }
+            }
+        }
+    }
+    return resolved;
+}
+
+
+
+uint32_t
+SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
+{
+    const uint32_t prev_size = sc_list.GetSize();
+    if (resolve_scope & eSymbolContextCompUnit)
+    {
+        DWARFDebugInfo* debug_info = DebugInfo();
+        if (debug_info)
+        {
+            uint32_t cu_idx;
+            DWARFCompileUnit* dwarf_cu = NULL;
+
+            for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
+            {
+                CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
+                const bool full_match = file_spec.GetDirectory();
+                bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
+                if (check_inlines || file_spec_matches_cu_file_spec)
+                {
+                    SymbolContext sc (m_obj_file->GetModule());
+                    sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
+                    if (sc.comp_unit)
+                    {
+                        uint32_t file_idx = UINT32_MAX;
+
+                        // If we are looking for inline functions only and we don't
+                        // find it in the support files, we are done.
+                        if (check_inlines)
+                        {
+                            file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
+                            if (file_idx == UINT32_MAX)
+                                continue;
+                        }
+
+                        if (line != 0)
+                        {
+                            LineTable *line_table = sc.comp_unit->GetLineTable();
+
+                            if (line_table != NULL && line != 0)
+                            {
+                                // We will have already looked up the file index if
+                                // we are searching for inline entries.
+                                if (!check_inlines)
+                                    file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
+
+                                if (file_idx != UINT32_MAX)
+                                {
+                                    uint32_t found_line;
+                                    uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
+                                    found_line = sc.line_entry.line;
+
+                                    while (line_idx != UINT32_MAX)
+                                    {
+                                        sc.function = NULL;
+                                        sc.block = NULL;
+                                        if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
+                                        {
+                                            const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
+                                            if (file_vm_addr != LLDB_INVALID_ADDRESS)
+                                            {
+                                                DWARFDebugInfoEntry *function_die = NULL;
+                                                DWARFDebugInfoEntry *block_die = NULL;
+                                                dwarf_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
+
+                                                if (function_die != NULL)
+                                                {
+                                                    sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
+                                                    if (sc.function == NULL)
+                                                        sc.function = ParseCompileUnitFunction(sc, dwarf_cu, function_die);
+                                                }
+
+                                                if (sc.function != NULL)
+                                                {
+                                                    Block& block = sc.function->GetBlock (true);
+
+                                                    if (block_die != NULL)
+                                                        sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
+                                                    else
+                                                        sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
+                                                }
+                                            }
+                                        }
+
+                                        sc_list.Append(sc);
+                                        line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
+                                    }
+                                }
+                            }
+                            else if (file_spec_matches_cu_file_spec && !check_inlines)
+                            {
+                                // only append the context if we aren't looking for inline call sites
+                                // by file and line and if the file spec matches that of the compile unit
+                                sc_list.Append(sc);
+                            }
+                        }
+                        else if (file_spec_matches_cu_file_spec && !check_inlines)
+                        {
+                            // only append the context if we aren't looking for inline call sites
+                            // by file and line and if the file spec matches that of the compile unit
+                            sc_list.Append(sc);
+                        }
+
+                        if (!check_inlines)
+                            break;
+                    }
+                }
+            }
+        }
+    }
+    return sc_list.GetSize() - prev_size;
+}
+
+void
+SymbolFileDWARF::Index ()
+{
+    if (m_indexed)
+        return;
+    m_indexed = true;
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "SymbolFileDWARF::Index (%s)",
+                        GetObjectFile()->GetFileSpec().GetFilename().AsCString());
+
+    DWARFDebugInfo* debug_info = DebugInfo();
+    if (debug_info)
+    {
+        uint32_t cu_idx = 0;
+        const uint32_t num_compile_units = GetNumCompileUnits();
+        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+        {
+            DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+
+            bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded (false) > 1;
+
+            dwarf_cu->Index (cu_idx,
+                             m_function_basename_index,
+                             m_function_fullname_index,
+                             m_function_method_index,
+                             m_function_selector_index,
+                             m_objc_class_selectors_index,
+                             m_global_index, 
+                             m_type_index,
+                             m_namespace_index);
+            
+            // Keep memory down by clearing DIEs if this generate function
+            // caused them to be parsed
+            if (clear_dies)
+                dwarf_cu->ClearDIEs (true);
+        }
+        
+        m_function_basename_index.Finalize();
+        m_function_fullname_index.Finalize();
+        m_function_method_index.Finalize();
+        m_function_selector_index.Finalize();
+        m_objc_class_selectors_index.Finalize();
+        m_global_index.Finalize(); 
+        m_type_index.Finalize();
+        m_namespace_index.Finalize();
+
+#if defined (ENABLE_DEBUG_PRINTF)
+        StreamFile s(stdout, false);
+        s.Printf ("DWARF index for '%s/%s':", 
+                  GetObjectFile()->GetFileSpec().GetDirectory().AsCString(), 
+                  GetObjectFile()->GetFileSpec().GetFilename().AsCString());
+        s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
+        s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
+        s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
+        s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
+        s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
+        s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s); 
+        s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
+        s.Printf("\nNamepaces:\n");             m_namespace_index.Dump (&s);
+#endif
+    }
+}
+
+bool
+SymbolFileDWARF::NamespaceDeclMatchesThisSymbolFile (const ClangNamespaceDecl *namespace_decl)
+{
+    if (namespace_decl == NULL)
+    {
+        // Invalid namespace decl which means we aren't matching only things
+        // in this symbol file, so return true to indicate it matches this
+        // symbol file.
+        return true;
+    }
+    
+    clang::ASTContext *namespace_ast = namespace_decl->GetASTContext();
+
+    if (namespace_ast == NULL)
+        return true;    // No AST in the "namespace_decl", return true since it 
+                        // could then match any symbol file, including this one
+
+    if (namespace_ast == GetClangASTContext().getASTContext())
+        return true;    // The ASTs match, return true
+    
+    // The namespace AST was valid, and it does not match...
+    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+    if (log)
+        GetObjectFile()->GetModule()->LogMessage(log.get(), "Valid namespace does not match symbol file");
+    
+    return false;
+}
+
+bool
+SymbolFileDWARF::DIEIsInNamespace (const ClangNamespaceDecl *namespace_decl, 
+                                   DWARFCompileUnit* cu, 
+                                   const DWARFDebugInfoEntry* die)
+{
+    // No namespace specified, so the answesr i
+    if (namespace_decl == NULL)
+        return true;
+    
+    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+    const DWARFDebugInfoEntry *decl_ctx_die = NULL;
+    clang::DeclContext *die_clang_decl_ctx = GetClangDeclContextContainingDIE (cu, die, &decl_ctx_die);
+    if (decl_ctx_die)
+    { 
+        clang::NamespaceDecl *clang_namespace_decl = namespace_decl->GetNamespaceDecl();
+
+        if (clang_namespace_decl)
+        {
+            if (decl_ctx_die->Tag() != DW_TAG_namespace)
+            {
+                if (log)
+                    GetObjectFile()->GetModule()->LogMessage(log.get(), "Found a match, but its parent is not a namespace");
+                return false;
+            }
+                
+            if (clang_namespace_decl == die_clang_decl_ctx)
+                return true;
+            else
+                return false;
+        }
+        else
+        {
+            // We have a namespace_decl that was not NULL but it contained
+            // a NULL "clang::NamespaceDecl", so this means the global namespace
+            // So as long the the contained decl context DIE isn't a namespace
+            // we should be ok.
+            if (decl_ctx_die->Tag() != DW_TAG_namespace)
+                return true;
+        }
+    }
+    
+    if (log)
+        GetObjectFile()->GetModule()->LogMessage(log.get(), "Found a match, but its parent doesn't exist");
+    
+    return false;
+}
+uint32_t
+SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
+{
+    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+
+    if (log)
+    {
+        GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                  "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables)", 
+                                                  name.GetCString(), 
+                                                  namespace_decl,
+                                                  append, 
+                                                  max_matches);
+    }
+    
+    if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
+		return 0;
+    
+    DWARFDebugInfo* info = DebugInfo();
+    if (info == NULL)
+        return 0;
+
+    // If we aren't appending the results to this list, then clear the list
+    if (!append)
+        variables.Clear();
+
+    // Remember how many variables are in the list before we search in case
+    // we are appending the results to a variable list.
+    const uint32_t original_size = variables.GetSize();
+
+    DIEArray die_offsets;
+    
+    if (m_using_apple_tables)
+    {
+        if (m_apple_names_ap.get())
+        {
+            const char *name_cstr = name.GetCString();
+            const char *base_name_start;
+            const char *base_name_end = NULL;
+            
+            if (!CPPLanguageRuntime::StripNamespacesFromVariableName(name_cstr, base_name_start, base_name_end))
+                base_name_start = name_cstr;
+                
+            m_apple_names_ap->FindByName (base_name_start, die_offsets);
+        }
+    }
+    else
+    {
+        // Index the DWARF if we haven't already
+        if (!m_indexed)
+            Index ();
+
+        m_global_index.Find (name, die_offsets);
+    }
+    
+    const size_t num_die_matches = die_offsets.size();
+    if (num_die_matches)
+    {
+        SymbolContext sc;
+        sc.module_sp = m_obj_file->GetModule();
+        assert (sc.module_sp);
+        
+        DWARFDebugInfo* debug_info = DebugInfo();
+        DWARFCompileUnit* dwarf_cu = NULL;
+        const DWARFDebugInfoEntry* die = NULL;
+        bool done = false;
+        for (size_t i=0; i<num_die_matches && !done; ++i)
+        {
+            const dw_offset_t die_offset = die_offsets[i];
+            die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+
+            if (die)
+            {
+                switch (die->Tag())
+                {
+                    default:
+                    case DW_TAG_subprogram:
+                    case DW_TAG_inlined_subroutine:
+                    case DW_TAG_try_block:
+                    case DW_TAG_catch_block:
+                        break;
+                        
+                    case DW_TAG_variable:
+                        {
+                            sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
+                    
+                            if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
+                                continue;
+
+                            ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
+
+                            if (variables.GetSize() - original_size >= max_matches)
+                                done = true;
+                        }
+                        break;
+                }
+            }
+            else
+            {
+                if (m_using_apple_tables)
+                {
+                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n",
+                                                                               die_offset, name.GetCString());
+                }
+            }
+        }
+    }
+
+    // Return the number of variable that were appended to the list
+    const uint32_t num_matches = variables.GetSize() - original_size;
+    if (log && num_matches > 0)
+    {
+        GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                  "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables) => %u",
+                                                  name.GetCString(), 
+                                                  namespace_decl,
+                                                  append, 
+                                                  max_matches,
+                                                  num_matches);
+    }
+    return num_matches;
+}
+
+uint32_t
+SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
+{
+    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+    
+    if (log)
+    {
+        GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                  "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)", 
+                                                  regex.GetText(), 
+                                                  append, 
+                                                  max_matches);
+    }
+
+    DWARFDebugInfo* info = DebugInfo();
+    if (info == NULL)
+        return 0;
+
+    // If we aren't appending the results to this list, then clear the list
+    if (!append)
+        variables.Clear();
+
+    // Remember how many variables are in the list before we search in case
+    // we are appending the results to a variable list.
+    const uint32_t original_size = variables.GetSize();
+
+    DIEArray die_offsets;
+    
+    if (m_using_apple_tables)
+    {
+        if (m_apple_names_ap.get())
+        {
+            DWARFMappedHash::DIEInfoArray hash_data_array;
+            if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
+                DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
+        }
+    }
+    else
+    {
+        // Index the DWARF if we haven't already
+        if (!m_indexed)
+            Index ();
+        
+        m_global_index.Find (regex, die_offsets);
+    }
+
+    SymbolContext sc;
+    sc.module_sp = m_obj_file->GetModule();
+    assert (sc.module_sp);
+    
+    DWARFCompileUnit* dwarf_cu = NULL;
+    const DWARFDebugInfoEntry* die = NULL;
+    const size_t num_matches = die_offsets.size();
+    if (num_matches)
+    {
+        DWARFDebugInfo* debug_info = DebugInfo();
+        for (size_t i=0; i<num_matches; ++i)
+        {
+            const dw_offset_t die_offset = die_offsets[i];
+            die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+            
+            if (die)
+            {
+                sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
+
+                ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
+
+                if (variables.GetSize() - original_size >= max_matches)
+                    break;
+            }
+            else
+            {
+                if (m_using_apple_tables)
+                {
+                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n",
+                                                                               die_offset, regex.GetText());
+                }
+            }            
+        }
+    }
+
+    // Return the number of variable that were appended to the list
+    return variables.GetSize() - original_size;
+}
+
+
+bool
+SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset,
+                                  DWARFCompileUnit *&dwarf_cu,
+                                  SymbolContextList& sc_list)
+{
+    const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+    return ResolveFunction (dwarf_cu, die, sc_list);
+}
+    
+
+bool
+SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu,
+                                  const DWARFDebugInfoEntry *die,
+                                  SymbolContextList& sc_list)
+{
+    SymbolContext sc;
+
+    if (die == NULL)
+        return false;
+
+    // If we were passed a die that is not a function, just return false...
+    if (die->Tag() != DW_TAG_subprogram && die->Tag() != DW_TAG_inlined_subroutine)
+        return false;
+    
+    const DWARFDebugInfoEntry* inlined_die = NULL;
+    if (die->Tag() == DW_TAG_inlined_subroutine)
+    {
+        inlined_die = die;
+        
+        while ((die = die->GetParent()) != NULL)
+        {
+            if (die->Tag() == DW_TAG_subprogram)
+                break;
+        }
+    }
+    assert (die->Tag() == DW_TAG_subprogram);
+    if (GetFunction (cu, die, sc))
+    {
+        Address addr;
+        // Parse all blocks if needed
+        if (inlined_die)
+        {
+            sc.block = sc.function->GetBlock (true).FindBlockByID (MakeUserID(inlined_die->GetOffset()));
+            assert (sc.block != NULL);
+            if (sc.block->GetStartAddress (addr) == false)
+                addr.Clear();
+        }
+        else 
+        {
+            sc.block = NULL;
+            addr = sc.function->GetAddressRange().GetBaseAddress();
+        }
+
+        if (addr.IsValid())
+        {
+            sc_list.Append(sc);
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+void
+SymbolFileDWARF::FindFunctions (const ConstString &name, 
+                                const NameToDIE &name_to_die,
+                                SymbolContextList& sc_list)
+{
+    DIEArray die_offsets;
+    if (name_to_die.Find (name, die_offsets))
+    {
+        ParseFunctions (die_offsets, sc_list);
+    }
+}
+
+
+void
+SymbolFileDWARF::FindFunctions (const RegularExpression &regex, 
+                                const NameToDIE &name_to_die,
+                                SymbolContextList& sc_list)
+{
+    DIEArray die_offsets;
+    if (name_to_die.Find (regex, die_offsets))
+    {
+        ParseFunctions (die_offsets, sc_list);
+    }
+}
+
+
+void
+SymbolFileDWARF::FindFunctions (const RegularExpression &regex, 
+                                const DWARFMappedHash::MemoryTable &memory_table,
+                                SymbolContextList& sc_list)
+{
+    DIEArray die_offsets;
+    DWARFMappedHash::DIEInfoArray hash_data_array;
+    if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
+    {
+        DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
+        ParseFunctions (die_offsets, sc_list);
+    }
+}
+
+void
+SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
+                                 SymbolContextList& sc_list)
+{
+    const size_t num_matches = die_offsets.size();
+    if (num_matches)
+    {
+        SymbolContext sc;
+
+        DWARFCompileUnit* dwarf_cu = NULL;
+        for (size_t i=0; i<num_matches; ++i)
+        {
+            const dw_offset_t die_offset = die_offsets[i];
+            ResolveFunction (die_offset, dwarf_cu, sc_list);
+        }
+    }
+}
+
+bool
+SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die,
+                                                const DWARFCompileUnit *dwarf_cu,
+                                                uint32_t name_type_mask, 
+                                                const char *partial_name,
+                                                const char *base_name_start,
+                                                const char *base_name_end)
+{
+    // If we are looking only for methods, throw away all the ones that aren't in C++ classes:
+    if (name_type_mask == eFunctionNameTypeMethod
+        || name_type_mask == eFunctionNameTypeBase)
+    {
+        clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset());
+        if (!containing_decl_ctx)
+            return false;
+        
+        bool is_cxx_method = DeclKindIsCXXClass(containing_decl_ctx->getDeclKind());
+        
+        if (!is_cxx_method && name_type_mask == eFunctionNameTypeMethod)
+            return false;
+        if (is_cxx_method && name_type_mask == eFunctionNameTypeBase)
+            return false;
+    }
+
+    // Now we need to check whether the name we got back for this type matches the extra specifications
+    // that were in the name we're looking up:
+    if (base_name_start != partial_name || *base_name_end != '\0')
+    {
+        // First see if the stuff to the left matches the full name.  To do that let's see if
+        // we can pull out the mips linkage name attribute:
+        
+        Mangled best_name;
+
+        DWARFDebugInfoEntry::Attributes attributes;
+        die->GetAttributes(this, dwarf_cu, NULL, attributes);
+        uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name);
+        if (idx != UINT32_MAX)
+        {
+            DWARFFormValue form_value;
+            if (attributes.ExtractFormValueAtIndex(this, idx, form_value))
+            {
+                const char *name = form_value.AsCString(&get_debug_str_data());
+                best_name.SetValue (ConstString(name), true);
+            } 
+        }
+        if (best_name)
+        {
+            const char *demangled = best_name.GetDemangledName().GetCString();
+            if (demangled)
+            {
+                std::string name_no_parens(partial_name, base_name_end - partial_name);
+                const char *partial_in_demangled = strstr (demangled, name_no_parens.c_str());
+                if (partial_in_demangled == NULL)
+                    return false;
+                else
+                {
+                    // Sort out the case where our name is something like "Process::Destroy" and the match is
+                    // "SBProcess::Destroy" - that shouldn't be a match.  We should really always match on
+                    // namespace boundaries...
+                    
+                    if (partial_name[0] == ':'  && partial_name[1] == ':')
+                    {
+                        // The partial name was already on a namespace boundary so all matches are good.
+                        return true;
+                    }
+                    else if (partial_in_demangled == demangled)
+                    {
+                        // They both start the same, so this is an good match.
+                        return true;
+                    }
+                    else
+                    {
+                        if (partial_in_demangled - demangled == 1)
+                        {
+                            // Only one character difference, can't be a namespace boundary...
+                            return false;
+                        }
+                        else if (*(partial_in_demangled - 1) == ':' && *(partial_in_demangled - 2) == ':')
+                        {
+                            // We are on a namespace boundary, so this is also good.
+                            return true;
+                        }
+                        else
+                            return false;
+                    }
+                }
+            }
+        }
+    }
+    
+    return true;
+}
+
+uint32_t
+SymbolFileDWARF::FindFunctions (const ConstString &name, 
+                                const lldb_private::ClangNamespaceDecl *namespace_decl, 
+                                uint32_t name_type_mask,
+                                bool include_inlines,
+                                bool append, 
+                                SymbolContextList& sc_list)
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "SymbolFileDWARF::FindFunctions (name = '%s')",
+                        name.AsCString());
+
+    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+    
+    if (log)
+    {
+        GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                  "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)", 
+                                                  name.GetCString(), 
+                                                  name_type_mask, 
+                                                  append);
+    }
+
+    // If we aren't appending the results to this list, then clear the list
+    if (!append)
+        sc_list.Clear();
+    
+    if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
+		return 0;
+        
+    // If name is empty then we won't find anything.
+    if (name.IsEmpty())
+        return 0;
+
+    // Remember how many sc_list are in the list before we search in case
+    // we are appending the results to a variable list.
+
+    const uint32_t original_size = sc_list.GetSize();
+
+    const char *name_cstr = name.GetCString();
+    uint32_t effective_name_type_mask = eFunctionNameTypeNone;
+    const char *base_name_start = name_cstr;
+    const char *base_name_end = name_cstr + strlen(name_cstr);
+    
+    if (name_type_mask & eFunctionNameTypeAuto)
+    {
+        if (CPPLanguageRuntime::IsCPPMangledName (name_cstr))
+            effective_name_type_mask = eFunctionNameTypeFull;
+        else if (ObjCLanguageRuntime::IsPossibleObjCMethodName (name_cstr))
+            effective_name_type_mask = eFunctionNameTypeFull;
+        else
+        {
+            if (ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
+                effective_name_type_mask |= eFunctionNameTypeSelector;
+                
+            if (CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
+                effective_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
+        }
+    }
+    else
+    {
+        effective_name_type_mask = name_type_mask;
+        if (effective_name_type_mask & eFunctionNameTypeMethod || name_type_mask & eFunctionNameTypeBase)
+        {
+            // If they've asked for a CPP method or function name and it can't be that, we don't
+            // even need to search for CPP methods or names.
+            if (!CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
+            {
+                effective_name_type_mask &= ~(eFunctionNameTypeMethod | eFunctionNameTypeBase);
+                if (effective_name_type_mask == eFunctionNameTypeNone)
+                    return 0;
+            }
+        }
+        
+        if (effective_name_type_mask & eFunctionNameTypeSelector)
+        {
+            if (!ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
+            {
+                effective_name_type_mask &= ~(eFunctionNameTypeSelector);
+                if (effective_name_type_mask == eFunctionNameTypeNone)
+                    return 0;
+            }
+        }
+    }
+    
+    DWARFDebugInfo* info = DebugInfo();
+    if (info == NULL)
+        return 0;
+
+    DWARFCompileUnit *dwarf_cu = NULL;
+    if (m_using_apple_tables)
+    {
+        if (m_apple_names_ap.get())
+        {
+
+            DIEArray die_offsets;
+
+            uint32_t num_matches = 0;
+                
+            if (effective_name_type_mask & eFunctionNameTypeFull)
+            {
+                // If they asked for the full name, match what they typed.  At some point we may
+                // want to canonicalize this (strip double spaces, etc.  For now, we just add all the
+                // dies that we find by exact match.
+                num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
+                for (uint32_t i = 0; i < num_matches; i++)
+                {
+                    const dw_offset_t die_offset = die_offsets[i];
+                    const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+                    if (die)
+                    {
+                        if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
+                            continue;
+                        
+                        if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
+                            continue;
+                        
+                        ResolveFunction (dwarf_cu, die, sc_list);
+                    }
+                    else
+                    {
+                        GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')", 
+                                                                                   die_offset, name_cstr);
+                    }                                    
+                }
+            }
+            else
+            {                
+                if (effective_name_type_mask & eFunctionNameTypeSelector)
+                {
+                    if (namespace_decl && *namespace_decl)
+                        return 0; // no selectors in namespaces
+                        
+                    num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
+                    // Now make sure these are actually ObjC methods.  In this case we can simply look up the name,
+                    // and if it is an ObjC method name, we're good.
+                    
+                    for (uint32_t i = 0; i < num_matches; i++)
+                    {
+                        const dw_offset_t die_offset = die_offsets[i];
+                        const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+                        if (die)
+                        {
+                            const char *die_name = die->GetName(this, dwarf_cu);
+                            if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name))
+                            {
+                                if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
+                                    continue;
+                                
+                                ResolveFunction (dwarf_cu, die, sc_list);
+                            }
+                        }
+                        else
+                        {
+                            GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
+                                                                       die_offset, name_cstr);
+                        }                                    
+                    }
+                    die_offsets.clear();
+                }
+                
+                if (effective_name_type_mask & eFunctionNameTypeMethod
+                    || effective_name_type_mask & eFunctionNameTypeBase)
+                {
+                    if ((effective_name_type_mask & eFunctionNameTypeMethod) &&
+                        (namespace_decl && *namespace_decl))
+                        return 0; // no methods in namespaces
+                    
+                    // The apple_names table stores just the "base name" of C++ methods in the table.  So we have to 
+                    // extract the base name, look that up, and if there is any other information in the name we were
+                    // passed in we have to post-filter based on that.
+                    
+                    // FIXME: Arrange the logic above so that we don't calculate the base name twice:
+                    std::string base_name(base_name_start, base_name_end - base_name_start);
+                    num_matches = m_apple_names_ap->FindByName (base_name.c_str(), die_offsets);
+                    
+                    for (uint32_t i = 0; i < num_matches; i++)
+                    {
+                        const dw_offset_t die_offset = die_offsets[i];
+                        const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+                        if (die)
+                        {
+                            if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
+                                continue;
+                            
+                            if (!FunctionDieMatchesPartialName(die, 
+                                                               dwarf_cu, 
+                                                               effective_name_type_mask, 
+                                                               name_cstr, 
+                                                               base_name_start, 
+                                                               base_name_end))
+                                continue;
+                            
+                            if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
+                                continue;
+                                
+                            // If we get to here, the die is good, and we should add it:
+                            ResolveFunction (dwarf_cu, die, sc_list);
+                        }
+                        else
+                        {
+                            GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
+                                                                                       die_offset, name_cstr);
+                        }                                    
+                    }
+                    die_offsets.clear();
+                }
+            }
+        }
+    }
+    else
+    {
+
+        // Index the DWARF if we haven't already
+        if (!m_indexed)
+            Index ();
+
+        if (name_type_mask & eFunctionNameTypeFull)
+            FindFunctions (name, m_function_fullname_index, sc_list);
+
+        std::string base_name(base_name_start, base_name_end - base_name_start);
+        ConstString base_name_const(base_name.c_str());
+        DIEArray die_offsets;
+        DWARFCompileUnit *dwarf_cu = NULL;
+        
+        if (effective_name_type_mask & eFunctionNameTypeBase)
+        {
+            uint32_t num_base = m_function_basename_index.Find(base_name_const, die_offsets);
+            for (uint32_t i = 0; i < num_base; i++)
+            {
+                const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
+                if (die)
+                {
+                    if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
+                        continue;
+                    
+                    if (!FunctionDieMatchesPartialName(die, 
+                                                       dwarf_cu, 
+                                                       effective_name_type_mask, 
+                                                       name_cstr, 
+                                                       base_name_start, 
+                                                       base_name_end))
+                        continue;
+                    
+                    if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
+                        continue;
+                    
+                    // If we get to here, the die is good, and we should add it:
+                    ResolveFunction (dwarf_cu, die, sc_list);
+                }
+            }
+            die_offsets.clear();
+        }
+        
+        if (effective_name_type_mask & eFunctionNameTypeMethod)
+        {
+            if (namespace_decl && *namespace_decl)
+                return 0; // no methods in namespaces
+
+            uint32_t num_base = m_function_method_index.Find(base_name_const, die_offsets);
+            {
+                for (uint32_t i = 0; i < num_base; i++)
+                {
+                    const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
+                    if (die)
+                    {
+                        if (!FunctionDieMatchesPartialName(die, 
+                                                           dwarf_cu, 
+                                                           effective_name_type_mask, 
+                                                           name_cstr, 
+                                                           base_name_start, 
+                                                           base_name_end))
+                            continue;
+                        
+                        if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
+                            continue;
+                        
+                        // If we get to here, the die is good, and we should add it:
+                        ResolveFunction (dwarf_cu, die, sc_list);
+                    }
+                }
+            }
+            die_offsets.clear();
+        }
+
+        if ((effective_name_type_mask & eFunctionNameTypeSelector) && (!namespace_decl || !*namespace_decl))
+        {
+            FindFunctions (name, m_function_selector_index, sc_list);
+        }
+        
+    }
+
+    // Return the number of variable that were appended to the list
+    const uint32_t num_matches = sc_list.GetSize() - original_size;
+    
+    if (log && num_matches > 0)
+    {
+        GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                  "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list) => %u",
+                                                  name.GetCString(), 
+                                                  name_type_mask, 
+                                                  append,
+                                                  num_matches);
+    }
+    return num_matches;
+}
+
+uint32_t
+SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__,
+                        "SymbolFileDWARF::FindFunctions (regex = '%s')",
+                        regex.GetText());
+
+    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+    
+    if (log)
+    {
+        GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                  "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)", 
+                                                  regex.GetText(), 
+                                                  append);
+    }
+    
+
+    // If we aren't appending the results to this list, then clear the list
+    if (!append)
+        sc_list.Clear();
+
+    // Remember how many sc_list are in the list before we search in case
+    // we are appending the results to a variable list.
+    uint32_t original_size = sc_list.GetSize();
+
+    if (m_using_apple_tables)
+    {
+        if (m_apple_names_ap.get())
+            FindFunctions (regex, *m_apple_names_ap, sc_list);
+    }
+    else
+    {
+        // Index the DWARF if we haven't already
+        if (!m_indexed)
+            Index ();
+
+        FindFunctions (regex, m_function_basename_index, sc_list);
+
+        FindFunctions (regex, m_function_fullname_index, sc_list);
+    }
+
+    // Return the number of variable that were appended to the list
+    return sc_list.GetSize() - original_size;
+}
+
+uint32_t
+SymbolFileDWARF::FindTypes (const SymbolContext& sc, 
+                            const ConstString &name, 
+                            const lldb_private::ClangNamespaceDecl *namespace_decl, 
+                            bool append, 
+                            uint32_t max_matches, 
+                            TypeList& types)
+{
+    DWARFDebugInfo* info = DebugInfo();
+    if (info == NULL)
+        return 0;
+
+    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+    
+    if (log)
+    {
+        if (namespace_decl)
+        {
+            GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                      "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(%p) \"%s\", append=%u, max_matches=%u, type_list)", 
+                                                      name.GetCString(),
+                                                      namespace_decl->GetNamespaceDecl(),
+                                                      namespace_decl->GetQualifiedName().c_str(),
+                                                      append, 
+                                                      max_matches);
+        }
+        else
+        {
+            GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                      "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(NULL), append=%u, max_matches=%u, type_list)",
+                                                      name.GetCString(), 
+                                                      append, 
+                                                      max_matches);
+        }
+    }
+
+    // If we aren't appending the results to this list, then clear the list
+    if (!append)
+        types.Clear();
+    
+    if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
+		return 0;
+
+    DIEArray die_offsets;
+    
+    if (m_using_apple_tables)
+    {
+        if (m_apple_types_ap.get())
+        {
+            const char *name_cstr = name.GetCString();
+            m_apple_types_ap->FindByName (name_cstr, die_offsets);
+        }
+    }
+    else
+    {
+        if (!m_indexed)
+            Index ();
+        
+        m_type_index.Find (name, die_offsets);
+    }
+    
+    const size_t num_die_matches = die_offsets.size();
+
+    if (num_die_matches)
+    {
+        const uint32_t initial_types_size = types.GetSize();
+        DWARFCompileUnit* dwarf_cu = NULL;
+        const DWARFDebugInfoEntry* die = NULL;
+        DWARFDebugInfo* debug_info = DebugInfo();
+        for (size_t i=0; i<num_die_matches; ++i)
+        {
+            const dw_offset_t die_offset = die_offsets[i];
+            die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+
+            if (die)
+            {
+                if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
+                    continue;
+                
+                Type *matching_type = ResolveType (dwarf_cu, die);
+                if (matching_type)
+                {
+                    // We found a type pointer, now find the shared pointer form our type list
+                    types.InsertUnique (matching_type->shared_from_this());
+                    if (types.GetSize() >= max_matches)
+                        break;
+                }
+            }
+            else
+            {
+                if (m_using_apple_tables)
+                {
+                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
+                                                                               die_offset, name.GetCString());
+                }
+            }            
+
+        }
+        const uint32_t num_matches = types.GetSize() - initial_types_size;
+        if (log && num_matches)
+        {
+            if (namespace_decl)
+            {
+                GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                          "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(%p) \"%s\", append=%u, max_matches=%u, type_list) => %u", 
+                                                          name.GetCString(),
+                                                          namespace_decl->GetNamespaceDecl(),
+                                                          namespace_decl->GetQualifiedName().c_str(),
+                                                          append, 
+                                                          max_matches,
+                                                          num_matches);
+            }
+            else
+            {
+                GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                          "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(NULL), append=%u, max_matches=%u, type_list) => %u",
+                                                          name.GetCString(), 
+                                                          append, 
+                                                          max_matches,
+                                                          num_matches);
+            }
+        }
+        return num_matches;
+    }
+    return 0;
+}
+
+
+ClangNamespaceDecl
+SymbolFileDWARF::FindNamespace (const SymbolContext& sc, 
+                                const ConstString &name,
+                                const lldb_private::ClangNamespaceDecl *parent_namespace_decl)
+{
+    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
+    
+    if (log)
+    {
+        GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                  "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")", 
+                                                  name.GetCString());
+    }
+    
+    if (!NamespaceDeclMatchesThisSymbolFile(parent_namespace_decl))
+		return ClangNamespaceDecl();
+
+    ClangNamespaceDecl namespace_decl;
+    DWARFDebugInfo* info = DebugInfo();
+    if (info)
+    {
+        DIEArray die_offsets;
+
+        // Index if we already haven't to make sure the compile units
+        // get indexed and make their global DIE index list
+        if (m_using_apple_tables)
+        {
+            if (m_apple_namespaces_ap.get())
+            {
+                const char *name_cstr = name.GetCString();
+                m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
+            }
+        }
+        else
+        {
+            if (!m_indexed)
+                Index ();
+
+            m_namespace_index.Find (name, die_offsets);
+        }
+        
+        DWARFCompileUnit* dwarf_cu = NULL;
+        const DWARFDebugInfoEntry* die = NULL;
+        const size_t num_matches = die_offsets.size();
+        if (num_matches)
+        {
+            DWARFDebugInfo* debug_info = DebugInfo();
+            for (size_t i=0; i<num_matches; ++i)
+            {
+                const dw_offset_t die_offset = die_offsets[i];
+                die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+                
+                if (die)
+                {
+                    if (parent_namespace_decl && !DIEIsInNamespace (parent_namespace_decl, dwarf_cu, die))
+                        continue;
+
+                    clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die);
+                    if (clang_namespace_decl)
+                    {
+                        namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
+                        namespace_decl.SetNamespaceDecl (clang_namespace_decl);
+                        break;
+                    }
+                }
+                else
+                {
+                    if (m_using_apple_tables)
+                    {
+                        GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n",
+                                                                   die_offset, name.GetCString());
+                    }
+                }            
+
+            }
+        }
+    }
+    if (log && namespace_decl.GetNamespaceDecl())
+    {
+        GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                  "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => clang::NamespaceDecl(%p) \"%s\"",
+                                                  name.GetCString(),
+                                                  namespace_decl.GetNamespaceDecl(),
+                                                  namespace_decl.GetQualifiedName().c_str());
+    }
+
+    return namespace_decl;
+}
+
+uint32_t
+SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
+{
+    // Remember how many sc_list are in the list before we search in case
+    // we are appending the results to a variable list.
+    uint32_t original_size = types.GetSize();
+
+    const uint32_t num_die_offsets = die_offsets.size();
+    // Parse all of the types we found from the pubtypes matches
+    uint32_t i;
+    uint32_t num_matches = 0;
+    for (i = 0; i < num_die_offsets; ++i)
+    {
+        Type *matching_type = ResolveTypeUID (die_offsets[i]);
+        if (matching_type)
+        {
+            // We found a type pointer, now find the shared pointer form our type list
+            types.InsertUnique (matching_type->shared_from_this());
+            ++num_matches;
+            if (num_matches >= max_matches)
+                break;
+        }
+    }
+
+    // Return the number of variable that were appended to the list
+    return types.GetSize() - original_size;
+}
+
+
+size_t
+SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
+                                       clang::DeclContext *containing_decl_ctx,
+                                       DWARFCompileUnit* dwarf_cu,
+                                       const DWARFDebugInfoEntry *parent_die,
+                                       bool skip_artificial,
+                                       bool &is_static,
+                                       TypeList* type_list,
+                                       std::vector<clang_type_t>& function_param_types,
+                                       std::vector<clang::ParmVarDecl*>& function_param_decls,
+                                       unsigned &type_quals,
+                                       ClangASTContext::TemplateParameterInfos &template_param_infos)
+{
+    if (parent_die == NULL)
+        return 0;
+
+    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
+
+    size_t arg_idx = 0;
+    const DWARFDebugInfoEntry *die;
+    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
+    {
+        dw_tag_t tag = die->Tag();
+        switch (tag)
+        {
+        case DW_TAG_formal_parameter:
+            {
+                DWARFDebugInfoEntry::Attributes attributes;
+                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
+                if (num_attributes > 0)
+                {
+                    const char *name = NULL;
+                    Declaration decl;
+                    dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
+                    bool is_artificial = false;
+                    // one of None, Auto, Register, Extern, Static, PrivateExtern
+
+                    clang::StorageClass storage = clang::SC_None;
+                    uint32_t i;
+                    for (i=0; i<num_attributes; ++i)
+                    {
+                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
+                        DWARFFormValue form_value;
+                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                        {
+                            switch (attr)
+                            {
+                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
+                            case DW_AT_type:        param_type_die_offset = form_value.Reference(dwarf_cu); break;
+                            case DW_AT_artificial:  is_artificial = form_value.Unsigned() != 0; break;
+                            case DW_AT_location:
+    //                          if (form_value.BlockData())
+    //                          {
+    //                              const DataExtractor& debug_info_data = debug_info();
+    //                              uint32_t block_length = form_value.Unsigned();
+    //                              DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
+    //                          }
+    //                          else
+    //                          {
+    //                          }
+    //                          break;
+                            case DW_AT_const_value:
+                            case DW_AT_default_value:
+                            case DW_AT_description:
+                            case DW_AT_endianity:
+                            case DW_AT_is_optional:
+                            case DW_AT_segment:
+                            case DW_AT_variable_parameter:
+                            default:
+                            case DW_AT_abstract_origin:
+                            case DW_AT_sibling:
+                                break;
+                            }
+                        }
+                    }
+
+                    bool skip = false;
+                    if (skip_artificial)
+                    {
+                        if (is_artificial)
+                        {
+                            // In order to determine if a C++ member function is
+                            // "const" we have to look at the const-ness of "this"...
+                            // Ugly, but that
+                            if (arg_idx == 0)
+                            {
+                                if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()))
+                                {                                    
+                                    // Often times compilers omit the "this" name for the
+                                    // specification DIEs, so we can't rely upon the name
+                                    // being in the formal parameter DIE...
+                                    if (name == NULL || ::strcmp(name, "this")==0)
+                                    {
+                                        Type *this_type = ResolveTypeUID (param_type_die_offset);
+                                        if (this_type)
+                                        {                              
+                                            uint32_t encoding_mask = this_type->GetEncodingMask();
+                                            if (encoding_mask & Type::eEncodingIsPointerUID)
+                                            {
+                                                is_static = false;
+                                                
+                                                if (encoding_mask & (1u << Type::eEncodingIsConstUID))
+                                                    type_quals |= clang::Qualifiers::Const;
+                                                if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
+                                                    type_quals |= clang::Qualifiers::Volatile;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                            skip = true;
+                        }
+                        else
+                        {
+
+                            // HACK: Objective C formal parameters "self" and "_cmd" 
+                            // are not marked as artificial in the DWARF...
+                            CompileUnit *comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
+                            if (comp_unit)
+                            {
+                                switch (comp_unit->GetLanguage())
+                                {
+                                    case eLanguageTypeObjC:
+                                    case eLanguageTypeObjC_plus_plus:
+                                        if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
+                                            skip = true;
+                                        break;
+                                    default:
+                                        break;
+                                }
+                            }
+                        }
+                    }
+
+                    if (!skip)
+                    {
+                        Type *type = ResolveTypeUID(param_type_die_offset);
+                        if (type)
+                        {
+                            function_param_types.push_back (type->GetClangForwardType());
+
+                            clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, 
+                                                                                                                  type->GetClangForwardType(), 
+                                                                                                                  storage);
+                            assert(param_var_decl);
+                            function_param_decls.push_back(param_var_decl);
+                            
+                            GetClangASTContext().SetMetadataAsUserID ((uintptr_t)param_var_decl, MakeUserID(die->GetOffset()));
+                        }
+                    }
+                }
+                arg_idx++;
+            }
+            break;
+
+        case DW_TAG_template_type_parameter:
+        case DW_TAG_template_value_parameter:
+            ParseTemplateDIE (dwarf_cu, die,template_param_infos);
+            break;
+
+        default:
+            break;
+        }
+    }
+    return arg_idx;
+}
+
+size_t
+SymbolFileDWARF::ParseChildEnumerators
+(
+    const SymbolContext& sc,
+    clang_type_t  enumerator_clang_type,
+    uint32_t enumerator_byte_size,
+    DWARFCompileUnit* dwarf_cu,
+    const DWARFDebugInfoEntry *parent_die
+)
+{
+    if (parent_die == NULL)
+        return 0;
+
+    size_t enumerators_added = 0;
+    const DWARFDebugInfoEntry *die;
+    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
+
+    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
+    {
+        const dw_tag_t tag = die->Tag();
+        if (tag == DW_TAG_enumerator)
+        {
+            DWARFDebugInfoEntry::Attributes attributes;
+            const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
+            if (num_child_attributes > 0)
+            {
+                const char *name = NULL;
+                bool got_value = false;
+                int64_t enum_value = 0;
+                Declaration decl;
+
+                uint32_t i;
+                for (i=0; i<num_child_attributes; ++i)
+                {
+                    const dw_attr_t attr = attributes.AttributeAtIndex(i);
+                    DWARFFormValue form_value;
+                    if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                    {
+                        switch (attr)
+                        {
+                        case DW_AT_const_value:
+                            got_value = true;
+                            enum_value = form_value.Unsigned();
+                            break;
+
+                        case DW_AT_name:
+                            name = form_value.AsCString(&get_debug_str_data());
+                            break;
+
+                        case DW_AT_description:
+                        default:
+                        case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                        case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                        case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                        case DW_AT_sibling:
+                            break;
+                        }
+                    }
+                }
+
+                if (name && name[0] && got_value)
+                {
+                    GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type, 
+                                                                               enumerator_clang_type, 
+                                                                               decl, 
+                                                                               name, 
+                                                                               enum_value, 
+                                                                               enumerator_byte_size * 8);
+                    ++enumerators_added;
+                }
+            }
+        }
+    }
+    return enumerators_added;
+}
+
+void
+SymbolFileDWARF::ParseChildArrayInfo
+(
+    const SymbolContext& sc,
+    DWARFCompileUnit* dwarf_cu,
+    const DWARFDebugInfoEntry *parent_die,
+    int64_t& first_index,
+    std::vector<uint64_t>& element_orders,
+    uint32_t& byte_stride,
+    uint32_t& bit_stride
+)
+{
+    if (parent_die == NULL)
+        return;
+
+    const DWARFDebugInfoEntry *die;
+    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
+    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
+    {
+        const dw_tag_t tag = die->Tag();
+        switch (tag)
+        {
+        case DW_TAG_subrange_type:
+            {
+                DWARFDebugInfoEntry::Attributes attributes;
+                const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
+                if (num_child_attributes > 0)
+                {
+                    uint64_t num_elements = 0;
+                    uint64_t lower_bound = 0;
+                    uint64_t upper_bound = 0;
+                    uint32_t i;
+                    for (i=0; i<num_child_attributes; ++i)
+                    {
+                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
+                        DWARFFormValue form_value;
+                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                        {
+                            switch (attr)
+                            {
+                            case DW_AT_name:
+                                break;
+
+                            case DW_AT_count:
+                                num_elements = form_value.Unsigned();
+                                break;
+
+                            case DW_AT_bit_stride:
+                                bit_stride = form_value.Unsigned();
+                                break;
+
+                            case DW_AT_byte_stride:
+                                byte_stride = form_value.Unsigned();
+                                break;
+
+                            case DW_AT_lower_bound:
+                                lower_bound = form_value.Unsigned();
+                                break;
+
+                            case DW_AT_upper_bound:
+                                upper_bound = form_value.Unsigned();
+                                break;
+
+                            default:
+                            case DW_AT_abstract_origin:
+                            case DW_AT_accessibility:
+                            case DW_AT_allocated:
+                            case DW_AT_associated:
+                            case DW_AT_data_location:
+                            case DW_AT_declaration:
+                            case DW_AT_description:
+                            case DW_AT_sibling:
+                            case DW_AT_threads_scaled:
+                            case DW_AT_type:
+                            case DW_AT_visibility:
+                                break;
+                            }
+                        }
+                    }
+
+                    if (upper_bound > lower_bound)
+                        num_elements = upper_bound - lower_bound + 1;
+
+                    element_orders.push_back (num_elements);
+                }
+            }
+            break;
+        }
+    }
+}
+
+TypeSP
+SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *dwarf_cu, const DWARFDebugInfoEntry* die)
+{
+    TypeSP type_sp;
+    if (die != NULL)
+    {
+        assert(dwarf_cu != NULL);
+        Type *type_ptr = m_die_to_type.lookup (die);
+        if (type_ptr == NULL)
+        {
+            CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(dwarf_cu);
+            assert (lldb_cu);
+            SymbolContext sc(lldb_cu);
+            type_sp = ParseType(sc, dwarf_cu, die, NULL);
+        }
+        else if (type_ptr != DIE_IS_BEING_PARSED)
+        {
+            // Grab the existing type from the master types lists
+            type_sp = type_ptr->shared_from_this();
+        }
+
+    }
+    return type_sp;
+}
+
+clang::DeclContext *
+SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
+{
+    if (die_offset != DW_INVALID_OFFSET)
+    {
+        DWARFCompileUnitSP cu_sp;
+        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
+        return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
+    }
+    return NULL;
+}
+
+clang::DeclContext *
+SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
+{
+    if (die_offset != DW_INVALID_OFFSET)
+    {
+        DWARFDebugInfo* debug_info = DebugInfo();
+        if (debug_info)
+        {
+            DWARFCompileUnitSP cu_sp;
+            const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(die_offset, &cu_sp);
+            if (die)
+                return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
+        }
+    }
+    return NULL;
+}
+
+clang::NamespaceDecl *
+SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *dwarf_cu, const DWARFDebugInfoEntry *die)
+{
+    if (die && die->Tag() == DW_TAG_namespace)
+    {
+        // See if we already parsed this namespace DIE and associated it with a
+        // uniqued namespace declaration
+        clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die]);
+        if (namespace_decl)
+            return namespace_decl;
+        else
+        {
+            const char *namespace_name = die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL);
+            clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, NULL);
+            namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx);
+            LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+            if (log)
+            {
+                if (namespace_name)
+                {
+                    GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                              "ASTContext => %p: 0x%8.8llx: DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)", 
+                                                              GetClangASTContext().getASTContext(),
+                                                              MakeUserID(die->GetOffset()),
+                                                              namespace_name,
+                                                              namespace_decl,
+                                                              namespace_decl->getOriginalNamespace());
+                }
+                else
+                {
+                    GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                              "ASTContext => %p: 0x%8.8llx: DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)", 
+                                                              GetClangASTContext().getASTContext(),
+                                                              MakeUserID(die->GetOffset()),
+                                                              namespace_decl,
+                                                              namespace_decl->getOriginalNamespace());
+                }
+            }
+
+            if (namespace_decl)
+                LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
+            return namespace_decl;
+        }
+    }
+    return NULL;
+}
+
+clang::DeclContext *
+SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
+{
+    clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
+    if (clang_decl_ctx)
+        return clang_decl_ctx;
+    // If this DIE has a specification, or an abstract origin, then trace to those.
+        
+    dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
+    if (die_offset != DW_INVALID_OFFSET)
+        return GetClangDeclContextForDIEOffset (sc, die_offset);
+    
+    die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
+    if (die_offset != DW_INVALID_OFFSET)
+        return GetClangDeclContextForDIEOffset (sc, die_offset);
+    
+    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+    if (log)
+        GetObjectFile()->GetModule()->LogMessage(log.get(), "SymbolFileDWARF::GetClangDeclContextForDIE (die = 0x%8.8x) %s '%s'", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), die->GetName(this, cu));
+    // This is the DIE we want.  Parse it, then query our map.
+    bool assert_not_being_parsed = true;
+    ResolveTypeUID (cu, die, assert_not_being_parsed);    
+
+    clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
+
+    return clang_decl_ctx;
+}
+
+clang::DeclContext *
+SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, const DWARFDebugInfoEntry **decl_ctx_die_copy)
+{
+    if (m_clang_tu_decl == NULL)
+        m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
+
+    const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
+
+    if (decl_ctx_die_copy)
+        *decl_ctx_die_copy = decl_ctx_die;
+    
+    if (decl_ctx_die)
+    {
+
+        DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find (decl_ctx_die);
+        if (pos != m_die_to_decl_ctx.end())
+            return pos->second;
+
+        switch (decl_ctx_die->Tag())
+        {
+        case DW_TAG_compile_unit:
+            return m_clang_tu_decl;
+
+        case DW_TAG_namespace:
+            return ResolveNamespaceDIE (cu, decl_ctx_die);
+            break;
+
+        case DW_TAG_structure_type:
+        case DW_TAG_union_type:
+        case DW_TAG_class_type:
+            {
+                Type* type = ResolveType (cu, decl_ctx_die);
+                if (type)
+                {
+                    clang::DeclContext *decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
+                    if (decl_ctx)
+                    {
+                        LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
+                        if (decl_ctx)
+                            return decl_ctx;
+                    }
+                }
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
+    return m_clang_tu_decl;
+}
+
+
+const DWARFDebugInfoEntry *
+SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
+{
+    if (cu && die)
+    {
+        const DWARFDebugInfoEntry * const decl_die = die;
+    
+        while (die != NULL)
+        {
+            // If this is the original DIE that we are searching for a declaration 
+            // for, then don't look in the cache as we don't want our own decl 
+            // context to be our decl context...
+            if (decl_die != die)
+            {            
+                switch (die->Tag())
+                {
+                    case DW_TAG_compile_unit:
+                    case DW_TAG_namespace:
+                    case DW_TAG_structure_type:
+                    case DW_TAG_union_type:
+                    case DW_TAG_class_type:
+                        return die;
+                        
+                    default:
+                        break;
+                }
+            }
+            
+            dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
+            if (die_offset != DW_INVALID_OFFSET)
+            {
+                DWARFCompileUnit *spec_cu = cu;
+                const DWARFDebugInfoEntry *spec_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &spec_cu);
+                const DWARFDebugInfoEntry *spec_die_decl_ctx_die = GetDeclContextDIEContainingDIE (spec_cu, spec_die);
+                if (spec_die_decl_ctx_die)
+                    return spec_die_decl_ctx_die;
+            }
+            
+            die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
+            if (die_offset != DW_INVALID_OFFSET)
+            {
+                DWARFCompileUnit *abs_cu = cu;
+                const DWARFDebugInfoEntry *abs_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &abs_cu);
+                const DWARFDebugInfoEntry *abs_die_decl_ctx_die = GetDeclContextDIEContainingDIE (abs_cu, abs_die);
+                if (abs_die_decl_ctx_die)
+                    return abs_die_decl_ctx_die;
+            }
+            
+            die = die->GetParent();
+        }
+    }
+    return NULL;
+}
+
+
+Symbol *
+SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
+{
+    Symbol *objc_class_symbol = NULL;
+    if (m_obj_file)
+    {
+        Symtab *symtab = m_obj_file->GetSymtab();
+        if (symtab)
+        {
+            objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name, 
+                                                                        eSymbolTypeObjCClass, 
+                                                                        Symtab::eDebugNo, 
+                                                                        Symtab::eVisibilityAny);
+        }
+    }
+    return objc_class_symbol;
+}
+
+// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't
+// then we can end up looking through all class types for a complete type and never find
+// the full definition. We need to know if this attribute is supported, so we determine
+// this here and cache th result. We also need to worry about the debug map DWARF file
+// if we are doing darwin DWARF in .o file debugging.
+bool
+SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
+{
+    if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
+    {
+        m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
+        if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
+            m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
+        else
+        {
+            DWARFDebugInfo* debug_info = DebugInfo();
+            const uint32_t num_compile_units = GetNumCompileUnits();
+            for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
+            {
+                DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
+                if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type())
+                {
+                    m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
+                    break;
+                }
+            }
+        }
+        if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ())
+            return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
+    }
+    return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
+}
+
+// This function can be used when a DIE is found that is a forward declaration
+// DIE and we want to try and find a type that has the complete definition.
+TypeSP
+SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die, 
+                                                       const ConstString &type_name,
+                                                       bool must_be_implementation)
+{
+    
+    TypeSP type_sp;
+    
+    if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name)))
+        return type_sp;
+    
+    DIEArray die_offsets;
+    
+    if (m_using_apple_tables)
+    {
+        if (m_apple_types_ap.get())
+        {
+            const char *name_cstr = type_name.GetCString();
+            m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation);
+        }
+    }
+    else
+    {
+        if (!m_indexed)
+            Index ();
+        
+        m_type_index.Find (type_name, die_offsets);
+    }
+    
+    const size_t num_matches = die_offsets.size();
+    
+    DWARFCompileUnit* type_cu = NULL;
+    const DWARFDebugInfoEntry* type_die = NULL;
+    if (num_matches)
+    {
+        DWARFDebugInfo* debug_info = DebugInfo();
+        for (size_t i=0; i<num_matches; ++i)
+        {
+            const dw_offset_t die_offset = die_offsets[i];
+            type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
+            
+            if (type_die)
+            {
+                bool try_resolving_type = false;
+                
+                // Don't try and resolve the DIE we are looking for with the DIE itself!
+                if (type_die != die)
+                {
+                    switch (type_die->Tag())
+                    {
+                        case DW_TAG_class_type:
+                        case DW_TAG_structure_type:
+                            try_resolving_type = true;
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                
+                if (try_resolving_type)
+                {
+					if (must_be_implementation && type_cu->Supports_DW_AT_APPLE_objc_complete_type())
+	                    try_resolving_type = type_die->GetAttributeValueAsUnsigned (this, type_cu, DW_AT_APPLE_objc_complete_type, 0);
+                    
+                    if (try_resolving_type)
+                    {
+                        Type *resolved_type = ResolveType (type_cu, type_die, false);
+                        if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
+                        {
+                            DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n",
+                                          MakeUserID(die->GetOffset()), 
+                                          MakeUserID(dwarf_cu->GetOffset()),
+                                          m_obj_file->GetFileSpec().GetFilename().AsCString(),
+                                          MakeUserID(type_die->GetOffset()), 
+                                          MakeUserID(type_cu->GetOffset()));
+                            
+                            if (die)
+                                m_die_to_type[die] = resolved_type;
+                            type_sp = resolved_type->shared_from_this();
+                            break;
+                        }
+                    }
+                }
+            }
+            else
+            {
+                if (m_using_apple_tables)
+                {
+                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
+                                                               die_offset, type_name.GetCString());
+                }
+            }            
+            
+        }
+    }
+    return type_sp;
+}
+
+
+//----------------------------------------------------------------------
+// This function helps to ensure that the declaration contexts match for
+// two different DIEs. Often times debug information will refer to a 
+// forward declaration of a type (the equivalent of "struct my_struct;".
+// There will often be a declaration of that type elsewhere that has the
+// full definition. When we go looking for the full type "my_struct", we
+// will find one or more matches in the accelerator tables and we will
+// then need to make sure the type was in the same declaration context 
+// as the original DIE. This function can efficiently compare two DIEs
+// and will return true when the declaration context matches, and false
+// when they don't. 
+//----------------------------------------------------------------------
+bool
+SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugInfoEntry *die1,
+                                       DWARFCompileUnit* cu2, const DWARFDebugInfoEntry *die2)
+{
+    if (die1 == die2)
+        return true;
+
+#if defined (LLDB_CONFIGURATION_DEBUG)
+    // You can't and shouldn't call this function with a compile unit from
+    // two different SymbolFileDWARF instances.
+    assert (DebugInfo()->ContainsCompileUnit (cu1));
+    assert (DebugInfo()->ContainsCompileUnit (cu2));
+#endif
+
+    DWARFDIECollection decl_ctx_1;
+    DWARFDIECollection decl_ctx_2;
+    //The declaration DIE stack is a stack of the declaration context 
+    // DIEs all the way back to the compile unit. If a type "T" is
+    // declared inside a class "B", and class "B" is declared inside
+    // a class "A" and class "A" is in a namespace "lldb", and the
+    // namespace is in a compile unit, there will be a stack of DIEs:
+    //
+    //   [0] DW_TAG_class_type for "B"
+    //   [1] DW_TAG_class_type for "A"
+    //   [2] DW_TAG_namespace  for "lldb"
+    //   [3] DW_TAG_compile_unit for the source file.
+    // 
+    // We grab both contexts and make sure that everything matches 
+    // all the way back to the compiler unit.
+    
+    // First lets grab the decl contexts for both DIEs
+    die1->GetDeclContextDIEs (this, cu1, decl_ctx_1);
+    die2->GetDeclContextDIEs (this, cu2, decl_ctx_2);
+    // Make sure the context arrays have the same size, otherwise
+    // we are done
+    const size_t count1 = decl_ctx_1.Size();
+    const size_t count2 = decl_ctx_2.Size();
+    if (count1 != count2)
+        return false;
+    
+    // Make sure the DW_TAG values match all the way back up the the
+    // compile unit. If they don't, then we are done.
+    const DWARFDebugInfoEntry *decl_ctx_die1;
+    const DWARFDebugInfoEntry *decl_ctx_die2;
+    size_t i;
+    for (i=0; i<count1; i++)
+    {
+        decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
+        decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
+        if (decl_ctx_die1->Tag() != decl_ctx_die2->Tag())
+            return false;
+    }
+#if defined LLDB_CONFIGURATION_DEBUG
+
+    // Make sure the top item in the decl context die array is always 
+    // DW_TAG_compile_unit. If it isn't then something went wrong in
+    // the DWARFDebugInfoEntry::GetDeclContextDIEs() function...
+    assert (decl_ctx_1.GetDIEPtrAtIndex (count1 - 1)->Tag() == DW_TAG_compile_unit);
+
+#endif
+    // Always skip the compile unit when comparing by only iterating up to
+    // "count - 1". Here we compare the names as we go. 
+    for (i=0; i<count1 - 1; i++)
+    {
+        decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
+        decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
+        const char *name1 = decl_ctx_die1->GetName(this, cu1);
+        const char *name2 = decl_ctx_die2->GetName(this, cu2);
+        // If the string was from a DW_FORM_strp, then the pointer will often
+        // be the same!
+        if (name1 == name2)
+            continue;
+
+        // Name pointers are not equal, so only compare the strings
+        // if both are not NULL.
+        if (name1 && name2)
+        {
+            // If the strings don't compare, we are done...
+            if (strcmp(name1, name2) != 0)
+                return false;
+        }
+        else
+        {
+            // One name was NULL while the other wasn't
+            return false;
+        }
+    }
+    // We made it through all of the checks and the declaration contexts
+    // are equal.
+    return true;
+}
+                                          
+// This function can be used when a DIE is found that is a forward declaration
+// DIE and we want to try and find a type that has the complete definition.
+// "cu" and "die" must be from this SymbolFileDWARF
+TypeSP
+SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu,
+                                           const DWARFDebugInfoEntry *die, 
+                                           const ConstString &type_name)
+{
+    TypeSP type_sp;
+
+#if defined (LLDB_CONFIGURATION_DEBUG)
+    // You can't and shouldn't call this function with a compile unit from
+    // another SymbolFileDWARF instance.
+    assert (DebugInfo()->ContainsCompileUnit (cu));
+#endif
+
+    if (cu == NULL || die == NULL || !type_name)
+        return type_sp;
+
+    LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
+    if (log)
+    {
+        std::string qualified_name;
+        die->GetQualifiedName(this, cu, qualified_name);
+        GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                  "SymbolFileDWARF::FindDefinitionTypeForDIE(die=0x%8.8x (%s), name='%s')",
+                                                  die->GetOffset(),
+                                                  qualified_name.c_str(),
+                                                  type_name.GetCString());
+    }
+
+    DIEArray die_offsets;
+
+    if (m_using_apple_tables)
+    {
+        if (m_apple_types_ap.get())
+        {
+            if (m_apple_types_ap->GetHeader().header_data.atoms.size() > 1)
+            {
+                m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), die->Tag(), die_offsets);
+            }
+            else
+            {
+                m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
+            }
+        }
+    }
+    else
+    {
+        if (!m_indexed)
+            Index ();
+        
+        m_type_index.Find (type_name, die_offsets);
+    }
+    
+    const size_t num_matches = die_offsets.size();
+
+    const dw_tag_t die_tag = die->Tag();
+    
+    DWARFCompileUnit* type_cu = NULL;
+    const DWARFDebugInfoEntry* type_die = NULL;
+    if (num_matches)
+    {
+        DWARFDebugInfo* debug_info = DebugInfo();
+        for (size_t i=0; i<num_matches; ++i)
+        {
+            const dw_offset_t die_offset = die_offsets[i];
+            type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
+            
+            if (type_die)
+            {
+                bool try_resolving_type = false;
+
+                // Don't try and resolve the DIE we are looking for with the DIE itself!
+                if (type_die != die)
+                {
+                    const dw_tag_t type_die_tag = type_die->Tag();
+                    // Make sure the tags match
+                    if (type_die_tag == die_tag)
+                    {
+                        // The tags match, lets try resolving this type
+                        try_resolving_type = true;
+                    }
+                    else
+                    {
+                        // The tags don't match, but we need to watch our for a
+                        // forward declaration for a struct and ("struct foo")
+                        // ends up being a class ("class foo { ... };") or
+                        // vice versa.
+                        switch (type_die_tag)
+                        {
+                        case DW_TAG_class_type:
+                            // We had a "class foo", see if we ended up with a "struct foo { ... };"
+                            try_resolving_type = (die_tag == DW_TAG_structure_type);
+                            break;
+                        case DW_TAG_structure_type:
+                            // We had a "struct foo", see if we ended up with a "class foo { ... };"
+                            try_resolving_type = (die_tag == DW_TAG_class_type);
+                            break;
+                        default:
+                            // Tags don't match, don't event try to resolve
+                            // using this type whose name matches....
+                            break;
+                        }
+                    }
+                }
+                        
+                if (try_resolving_type)
+                {
+                    if (log)
+                    {
+                        std::string qualified_name;
+                        type_die->GetQualifiedName(this, cu, qualified_name);
+                        GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                                  "SymbolFileDWARF::FindDefinitionTypeForDIE(die=0x%8.8x, name='%s') trying die=0x%8.8x (%s)",
+                                                                  die->GetOffset(),
+                                                                  type_name.GetCString(),
+                                                                  type_die->GetOffset(),
+                                                                  qualified_name.c_str());
+                    }
+                    
+                    // Make sure the decl contexts match all the way up
+                    if (DIEDeclContextsMatch(cu, die, type_cu, type_die))
+                    {
+                        Type *resolved_type = ResolveType (type_cu, type_die, false);
+                        if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
+                        {
+                            DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n",
+                                          MakeUserID(die->GetOffset()), 
+                                          MakeUserID(dwarf_cu->GetOffset()),
+                                          m_obj_file->GetFileSpec().GetFilename().AsCString(),
+                                          MakeUserID(type_die->GetOffset()), 
+                                          MakeUserID(type_cu->GetOffset()));
+                            
+                            m_die_to_type[die] = resolved_type;
+                            type_sp = resolved_type->shared_from_this();
+                            break;
+                        }
+                    }
+                }
+                else
+                {
+                    if (log)
+                    {
+                        std::string qualified_name;
+                        type_die->GetQualifiedName(this, cu, qualified_name);
+                        GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                                  "SymbolFileDWARF::FindDefinitionTypeForDIE(die=0x%8.8x, name='%s') ignoring die=0x%8.8x (%s)",
+                                                                  die->GetOffset(),
+                                                                  type_name.GetCString(),
+                                                                  type_die->GetOffset(),
+                                                                  qualified_name.c_str());
+                    }
+                }
+            }
+            else
+            {
+                if (m_using_apple_tables)
+                {
+                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
+                                                                               die_offset, type_name.GetCString());
+                }
+            }            
+
+        }
+    }
+    return type_sp;
+}
+
+TypeSP
+SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx)
+{
+    TypeSP type_sp;
+
+    const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
+    if (dwarf_decl_ctx_count > 0)
+    {
+        const ConstString type_name(dwarf_decl_ctx[0].name);
+        const dw_tag_t tag = dwarf_decl_ctx[0].tag;
+
+        if (type_name)
+        {
+            LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
+            if (log)
+            {
+                GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                          "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')",
+                                                          DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
+                                                          dwarf_decl_ctx.GetQualifiedName());
+            }
+            
+            DIEArray die_offsets;
+            
+            if (m_using_apple_tables)
+            {
+                if (m_apple_types_ap.get())
+                {
+                    if (m_apple_types_ap->GetHeader().header_data.atoms.size() > 1)
+                    {
+                        m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
+                    }
+                    else
+                    {
+                        m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
+                    }
+                }
+            }
+            else
+            {
+                if (!m_indexed)
+                    Index ();
+                
+                m_type_index.Find (type_name, die_offsets);
+            }
+            
+            const size_t num_matches = die_offsets.size();
+            
+            
+            DWARFCompileUnit* type_cu = NULL;
+            const DWARFDebugInfoEntry* type_die = NULL;
+            if (num_matches)
+            {
+                DWARFDebugInfo* debug_info = DebugInfo();
+                for (size_t i=0; i<num_matches; ++i)
+                {
+                    const dw_offset_t die_offset = die_offsets[i];
+                    type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
+                    
+                    if (type_die)
+                    {
+                        bool try_resolving_type = false;
+                        
+                        // Don't try and resolve the DIE we are looking for with the DIE itself!
+                        const dw_tag_t type_tag = type_die->Tag();
+                        // Make sure the tags match
+                        if (type_tag == tag)
+                        {
+                            // The tags match, lets try resolving this type
+                            try_resolving_type = true;
+                        }
+                        else
+                        {
+                            // The tags don't match, but we need to watch our for a
+                            // forward declaration for a struct and ("struct foo")
+                            // ends up being a class ("class foo { ... };") or
+                            // vice versa.
+                            switch (type_tag)
+                            {
+                                case DW_TAG_class_type:
+                                    // We had a "class foo", see if we ended up with a "struct foo { ... };"
+                                    try_resolving_type = (tag == DW_TAG_structure_type);
+                                    break;
+                                case DW_TAG_structure_type:
+                                    // We had a "struct foo", see if we ended up with a "class foo { ... };"
+                                    try_resolving_type = (tag == DW_TAG_class_type);
+                                    break;
+                                default:
+                                    // Tags don't match, don't event try to resolve
+                                    // using this type whose name matches....
+                                    break;
+                            }
+                        }
+                        
+                        if (try_resolving_type)
+                        {
+                            DWARFDeclContext type_dwarf_decl_ctx;
+                            type_die->GetDWARFDeclContext (this, type_cu, type_dwarf_decl_ctx);
+
+                            if (log)
+                            {
+                                GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                                          "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
+                                                                          DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
+                                                                          dwarf_decl_ctx.GetQualifiedName(),
+                                                                          type_die->GetOffset(),
+                                                                          type_dwarf_decl_ctx.GetQualifiedName());
+                            }
+                            
+                            // Make sure the decl contexts match all the way up
+                            if (dwarf_decl_ctx == type_dwarf_decl_ctx)
+                            {
+                                Type *resolved_type = ResolveType (type_cu, type_die, false);
+                                if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
+                                {
+                                    type_sp = resolved_type->shared_from_this();
+                                    break;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            if (log)
+                            {
+                                std::string qualified_name;
+                                type_die->GetQualifiedName(this, type_cu, qualified_name);
+                                GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                                          "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
+                                                                          DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
+                                                                          dwarf_decl_ctx.GetQualifiedName(),
+                                                                          type_die->GetOffset(),
+                                                                          qualified_name.c_str());
+                            }
+                        }
+                    }
+                    else
+                    {
+                        if (m_using_apple_tables)
+                        {
+                            GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
+                                                                                       die_offset, type_name.GetCString());
+                        }
+                    }            
+                    
+                }
+            }
+        }
+    }
+    return type_sp;
+}
+
+bool
+SymbolFileDWARF::CopyUniqueClassMethodTypes (Type *class_type,
+                                             DWARFCompileUnit* src_cu,
+                                             const DWARFDebugInfoEntry *src_class_die,
+                                             DWARFCompileUnit* dst_cu,
+                                             const DWARFDebugInfoEntry *dst_class_die)
+{
+    if (!class_type || !src_cu || !src_class_die || !dst_cu || !dst_class_die)
+        return false;
+    if (src_class_die->Tag() != dst_class_die->Tag())
+        return false;
+    
+    // We need to complete the class type so we can get all of the method types
+    // parsed so we can then unique those types to their equivalent counterparts
+    // in "dst_cu" and "dst_class_die"
+    class_type->GetClangFullType();
+
+    const DWARFDebugInfoEntry *src_die;
+    const DWARFDebugInfoEntry *dst_die;
+    UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die;
+    UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die;
+    for (src_die = src_class_die->GetFirstChild(); src_die != NULL; src_die = src_die->GetSibling())
+    {
+        if (src_die->Tag() == DW_TAG_subprogram)
+        {
+            const char *src_name = src_die->GetMangledName (this, src_cu);
+            if (src_name)
+                src_name_to_die.Append(ConstString(src_name).GetCString(), src_die);
+        }
+    }
+    for (dst_die = dst_class_die->GetFirstChild(); dst_die != NULL; dst_die = dst_die->GetSibling())
+    {
+        if (dst_die->Tag() == DW_TAG_subprogram)
+        {
+            const char *dst_name = dst_die->GetMangledName (this, dst_cu);
+            if (dst_name)
+                dst_name_to_die.Append(ConstString(dst_name).GetCString(), dst_die);
+        }
+    }
+    const uint32_t src_size = src_name_to_die.GetSize ();
+    const uint32_t dst_size = dst_name_to_die.GetSize ();
+    LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION));
+    
+    if (src_size && dst_size)
+    {
+        if (src_size != dst_size)
+        {
+            if (log)
+                log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)",
+                            src_class_die->GetOffset(),
+                            dst_class_die->GetOffset(),
+                            src_size,
+                            dst_size);
+            
+            return false;
+        }
+            
+        uint32_t idx;
+        for (idx = 0; idx < src_size; ++idx)
+        {
+            src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
+            dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
+
+            if (src_die->Tag() != dst_die->Tag())
+            {
+                if (log)
+                    log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)",
+                                src_class_die->GetOffset(),
+                                dst_class_die->GetOffset(),
+                                src_die->GetOffset(),
+                                DW_TAG_value_to_name(src_die->Tag()),
+                                dst_die->GetOffset(),
+                                DW_TAG_value_to_name(src_die->Tag()));
+                return false;
+            }
+            
+            const char *src_name = src_die->GetMangledName (this, src_cu);
+            const char *dst_name = dst_die->GetMangledName (this, dst_cu);
+            
+            // Make sure the names match
+            if (src_name == dst_name || (strcmp (src_name, dst_name) == 0))
+                continue;
+
+            if (log)
+                log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)",
+                            src_class_die->GetOffset(),
+                            dst_class_die->GetOffset(),
+                            src_die->GetOffset(),
+                            src_name,
+                            dst_die->GetOffset(),
+                            dst_name);
+            
+            return false;
+        }
+
+        for (idx = 0; idx < src_size; ++idx)
+        {
+            src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
+            dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
+            
+            clang::DeclContext *src_decl_ctx = m_die_to_decl_ctx[src_die];
+            if (src_decl_ctx)
+            {
+                if (log)
+                    log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x\n", src_decl_ctx, src_die->GetOffset(), dst_die->GetOffset());
+                LinkDeclContextToDIE (src_decl_ctx, dst_die);
+            }
+            else
+            {
+                if (log)
+                    log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found\n", src_die->GetOffset(), dst_die->GetOffset());
+            }
+            
+            Type *src_child_type = m_die_to_type[src_die];
+            if (src_child_type)
+            {
+                if (log)
+                    log->Printf ("uniquing type %p (uid=0x%llx) from 0x%8.8x for 0x%8.8x\n", src_child_type, src_child_type->GetID(), src_die->GetOffset(), dst_die->GetOffset());
+                m_die_to_type[dst_die] = src_child_type;
+            }
+            else
+            {
+                if (log)
+                    log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found\n", src_die->GetOffset(), dst_die->GetOffset());
+            }
+        }
+        return true;
+    }
+    else
+    {
+        if (log)
+            log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x has %u methods and 0x%8.8x has %u",
+                        src_class_die->GetOffset(),
+                        dst_class_die->GetOffset(),
+                        src_die->GetOffset(),
+                        src_size,
+                        dst_die->GetOffset(),
+                        dst_size);
+    }
+    return false;
+}
+
+TypeSP
+SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
+{
+    TypeSP type_sp;
+
+    if (type_is_new_ptr)
+        *type_is_new_ptr = false;
+
+#if defined(LLDB_CONFIGURATION_DEBUG) or defined(LLDB_CONFIGURATION_RELEASE)
+    static DIEStack g_die_stack;
+    DIEStack::ScopedPopper scoped_die_logger(g_die_stack);
+#endif
+
+    AccessType accessibility = eAccessNone;
+    if (die != NULL)
+    {
+        LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+        if (log)
+        {
+            const DWARFDebugInfoEntry *context_die;
+            clang::DeclContext *context = GetClangDeclContextContainingDIE (dwarf_cu, die, &context_die);
+            
+            GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')", 
+                        die->GetOffset(),
+                        context,
+                        context_die->GetOffset(),
+                        DW_TAG_value_to_name(die->Tag()), 
+                        die->GetName(this, dwarf_cu));
+            
+#if defined(LLDB_CONFIGURATION_DEBUG) or defined(LLDB_CONFIGURATION_RELEASE)
+            scoped_die_logger.Push (dwarf_cu, die);
+            g_die_stack.LogDIEs(log.get(), this);
+#endif
+        }
+//
+//        LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+//        if (log && dwarf_cu)
+//        {
+//            StreamString s;
+//            die->DumpLocation (this, dwarf_cu, s);
+//            GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
+//            
+//        }
+        
+        Type *type_ptr = m_die_to_type.lookup (die);
+        TypeList* type_list = GetTypeList();
+        if (type_ptr == NULL)
+        {
+            ClangASTContext &ast = GetClangASTContext();
+            if (type_is_new_ptr)
+                *type_is_new_ptr = true;
+
+            const dw_tag_t tag = die->Tag();
+
+            bool is_forward_declaration = false;
+            DWARFDebugInfoEntry::Attributes attributes;
+            const char *type_name_cstr = NULL;
+            ConstString type_name_const_str;
+            Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
+            size_t byte_size = 0;
+            Declaration decl;
+
+            Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
+            clang_type_t clang_type = NULL;
+
+            dw_attr_t attr;
+
+            switch (tag)
+            {
+            case DW_TAG_base_type:
+            case DW_TAG_pointer_type:
+            case DW_TAG_reference_type:
+            case DW_TAG_rvalue_reference_type:
+            case DW_TAG_typedef:
+            case DW_TAG_const_type:
+            case DW_TAG_restrict_type:
+            case DW_TAG_volatile_type:
+            case DW_TAG_unspecified_type:
+                {
+                    // Set a bit that lets us know that we are currently parsing this
+                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
+
+                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
+                    uint32_t encoding = 0;
+                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
+
+                    if (num_attributes > 0)
+                    {
+                        uint32_t i;
+                        for (i=0; i<num_attributes; ++i)
+                        {
+                            attr = attributes.AttributeAtIndex(i);
+                            DWARFFormValue form_value;
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                switch (attr)
+                                {
+                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                                case DW_AT_name:
+                                    
+                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
+                                    // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
+                                    // include the "&"...
+                                    if (tag == DW_TAG_reference_type)
+                                    {
+                                        if (strchr (type_name_cstr, '&') == NULL)
+                                            type_name_cstr = NULL;
+                                    }
+                                    if (type_name_cstr)
+                                        type_name_const_str.SetCString(type_name_cstr);
+                                    break;
+                                case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
+                                case DW_AT_encoding:    encoding = form_value.Unsigned(); break;
+                                case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
+                                default:
+                                case DW_AT_sibling:
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\") type => 0x%8.8x\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
+
+                    switch (tag)
+                    {
+                    default:
+                        break;
+
+                    case DW_TAG_unspecified_type:
+                        if (strcmp(type_name_cstr, "nullptr_t") == 0)
+                        {
+                            resolve_state = Type::eResolveStateFull;
+                            clang_type = ast.getASTContext()->NullPtrTy.getAsOpaquePtr();
+                            break;
+                        }
+                        // Fall through to base type below in case we can handle the type there...
+
+                    case DW_TAG_base_type:
+                        resolve_state = Type::eResolveStateFull;
+                        clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, 
+                                                                                   encoding, 
+                                                                                   byte_size * 8);
+                        break;
+
+                    case DW_TAG_pointer_type:           encoding_data_type = Type::eEncodingIsPointerUID;           break;
+                    case DW_TAG_reference_type:         encoding_data_type = Type::eEncodingIsLValueReferenceUID;   break;
+                    case DW_TAG_rvalue_reference_type:  encoding_data_type = Type::eEncodingIsRValueReferenceUID;   break;
+                    case DW_TAG_typedef:                encoding_data_type = Type::eEncodingIsTypedefUID;           break;
+                    case DW_TAG_const_type:             encoding_data_type = Type::eEncodingIsConstUID;             break;
+                    case DW_TAG_restrict_type:          encoding_data_type = Type::eEncodingIsRestrictUID;          break;
+                    case DW_TAG_volatile_type:          encoding_data_type = Type::eEncodingIsVolatileUID;          break;
+                    }
+
+                    if (clang_type == NULL && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID))
+                    {
+                        if (type_name_cstr != NULL && sc.comp_unit != NULL && 
+                            (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
+                        {
+                            static ConstString g_objc_type_name_id("id");
+                            static ConstString g_objc_type_name_Class("Class");
+                            static ConstString g_objc_type_name_selector("SEL");
+                            
+                            if (type_name_const_str == g_objc_type_name_id)
+                            {
+                                if (log)
+                                    GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.", 
+                                                                              die->GetOffset(), 
+                                                                              DW_TAG_value_to_name(die->Tag()), 
+                                                                              die->GetName(this, dwarf_cu));
+                                clang_type = ast.GetBuiltInType_objc_id();
+                                encoding_data_type = Type::eEncodingIsUID;
+                                encoding_uid = LLDB_INVALID_UID;
+                                resolve_state = Type::eResolveStateFull;
+
+                            }
+                            else if (type_name_const_str == g_objc_type_name_Class)
+                            {
+                                if (log)
+                                    GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.", 
+                                                                              die->GetOffset(), 
+                                                                              DW_TAG_value_to_name(die->Tag()), 
+                                                                              die->GetName(this, dwarf_cu));
+                                clang_type = ast.GetBuiltInType_objc_Class();
+                                encoding_data_type = Type::eEncodingIsUID;
+                                encoding_uid = LLDB_INVALID_UID;
+                                resolve_state = Type::eResolveStateFull;
+                            }
+                            else if (type_name_const_str == g_objc_type_name_selector)
+                            {
+                                if (log)
+                                    GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.", 
+                                                                              die->GetOffset(), 
+                                                                              DW_TAG_value_to_name(die->Tag()), 
+                                                                              die->GetName(this, dwarf_cu));
+                                clang_type = ast.GetBuiltInType_objc_selector();
+                                encoding_data_type = Type::eEncodingIsUID;
+                                encoding_uid = LLDB_INVALID_UID;
+                                resolve_state = Type::eResolveStateFull;
+                            }
+                        }
+                    }
+                        
+                    type_sp.reset( new Type (MakeUserID(die->GetOffset()),
+                                             this, 
+                                             type_name_const_str, 
+                                             byte_size, 
+                                             NULL, 
+                                             encoding_uid, 
+                                             encoding_data_type, 
+                                             &decl, 
+                                             clang_type, 
+                                             resolve_state));
+                    
+                    m_die_to_type[die] = type_sp.get();
+
+//                  Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
+//                  if (encoding_type != NULL)
+//                  {
+//                      if (encoding_type != DIE_IS_BEING_PARSED)
+//                          type_sp->SetEncodingType(encoding_type);
+//                      else
+//                          m_indirect_fixups.push_back(type_sp.get());
+//                  }
+                }
+                break;
+
+            case DW_TAG_structure_type:
+            case DW_TAG_union_type:
+            case DW_TAG_class_type:
+                {
+                    // Set a bit that lets us know that we are currently parsing this
+                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
+                    bool byte_size_valid = false;
+
+                    LanguageType class_language = eLanguageTypeUnknown;
+                    bool is_complete_objc_class = false;
+                    //bool struct_is_class = false;
+                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
+                    if (num_attributes > 0)
+                    {
+                        uint32_t i;
+                        for (i=0; i<num_attributes; ++i)
+                        {
+                            attr = attributes.AttributeAtIndex(i);
+                            DWARFFormValue form_value;
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                switch (attr)
+                                {
+                                case DW_AT_decl_file:
+                                    if (dwarf_cu->DW_AT_decl_file_attributes_are_invalid())
+									{
+										// llvm-gcc outputs invalid DW_AT_decl_file attributes that always
+										// point to the compile unit file, so we clear this invalid value
+										// so that we can still unique types efficiently.
+                                        decl.SetFile(FileSpec ("<invalid>", false));
+									}
+                                    else
+                                        decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); 
+                                    break;
+
+                                case DW_AT_decl_line:
+                                    decl.SetLine(form_value.Unsigned()); 
+                                    break;
+
+                                case DW_AT_decl_column: 
+                                    decl.SetColumn(form_value.Unsigned()); 
+                                    break;
+
+                                case DW_AT_name:
+                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
+                                    type_name_const_str.SetCString(type_name_cstr);
+                                    break;
+
+                                case DW_AT_byte_size:   
+                                    byte_size = form_value.Unsigned(); 
+                                    byte_size_valid = true;
+                                    break;
+
+                                case DW_AT_accessibility: 
+                                    accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); 
+                                    break;
+
+                                case DW_AT_declaration: 
+                                    is_forward_declaration = form_value.Unsigned() != 0; 
+                                    break;
+
+                                case DW_AT_APPLE_runtime_class: 
+                                    class_language = (LanguageType)form_value.Signed(); 
+                                    break;
+
+                                case DW_AT_APPLE_objc_complete_type:
+                                    is_complete_objc_class = form_value.Signed(); 
+                                    break;
+                                        
+                                case DW_AT_allocated:
+                                case DW_AT_associated:
+                                case DW_AT_data_location:
+                                case DW_AT_description:
+                                case DW_AT_start_scope:
+                                case DW_AT_visibility:
+                                default:
+                                case DW_AT_sibling:
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    UniqueDWARFASTType unique_ast_entry;
+
+                    // Only try and unique the type if it has a name. 
+                    if (type_name_const_str &&
+                        GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
+                                                         this,
+                                                         dwarf_cu,
+                                                         die,
+                                                         decl,
+                                                         byte_size_valid ? byte_size : -1,
+                                                         unique_ast_entry))
+                    {
+                        // We have already parsed this type or from another 
+                        // compile unit. GCC loves to use the "one definition
+                        // rule" which can result in multiple definitions
+                        // of the same class over and over in each compile
+                        // unit.
+                        type_sp = unique_ast_entry.m_type_sp;
+                        if (type_sp)
+                        {
+                            m_die_to_type[die] = type_sp.get();
+                            return type_sp;
+                        }
+                    }
+                    
+                    DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
+
+                    int tag_decl_kind = -1;
+                    AccessType default_accessibility = eAccessNone;
+                    if (tag == DW_TAG_structure_type)
+                    {
+                        tag_decl_kind = clang::TTK_Struct;
+                        default_accessibility = eAccessPublic;
+                    }
+                    else if (tag == DW_TAG_union_type)
+                    {
+                        tag_decl_kind = clang::TTK_Union;
+                        default_accessibility = eAccessPublic;
+                    }
+                    else if (tag == DW_TAG_class_type)
+                    {
+                        tag_decl_kind = clang::TTK_Class;
+                        default_accessibility = eAccessPrivate;
+                    }
+                    
+                    if (byte_size_valid && byte_size == 0 && type_name_cstr &&
+                        die->HasChildren() == false && 
+                        sc.comp_unit->GetLanguage() == eLanguageTypeObjC)
+                    {
+                        // Work around an issue with clang at the moment where
+                        // forward declarations for objective C classes are emitted
+                        // as:
+                        //  DW_TAG_structure_type [2]  
+                        //  DW_AT_name( "ForwardObjcClass" )
+                        //  DW_AT_byte_size( 0x00 )
+                        //  DW_AT_decl_file( "..." )
+                        //  DW_AT_decl_line( 1 )
+                        //
+                        // Note that there is no DW_AT_declaration and there are
+                        // no children, and the byte size is zero.
+                        is_forward_declaration = true;
+                    }
+
+                    if (class_language == eLanguageTypeObjC ||
+                        class_language == eLanguageTypeObjC_plus_plus)
+                    {
+                        if (!is_complete_objc_class && Supports_DW_AT_APPLE_objc_complete_type(dwarf_cu))
+                        {
+                            // We have a valid eSymbolTypeObjCClass class symbol whose
+                            // name matches the current objective C class that we
+                            // are trying to find and this DIE isn't the complete
+                            // definition (we checked is_complete_objc_class above and
+                            // know it is false), so the real definition is in here somewhere
+                            type_sp = FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
+
+                            if (!type_sp && GetDebugMapSymfile ())
+                            {
+                                // We weren't able to find a full declaration in
+                                // this DWARF, see if we have a declaration anywhere    
+                                // else...
+                                type_sp = m_debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
+                            }
+                            
+                            if (type_sp)
+                            {
+                                if (log)
+                                {
+                                    GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                                              "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8llx", 
+                                                                              this,
+                                                                              die->GetOffset(), 
+                                                                              DW_TAG_value_to_name(tag),
+                                                                              type_name_cstr,
+                                                                              type_sp->GetID());
+                                }
+                                
+                                // We found a real definition for this type elsewhere
+                                // so lets use it and cache the fact that we found
+                                // a complete type for this die
+                                m_die_to_type[die] = type_sp.get();
+                                return type_sp;
+                            }
+                        }
+                    }
+                    
+
+                    if (is_forward_declaration)
+                    {
+                        // We have a forward declaration to a type and we need
+                        // to try and find a full declaration. We look in the
+                        // current type index just in case we have a forward
+                        // declaration followed by an actual declarations in the
+                        // DWARF. If this fails, we need to look elsewhere...
+                        if (log)
+                        {
+                            GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                                      "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, trying to find complete type", 
+                                                                      this,
+                                                                      die->GetOffset(), 
+                                                                      DW_TAG_value_to_name(tag),
+                                                                      type_name_cstr);
+                        }
+                    
+                        DWARFDeclContext die_decl_ctx;
+                        die->GetDWARFDeclContext(this, dwarf_cu, die_decl_ctx);
+
+                        //type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
+                        type_sp = FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
+
+                        if (!type_sp && GetDebugMapSymfile ())
+                        {
+                            // We weren't able to find a full declaration in
+                            // this DWARF, see if we have a declaration anywhere    
+                            // else...
+                            type_sp = m_debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
+                        }
+
+                        if (type_sp)
+                        {
+                            if (log)
+                            {
+                                GetObjectFile()->GetModule()->LogMessage (log.get(),
+                                                                          "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8llx", 
+                                                                          this,
+                                                                          die->GetOffset(), 
+                                                                          DW_TAG_value_to_name(tag),
+                                                                          type_name_cstr,
+                                                                          type_sp->GetID());
+                            }
+
+                            // We found a real definition for this type elsewhere
+                            // so lets use it and cache the fact that we found
+                            // a complete type for this die
+                            m_die_to_type[die] = type_sp.get();
+                            return type_sp;
+                        }
+                    }
+                    assert (tag_decl_kind != -1);
+                    bool clang_type_was_created = false;
+                    clang_type = m_forward_decl_die_to_clang_type.lookup (die);
+                    if (clang_type == NULL)
+                    {
+                        const DWARFDebugInfoEntry *decl_ctx_die;
+                        
+                        clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
+                        if (accessibility == eAccessNone && decl_ctx)
+                        {
+                            // Check the decl context that contains this class/struct/union.
+                            // If it is a class we must give it an accessability.
+                            const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
+                            if (DeclKindIsCXXClass (containing_decl_kind))
+                                accessibility = default_accessibility;
+                        }
+
+                        if (type_name_cstr && strchr (type_name_cstr, '<'))
+                        {
+                            ClangASTContext::TemplateParameterInfos template_param_infos;
+                            if (ParseTemplateParameterInfos (dwarf_cu, die, template_param_infos))
+                            {
+                                clang::ClassTemplateDecl *class_template_decl = ParseClassTemplateDecl (decl_ctx,
+                                                                                                        accessibility,
+                                                                                                        type_name_cstr,
+                                                                                                        tag_decl_kind,
+                                                                                                        template_param_infos);
+                            
+                                clang::ClassTemplateSpecializationDecl *class_specialization_decl = ast.CreateClassTemplateSpecializationDecl (decl_ctx,
+                                                                                                                                               class_template_decl,
+                                                                                                                                               tag_decl_kind,
+                                                                                                                                               template_param_infos);
+                                clang_type = ast.CreateClassTemplateSpecializationType (class_specialization_decl);
+                                clang_type_was_created = true;
+                                
+                                GetClangASTContext().SetMetadataAsUserID ((uintptr_t)class_template_decl, MakeUserID(die->GetOffset()));
+                                GetClangASTContext().SetMetadataAsUserID ((uintptr_t)class_specialization_decl, MakeUserID(die->GetOffset()));
+                            }
+                        }
+
+                        if (!clang_type_was_created)
+                        {
+                            clang_type_was_created = true;
+                            ClangASTMetadata metadata;
+                            metadata.SetUserID(MakeUserID(die->GetOffset()));
+                            clang_type = ast.CreateRecordType (decl_ctx, 
+                                                               accessibility, 
+                                                               type_name_cstr, 
+                                                               tag_decl_kind, 
+                                                               class_language,
+                                                               &metadata);
+                        }
+                    }
+
+                    // Store a forward declaration to this class type in case any 
+                    // parameters in any class methods need it for the clang 
+                    // types for function prototypes.
+                    LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
+                    type_sp.reset (new Type (MakeUserID(die->GetOffset()), 
+                                             this, 
+                                             type_name_const_str, 
+                                             byte_size, 
+                                             NULL, 
+                                             LLDB_INVALID_UID, 
+                                             Type::eEncodingIsUID, 
+                                             &decl, 
+                                             clang_type, 
+                                             Type::eResolveStateForward));
+                    
+                    type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
+
+
+                    // Add our type to the unique type map so we don't
+                    // end up creating many copies of the same type over
+                    // and over in the ASTContext for our module
+                    unique_ast_entry.m_type_sp = type_sp;
+                    unique_ast_entry.m_symfile = this;
+                    unique_ast_entry.m_cu = dwarf_cu;
+                    unique_ast_entry.m_die = die;
+                    unique_ast_entry.m_declaration = decl;
+                    unique_ast_entry.m_byte_size = byte_size;
+                    GetUniqueDWARFASTTypeMap().Insert (type_name_const_str, 
+                                                       unique_ast_entry);
+                    
+                    if (!is_forward_declaration)
+                    {
+                        // Always start the definition for a class type so that
+                        // if the class has child classes or types that require
+                        // the class to be created for use as their decl contexts
+                        // the class will be ready to accept these child definitions.
+                        if (die->HasChildren() == false)
+                        {
+                            // No children for this struct/union/class, lets finish it
+                            ast.StartTagDeclarationDefinition (clang_type);
+                            ast.CompleteTagDeclarationDefinition (clang_type);
+                            
+                            if (tag == DW_TAG_structure_type) // this only applies in C
+                            {
+                                clang::QualType qual_type = clang::QualType::getFromOpaquePtr (clang_type);
+                                const clang::RecordType *record_type = qual_type->getAs<clang::RecordType> ();
+                                
+                                if (record_type)
+                                {
+                                    clang::RecordDecl *record_decl = record_type->getDecl();
+                                    
+                                    if (record_decl)
+                                    {
+                                        LayoutInfo layout_info;
+                                        
+                                        layout_info.alignment = 0;
+                                        layout_info.bit_size = 0;
+                                        
+                                        m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
+                                    }
+                                }
+                            }
+                        }
+                        else if (clang_type_was_created)
+                        {
+                            // Start the definition if the class is not objective C since
+                            // the underlying decls respond to isCompleteDefinition(). Objective
+                            // C decls dont' respond to isCompleteDefinition() so we can't
+                            // start the declaration definition right away. For C++ classs/union/structs
+                            // we want to start the definition in case the class is needed as the
+                            // declaration context for a contained class or type without the need
+                            // to complete that type..
+                            
+                            if (class_language != eLanguageTypeObjC &&
+                                class_language != eLanguageTypeObjC_plus_plus)
+                                ast.StartTagDeclarationDefinition (clang_type);
+
+                            // Leave this as a forward declaration until we need
+                            // to know the details of the type. lldb_private::Type
+                            // will automatically call the SymbolFile virtual function
+                            // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
+                            // When the definition needs to be defined.
+                            m_forward_decl_die_to_clang_type[die] = clang_type;
+                            m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
+                            ClangASTContext::SetHasExternalStorage (clang_type, true);
+                        }
+                    }
+                    
+                }
+                break;
+
+            case DW_TAG_enumeration_type:
+                {
+                    // Set a bit that lets us know that we are currently parsing this
+                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
+
+                    lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
+
+                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
+                    if (num_attributes > 0)
+                    {
+                        uint32_t i;
+
+                        for (i=0; i<num_attributes; ++i)
+                        {
+                            attr = attributes.AttributeAtIndex(i);
+                            DWARFFormValue form_value;
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                switch (attr)
+                                {
+                                case DW_AT_decl_file:       decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                                case DW_AT_decl_line:       decl.SetLine(form_value.Unsigned()); break;
+                                case DW_AT_decl_column:     decl.SetColumn(form_value.Unsigned()); break;
+                                case DW_AT_name:
+                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
+                                    type_name_const_str.SetCString(type_name_cstr);
+                                    break;
+                                case DW_AT_type:            encoding_uid = form_value.Reference(dwarf_cu); break;
+                                case DW_AT_byte_size:       byte_size = form_value.Unsigned(); break;
+                                case DW_AT_accessibility:   break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
+                                case DW_AT_declaration:     break; //is_forward_declaration = form_value.Unsigned() != 0; break;
+                                case DW_AT_allocated:
+                                case DW_AT_associated:
+                                case DW_AT_bit_stride:
+                                case DW_AT_byte_stride:
+                                case DW_AT_data_location:
+                                case DW_AT_description:
+                                case DW_AT_start_scope:
+                                case DW_AT_visibility:
+                                case DW_AT_specification:
+                                case DW_AT_abstract_origin:
+                                case DW_AT_sibling:
+                                    break;
+                                }
+                            }
+                        }
+
+                        DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
+
+                        clang_type_t enumerator_clang_type = NULL;
+                        clang_type = m_forward_decl_die_to_clang_type.lookup (die);
+                        if (clang_type == NULL)
+                        {
+                            enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, 
+                                                                                                  DW_ATE_signed, 
+                                                                                                  byte_size * 8);
+                            clang_type = ast.CreateEnumerationType (type_name_cstr, 
+                                                                    GetClangDeclContextContainingDIE (dwarf_cu, die, NULL), 
+                                                                    decl,
+                                                                    enumerator_clang_type);
+                        }
+                        else
+                        {
+                            enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
+                            assert (enumerator_clang_type != NULL);
+                        }
+
+                        LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
+                        
+                        type_sp.reset( new Type (MakeUserID(die->GetOffset()), 
+                                                 this, 
+                                                 type_name_const_str, 
+                                                 byte_size, 
+                                                 NULL, 
+                                                 encoding_uid, 
+                                                 Type::eEncodingIsUID,
+                                                 &decl, 
+                                                 clang_type, 
+                                                 Type::eResolveStateForward));
+
+                        ast.StartTagDeclarationDefinition (clang_type);
+                        if (die->HasChildren())
+                        {
+                            SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
+                            ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
+                        }
+                        ast.CompleteTagDeclarationDefinition (clang_type);
+                    }
+                }
+                break;
+
+            case DW_TAG_inlined_subroutine:
+            case DW_TAG_subprogram:
+            case DW_TAG_subroutine_type:
+                {
+                    // Set a bit that lets us know that we are currently parsing this
+                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
+
+                    //const char *mangled = NULL;
+                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
+                    bool is_variadic = false;
+                    bool is_inline = false;
+                    bool is_static = false;
+                    bool is_virtual = false;
+                    bool is_explicit = false;
+                    bool is_artificial = false;
+                    dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
+                    dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
+                    dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
+
+                    unsigned type_quals = 0;
+                    clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
+
+
+                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
+                    if (num_attributes > 0)
+                    {
+                        uint32_t i;
+                        for (i=0; i<num_attributes; ++i)
+                        {
+                            attr = attributes.AttributeAtIndex(i);
+                            DWARFFormValue form_value;
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                switch (attr)
+                                {
+                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                                case DW_AT_name:
+                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
+                                    type_name_const_str.SetCString(type_name_cstr);
+                                    break;
+
+                                case DW_AT_MIPS_linkage_name:   break; // mangled = form_value.AsCString(&get_debug_str_data()); break;
+                                case DW_AT_type:                type_die_offset = form_value.Reference(dwarf_cu); break;
+                                case DW_AT_accessibility:       accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
+                                case DW_AT_declaration:         break; // is_forward_declaration = form_value.Unsigned() != 0; break;
+                                case DW_AT_inline:              is_inline = form_value.Unsigned() != 0; break;
+                                case DW_AT_virtuality:          is_virtual = form_value.Unsigned() != 0;  break;
+                                case DW_AT_explicit:            is_explicit = form_value.Unsigned() != 0;  break; 
+                                case DW_AT_artificial:          is_artificial = form_value.Unsigned() != 0;  break; 
+                                        
+
+                                case DW_AT_external:
+                                    if (form_value.Unsigned())
+                                    {
+                                        if (storage == clang::SC_None)
+                                            storage = clang::SC_Extern;
+                                        else
+                                            storage = clang::SC_PrivateExtern;
+                                    }
+                                    break;
+
+                                case DW_AT_specification:
+                                    specification_die_offset = form_value.Reference(dwarf_cu);
+                                    break;
+
+                                case DW_AT_abstract_origin:
+                                    abstract_origin_die_offset = form_value.Reference(dwarf_cu);
+                                    break;
+
+                                case DW_AT_object_pointer:
+                                    object_pointer_die_offset = form_value.Reference(dwarf_cu);
+                                    break;
+
+                                case DW_AT_allocated:
+                                case DW_AT_associated:
+                                case DW_AT_address_class:
+                                case DW_AT_calling_convention:
+                                case DW_AT_data_location:
+                                case DW_AT_elemental:
+                                case DW_AT_entry_pc:
+                                case DW_AT_frame_base:
+                                case DW_AT_high_pc:
+                                case DW_AT_low_pc:
+                                case DW_AT_prototyped:
+                                case DW_AT_pure:
+                                case DW_AT_ranges:
+                                case DW_AT_recursive:
+                                case DW_AT_return_addr:
+                                case DW_AT_segment:
+                                case DW_AT_start_scope:
+                                case DW_AT_static_link:
+                                case DW_AT_trampoline:
+                                case DW_AT_visibility:
+                                case DW_AT_vtable_elem_location:
+                                case DW_AT_description:
+                                case DW_AT_sibling:
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    std::string object_pointer_name;
+                    if (object_pointer_die_offset != DW_INVALID_OFFSET)
+                    {
+                        // Get the name from the object pointer die
+                        StreamString s;
+                        if (DWARFDebugInfoEntry::GetName (this, dwarf_cu, object_pointer_die_offset, s))
+                        {
+                            object_pointer_name.assign(s.GetData());
+                        }
+                    }
+                    
+                    DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
+
+                    clang_type_t return_clang_type = NULL;
+                    Type *func_type = NULL;
+                    
+                    if (type_die_offset != DW_INVALID_OFFSET)
+                        func_type = ResolveTypeUID(type_die_offset);
+
+                    if (func_type)
+                        return_clang_type = func_type->GetClangForwardType();
+                    else
+                        return_clang_type = ast.GetBuiltInType_void();
+
+
+                    std::vector<clang_type_t> function_param_types;
+                    std::vector<clang::ParmVarDecl*> function_param_decls;
+
+                    // Parse the function children for the parameters
+                    
+                    const DWARFDebugInfoEntry *decl_ctx_die = NULL;
+                    clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
+                    const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
+
+                    const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
+                    // Start off static. This will be set to false in ParseChildParameters(...)
+                    // if we find a "this" paramters as the first parameter
+                    if (is_cxx_method)
+                        is_static = true;
+                    ClangASTContext::TemplateParameterInfos template_param_infos;
+
+                    if (die->HasChildren())
+                    {
+                        bool skip_artificial = true;
+                        ParseChildParameters (sc,
+                                              containing_decl_ctx,
+                                              dwarf_cu,
+                                              die,
+                                              skip_artificial,
+                                              is_static,
+                                              type_list,
+                                              function_param_types,
+                                              function_param_decls,
+                                              type_quals,
+                                              template_param_infos);
+                    }
+
+                    // clang_type will get the function prototype clang type after this call
+                    clang_type = ast.CreateFunctionType (return_clang_type, 
+<<<<<<< .working
+                                                         function_param_types.size() == 0 ? NULL : &function_param_types[0], 
+=======
+                                                         function_param_types.data(),
+>>>>>>> .merge-right.r167119
+                                                         function_param_types.size(), 
+                                                         is_variadic, 
+                                                         type_quals);
+                    
+                    if (type_name_cstr)
+                    {
+                        bool type_handled = false;
+                        if (tag == DW_TAG_subprogram)
+                        {
+                            ConstString class_name;
+                            ConstString class_name_no_category;
+                            if (ObjCLanguageRuntime::ParseMethodName (type_name_cstr, &class_name, NULL, NULL, &class_name_no_category))
+                            {
+                                // Use the class name with no category if there is one
+                                if (class_name_no_category)
+                                    class_name = class_name_no_category;
+
+                                SymbolContext empty_sc;
+                                clang_type_t class_opaque_type = NULL;
+                                if (class_name)
+                                {
+                                    TypeList types;
+                                    TypeSP complete_objc_class_type_sp (FindCompleteObjCDefinitionTypeForDIE (NULL, class_name, false));
+
+                                    if (complete_objc_class_type_sp)
+                                    {
+                                        clang_type_t type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType();
+                                        if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
+                                            class_opaque_type = type_clang_forward_type;
+                                    }
+                                }
+
+                                if (class_opaque_type)
+                                {
+                                    // If accessibility isn't set to anything valid, assume public for 
+                                    // now...
+                                    if (accessibility == eAccessNone)
+                                        accessibility = eAccessPublic;
+
+                                    clang::ObjCMethodDecl *objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type, 
+                                                                                                             type_name_cstr,
+                                                                                                             clang_type,
+                                                                                                             accessibility);
+                                    type_handled = objc_method_decl != NULL;
+                                    if (type_handled)
+                                    {
+                                        LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
+                                        GetClangASTContext().SetMetadataAsUserID ((uintptr_t)objc_method_decl, MakeUserID(die->GetOffset()));
+                                    }
+                                }
+                            }
+                            else if (is_cxx_method)
+                            {
+                                // Look at the parent of this DIE and see if is is
+                                // a class or struct and see if this is actually a
+                                // C++ method
+                                Type *class_type = ResolveType (dwarf_cu, decl_ctx_die);
+                                if (class_type)
+                                {
+                                    if (class_type->GetID() != MakeUserID(decl_ctx_die->GetOffset()))
+                                    {
+                                        // We uniqued the parent class of this function to another class
+                                        // so we now need to associate all dies under "decl_ctx_die" to
+                                        // DIEs in the DIE for "class_type"...
+                                        DWARFCompileUnitSP class_type_cu_sp;
+                                        const DWARFDebugInfoEntry *class_type_die = DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
+                                        if (class_type_die)
+                                        {
+                                            if (CopyUniqueClassMethodTypes (class_type,
+                                                                            class_type_cu_sp.get(),
+                                                                            class_type_die,
+                                                                            dwarf_cu,
+                                                                            decl_ctx_die))
+                                            {
+                                                type_ptr = m_die_to_type[die];
+                                                if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
+                                                {
+                                                    type_sp = type_ptr->shared_from_this();
+                                                    break;
+                                                }
+                                            }
+                                        }
+                                    }
+                                    
+                                    if (specification_die_offset != DW_INVALID_OFFSET)
+                                    {
+                                        // We have a specification which we are going to base our function
+                                        // prototype off of, so we need this type to be completed so that the
+                                        // m_die_to_decl_ctx for the method in the specification has a valid
+                                        // clang decl context.
+                                        class_type->GetClangForwardType();
+                                        // If we have a specification, then the function type should have been
+                                        // made with the specification and not with this die.
+                                        DWARFCompileUnitSP spec_cu_sp;
+                                        const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
+                                        clang::DeclContext *spec_clang_decl_ctx = GetClangDeclContextForDIE (sc, dwarf_cu, spec_die);
+                                        if (spec_clang_decl_ctx)
+                                        {
+                                            LinkDeclContextToDIE(spec_clang_decl_ctx, die);
+                                        }
+                                        else
+                                        {
+                                            GetObjectFile()->GetModule()->ReportWarning ("0x%8.8llx: DW_AT_specification(0x%8.8x) has no decl\n", 
+                                                                                         MakeUserID(die->GetOffset()), 
+                                                                                         specification_die_offset);
+                                        }
+                                        type_handled = true;
+                                    }
+                                    else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
+                                    {
+                                        // We have a specification which we are going to base our function
+                                        // prototype off of, so we need this type to be completed so that the
+                                        // m_die_to_decl_ctx for the method in the abstract origin has a valid
+                                        // clang decl context.
+                                        class_type->GetClangForwardType();
+
+                                        DWARFCompileUnitSP abs_cu_sp;
+                                        const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
+                                        clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE (sc, dwarf_cu, abs_die);
+                                        if (abs_clang_decl_ctx)
+                                        {
+                                            LinkDeclContextToDIE (abs_clang_decl_ctx, die);
+                                        }
+                                        else
+                                        {
+                                            GetObjectFile()->GetModule()->ReportWarning ("0x%8.8llx: DW_AT_abstract_origin(0x%8.8x) has no decl\n", 
+                                                                                         MakeUserID(die->GetOffset()), 
+                                                                                         abstract_origin_die_offset);
+                                        }
+                                        type_handled = true;
+                                    }
+                                    else
+                                    {
+                                        clang_type_t class_opaque_type = class_type->GetClangForwardType();
+                                        if (ClangASTContext::IsCXXClassType (class_opaque_type))
+                                        {
+                                            if (ClangASTContext::IsBeingDefined (class_opaque_type))
+                                            {
+                                                // Neither GCC 4.2 nor clang++ currently set a valid accessibility
+                                                // in the DWARF for C++ methods... Default to public for now...
+                                                if (accessibility == eAccessNone)
+                                                    accessibility = eAccessPublic;
+                                                
+                                                if (!is_static && !die->HasChildren())
+                                                {
+                                                    // We have a C++ member function with no children (this pointer!)
+                                                    // and clang will get mad if we try and make a function that isn't
+                                                    // well formed in the DWARF, so we will just skip it...
+                                                    type_handled = true;
+                                                }
+                                                else
+                                                {
+                                                    clang::CXXMethodDecl *cxx_method_decl;
+                                                    // REMOVE THE CRASH DESCRIPTION BELOW
+                                                    Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8llx from %s/%s", 
+                                                                                         type_name_cstr, 
+                                                                                         class_type->GetName().GetCString(),
+                                                                                         MakeUserID(die->GetOffset()),
+                                                                                         m_obj_file->GetFileSpec().GetDirectory().GetCString(),
+                                                                                         m_obj_file->GetFileSpec().GetFilename().GetCString());
+
+                                                    const bool is_attr_used = false;
+                                                    
+                                                    cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type, 
+                                                                                                    type_name_cstr,
+                                                                                                    clang_type,
+                                                                                                    accessibility,
+                                                                                                    is_virtual,
+                                                                                                    is_static,
+                                                                                                    is_inline,
+                                                                                                    is_explicit,
+                                                                                                    is_attr_used,
+                                                                                                    is_artificial);
+                                                    
+                                                    type_handled = cxx_method_decl != NULL;
+
+                                                    if (type_handled)
+                                                    {
+                                                        LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
+
+                                                        Host::SetCrashDescription (NULL);
+
+                                                        
+                                                        ClangASTMetadata metadata;
+                                                        metadata.SetUserID(MakeUserID(die->GetOffset()));
+                                                        
+                                                        if (!object_pointer_name.empty())
+                                                        {
+                                                            metadata.SetObjectPtrName(object_pointer_name.c_str());
+                                                            if (log)
+                                                                log->Printf ("Setting object pointer name: %s on method object 0x%ld.\n",
+                                                                             object_pointer_name.c_str(),
+                                                                             (uintptr_t) cxx_method_decl);
+                                                        }
+                                                        GetClangASTContext().SetMetadata ((uintptr_t)cxx_method_decl, metadata);
+                                                    }
+                                                }
+                                            }
+                                            else
+                                            {
+                                                // We were asked to parse the type for a method in a class, yet the
+                                                // class hasn't been asked to complete itself through the 
+                                                // clang::ExternalASTSource protocol, so we need to just have the
+                                                // class complete itself and do things the right way, then our 
+                                                // DIE should then have an entry in the m_die_to_type map. First 
+                                                // we need to modify the m_die_to_type so it doesn't think we are 
+                                                // trying to parse this DIE anymore...
+                                                m_die_to_type[die] = NULL;
+                                                
+                                                // Now we get the full type to force our class type to complete itself 
+                                                // using the clang::ExternalASTSource protocol which will parse all 
+                                                // base classes and all methods (including the method for this DIE).
+                                                class_type->GetClangFullType();
+
+                                                // The type for this DIE should have been filled in the function call above
+                                                type_ptr = m_die_to_type[die];
+                                                if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
+                                                {
+                                                    type_sp = type_ptr->shared_from_this();
+                                                    break;
+                                                }
+                                                
+                                                // FIXME This is fixing some even uglier behavior but we really need to
+                                                // uniq the methods of each class as well as the class itself.
+                                                // <rdar://problem/11240464>
+                                                type_handled = true;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                            
+                        if (!type_handled)
+                        {
+                            // We just have a function that isn't part of a class
+                            clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (containing_decl_ctx,
+                                                                                                type_name_cstr, 
+                                                                                                clang_type, 
+                                                                                                storage, 
+                                                                                                is_inline);
+
+//                            if (template_param_infos.GetSize() > 0)
+//                            {
+//                                clang::FunctionTemplateDecl *func_template_decl = ast.CreateFunctionTemplateDecl (containing_decl_ctx,
+//                                                                                                                  function_decl,
+//                                                                                                                  type_name_cstr, 
+//                                                                                                                  template_param_infos);
+//                                
+//                                ast.CreateFunctionTemplateSpecializationInfo (function_decl,
+//                                                                              func_template_decl,
+//                                                                              template_param_infos);
+//                            }
+                            // Add the decl to our DIE to decl context map
+                            assert (function_decl);
+                            LinkDeclContextToDIE(function_decl, die);
+                            if (!function_param_decls.empty())
+                                ast.SetFunctionParameters (function_decl, 
+                                                           &function_param_decls.front(), 
+                                                           function_param_decls.size());
+                            
+                            ClangASTMetadata metadata;
+                            metadata.SetUserID(MakeUserID(die->GetOffset()));
+                            
+                            if (!object_pointer_name.empty())
+                            {
+                                metadata.SetObjectPtrName(object_pointer_name.c_str());
+                                if (log)
+                                    log->Printf ("Setting object pointer name: %s on function object 0x%ld.\n",
+                                                 object_pointer_name.c_str(),
+                                                 (uintptr_t) function_decl);
+                            }
+                            GetClangASTContext().SetMetadata ((uintptr_t)function_decl, metadata);
+                        }
+                    }
+                    type_sp.reset( new Type (MakeUserID(die->GetOffset()), 
+                                             this, 
+                                             type_name_const_str, 
+                                             0, 
+                                             NULL, 
+                                             LLDB_INVALID_UID, 
+                                             Type::eEncodingIsUID, 
+                                             &decl, 
+                                             clang_type, 
+                                             Type::eResolveStateFull));                    
+                    assert(type_sp.get());
+                }
+                break;
+
+            case DW_TAG_array_type:
+                {
+                    // Set a bit that lets us know that we are currently parsing this
+                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
+
+                    lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
+                    int64_t first_index = 0;
+                    uint32_t byte_stride = 0;
+                    uint32_t bit_stride = 0;
+                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
+
+                    if (num_attributes > 0)
+                    {
+                        uint32_t i;
+                        for (i=0; i<num_attributes; ++i)
+                        {
+                            attr = attributes.AttributeAtIndex(i);
+                            DWARFFormValue form_value;
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                switch (attr)
+                                {
+                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                                case DW_AT_name:
+                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
+                                    type_name_const_str.SetCString(type_name_cstr);
+                                    break;
+
+                                case DW_AT_type:            type_die_offset = form_value.Reference(dwarf_cu); break;
+                                case DW_AT_byte_size:       break; // byte_size = form_value.Unsigned(); break;
+                                case DW_AT_byte_stride:     byte_stride = form_value.Unsigned(); break;
+                                case DW_AT_bit_stride:      bit_stride = form_value.Unsigned(); break;
+                                case DW_AT_accessibility:   break; // accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
+                                case DW_AT_declaration:     break; // is_forward_declaration = form_value.Unsigned() != 0; break;
+                                case DW_AT_allocated:
+                                case DW_AT_associated:
+                                case DW_AT_data_location:
+                                case DW_AT_description:
+                                case DW_AT_ordering:
+                                case DW_AT_start_scope:
+                                case DW_AT_visibility:
+                                case DW_AT_specification:
+                                case DW_AT_abstract_origin:
+                                case DW_AT_sibling:
+                                    break;
+                                }
+                            }
+                        }
+
+                        DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
+
+                        Type *element_type = ResolveTypeUID(type_die_offset);
+
+                        if (element_type)
+                        {
+                            std::vector<uint64_t> element_orders;
+                            ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
+                            if (byte_stride == 0 && bit_stride == 0)
+                                byte_stride = element_type->GetByteSize();
+                            clang_type_t array_element_type = element_type->GetClangForwardType();
+                            uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
+                            uint64_t num_elements = 0;
+                            std::vector<uint64_t>::const_reverse_iterator pos;
+                            std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
+                            for (pos = element_orders.rbegin(); pos != end; ++pos)
+                            {
+                                num_elements = *pos;
+                                clang_type = ast.CreateArrayType (array_element_type, 
+                                                                  num_elements, 
+                                                                  num_elements * array_element_bit_stride);
+                                array_element_type = clang_type;
+                                array_element_bit_stride = array_element_bit_stride * num_elements;
+                            }
+                            ConstString empty_name;
+                            type_sp.reset( new Type (MakeUserID(die->GetOffset()), 
+                                                     this, 
+                                                     empty_name, 
+                                                     array_element_bit_stride / 8, 
+                                                     NULL, 
+                                                     type_die_offset, 
+                                                     Type::eEncodingIsUID, 
+                                                     &decl, 
+                                                     clang_type, 
+                                                     Type::eResolveStateFull));
+                            type_sp->SetEncodingType (element_type);
+                        }
+                    }
+                }
+                break;
+
+            case DW_TAG_ptr_to_member_type:
+                {
+                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
+                    dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
+
+                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
+                    
+                    if (num_attributes > 0) {
+                        uint32_t i;
+                        for (i=0; i<num_attributes; ++i)
+                        {
+                            attr = attributes.AttributeAtIndex(i);
+                            DWARFFormValue form_value;
+                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                            {
+                                switch (attr)
+                                {
+                                    case DW_AT_type:
+                                        type_die_offset = form_value.Reference(dwarf_cu); break;
+                                    case DW_AT_containing_type:
+                                        containing_type_die_offset = form_value.Reference(dwarf_cu); break;
+                                }
+                            }
+                        }
+                        
+                        Type *pointee_type = ResolveTypeUID(type_die_offset);
+                        Type *class_type = ResolveTypeUID(containing_type_die_offset);
+                        
+                        clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
+                        clang_type_t class_clang_type = class_type->GetClangLayoutType();
+
+                        clang_type = ast.CreateMemberPointerType(pointee_clang_type, 
+                                                                 class_clang_type);
+
+                        byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(), 
+                                                                       clang_type) / 8;
+
+                        type_sp.reset( new Type (MakeUserID(die->GetOffset()), 
+                                                 this, 
+                                                 type_name_const_str, 
+                                                 byte_size, 
+                                                 NULL, 
+                                                 LLDB_INVALID_UID, 
+                                                 Type::eEncodingIsUID, 
+                                                 NULL, 
+                                                 clang_type, 
+                                                 Type::eResolveStateForward));
+                    }
+                                            
+                    break;
+                }
+            default:
+                assert(false && "Unhandled type tag!");
+                break;
+            }
+
+            if (type_sp.get())
+            {
+                const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
+                dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
+
+                SymbolContextScope * symbol_context_scope = NULL;
+                if (sc_parent_tag == DW_TAG_compile_unit)
+                {
+                    symbol_context_scope = sc.comp_unit;
+                }
+                else if (sc.function != NULL)
+                {
+                    symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
+                    if (symbol_context_scope == NULL)
+                        symbol_context_scope = sc.function;
+                }
+
+                if (symbol_context_scope != NULL)
+                {
+                    type_sp->SetSymbolContextScope(symbol_context_scope);
+                }
+
+                // We are ready to put this type into the uniqued list up at the module level
+                type_list->Insert (type_sp);
+
+                m_die_to_type[die] = type_sp.get();
+            }
+        }
+        else if (type_ptr != DIE_IS_BEING_PARSED)
+        {
+            type_sp = type_ptr->shared_from_this();
+        }
+    }
+    return type_sp;
+}
+
+size_t
+SymbolFileDWARF::ParseTypes
+(
+    const SymbolContext& sc, 
+    DWARFCompileUnit* dwarf_cu, 
+    const DWARFDebugInfoEntry *die, 
+    bool parse_siblings, 
+    bool parse_children
+)
+{
+    size_t types_added = 0;
+    while (die != NULL)
+    {
+        bool type_is_new = false;
+        if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
+        {
+            if (type_is_new)
+                ++types_added;
+        }
+
+        if (parse_children && die->HasChildren())
+        {
+            if (die->Tag() == DW_TAG_subprogram)
+            {
+                SymbolContext child_sc(sc);
+                child_sc.function = sc.comp_unit->FindFunctionByUID(MakeUserID(die->GetOffset())).get();
+                types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
+            }
+            else
+                types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
+        }
+
+        if (parse_siblings)
+            die = die->GetSibling();
+        else
+            die = NULL;
+    }
+    return types_added;
+}
+
+
+size_t
+SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
+{
+    assert(sc.comp_unit && sc.function);
+    size_t functions_added = 0;
+    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+    if (dwarf_cu)
+    {
+        dw_offset_t function_die_offset = sc.function->GetID();
+        const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
+        if (function_die)
+        {
+            ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0);
+        }
+    }
+
+    return functions_added;
+}
+
+
+size_t
+SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
+{
+    // At least a compile unit must be valid
+    assert(sc.comp_unit);
+    size_t types_added = 0;
+    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+    if (dwarf_cu)
+    {
+        if (sc.function)
+        {
+            dw_offset_t function_die_offset = sc.function->GetID();
+            const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
+            if (func_die && func_die->HasChildren())
+            {
+                types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
+            }
+        }
+        else
+        {
+            const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
+            if (dwarf_cu_die && dwarf_cu_die->HasChildren())
+            {
+                types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
+            }
+        }
+    }
+
+    return types_added;
+}
+
+size_t
+SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
+{
+    if (sc.comp_unit != NULL)
+    {
+        DWARFDebugInfo* info = DebugInfo();
+        if (info == NULL)
+            return 0;
+        
+        uint32_t cu_idx = UINT32_MAX;
+        DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
+
+        if (dwarf_cu == NULL)
+            return 0;
+
+        if (sc.function)
+        {
+            const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
+            
+            dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
+            if (func_lo_pc != DW_INVALID_ADDRESS)
+            {
+                const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
+            
+                // Let all blocks know they have parse all their variables
+                sc.function->GetBlock (false).SetDidParseVariables (true, true);
+                return num_variables;
+            }
+        }
+        else if (sc.comp_unit)
+        {
+            uint32_t vars_added = 0;
+            VariableListSP variables (sc.comp_unit->GetVariableList(false));
+            
+            if (variables.get() == NULL)
+            {
+                variables.reset(new VariableList());
+                sc.comp_unit->SetVariableList(variables);
+
+                DWARFCompileUnit* match_dwarf_cu = NULL;
+                const DWARFDebugInfoEntry* die = NULL;
+                DIEArray die_offsets;
+                if (m_using_apple_tables)
+                {
+                    if (m_apple_names_ap.get())
+                    {
+                        DWARFMappedHash::DIEInfoArray hash_data_array;
+                        if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(), 
+                                                                    dwarf_cu->GetNextCompileUnitOffset(), 
+                                                                    hash_data_array))
+                        {
+                            DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
+                        }
+                    }
+                }
+                else
+                {
+                    // Index if we already haven't to make sure the compile units
+                    // get indexed and make their global DIE index list
+                    if (!m_indexed)
+                        Index ();
+
+                    m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(), 
+                                                                 dwarf_cu->GetNextCompileUnitOffset(), 
+                                                                 die_offsets);
+                }
+
+                const size_t num_matches = die_offsets.size();
+                if (num_matches)
+                {
+                    DWARFDebugInfo* debug_info = DebugInfo();
+                    for (size_t i=0; i<num_matches; ++i)
+                    {
+                        const dw_offset_t die_offset = die_offsets[i];
+                        die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu);
+                        if (die)
+                        {
+                            VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS));
+                            if (var_sp)
+                            {
+                                variables->AddVariableIfUnique (var_sp);
+                                ++vars_added;
+                            }
+                        }
+                        else
+                        {
+                            if (m_using_apple_tables)
+                            {
+                                GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_offset);
+                            }
+                        }            
+
+                    }
+                }
+            }
+            return vars_added;
+        }
+    }
+    return 0;
+}
+
+
+VariableSP
+SymbolFileDWARF::ParseVariableDIE
+(
+    const SymbolContext& sc,
+    DWARFCompileUnit* dwarf_cu,
+    const DWARFDebugInfoEntry *die,
+    const lldb::addr_t func_low_pc
+)
+{
+
+    VariableSP var_sp (m_die_to_variable_sp[die]);
+    if (var_sp)
+        return var_sp;  // Already been parsed!
+    
+    const dw_tag_t tag = die->Tag();
+    
+    if ((tag == DW_TAG_variable) ||
+        (tag == DW_TAG_constant) ||
+        (tag == DW_TAG_formal_parameter && sc.function))
+    {
+        DWARFDebugInfoEntry::Attributes attributes;
+        const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
+        if (num_attributes > 0)
+        {
+            const char *name = NULL;
+            const char *mangled = NULL;
+            Declaration decl;
+            uint32_t i;
+            lldb::user_id_t type_uid = LLDB_INVALID_UID;
+            DWARFExpression location;
+            bool is_external = false;
+            bool is_artificial = false;
+            bool location_is_const_value_data = false;
+            //AccessType accessibility = eAccessNone;
+
+            for (i=0; i<num_attributes; ++i)
+            {
+                dw_attr_t attr = attributes.AttributeAtIndex(i);
+                DWARFFormValue form_value;
+                if (attributes.ExtractFormValueAtIndex(this, i, form_value))
+                {
+                    switch (attr)
+                    {
+                    case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
+                    case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
+                    case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
+                    case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
+                    case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
+                    case DW_AT_type:        type_uid = form_value.Reference(dwarf_cu); break;
+                    case DW_AT_external:    is_external = form_value.Unsigned() != 0; break;
+                    case DW_AT_const_value:
+                        location_is_const_value_data = true;
+                        // Fall through...
+                    case DW_AT_location:
+                        {
+                            if (form_value.BlockData())
+                            {
+                                const DataExtractor& debug_info_data = get_debug_info_data();
+
+                                uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
+                                uint32_t block_length = form_value.Unsigned();
+                                location.CopyOpcodeData(get_debug_info_data(), block_offset, block_length);
+                            }
+                            else
+                            {
+                                const DataExtractor&    debug_loc_data = get_debug_loc_data();
+                                const dw_offset_t debug_loc_offset = form_value.Unsigned();
+
+                                size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
+                                if (loc_list_length > 0)
+                                {
+                                    location.CopyOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
+                                    assert (func_low_pc != LLDB_INVALID_ADDRESS);
+                                    location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
+                                }
+                            }
+                        }
+                        break;
+
+                    case DW_AT_artificial:      is_artificial = form_value.Unsigned() != 0; break;
+                    case DW_AT_accessibility:   break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
+                    case DW_AT_declaration:
+                    case DW_AT_description:
+                    case DW_AT_endianity:
+                    case DW_AT_segment:
+                    case DW_AT_start_scope:
+                    case DW_AT_visibility:
+                    default:
+                    case DW_AT_abstract_origin:
+                    case DW_AT_sibling:
+                    case DW_AT_specification:
+                        break;
+                    }
+                }
+            }
+
+            if (location.IsValid())
+            {
+                ValueType scope = eValueTypeInvalid;
+
+                const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
+                dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
+                SymbolContextScope * symbol_context_scope = NULL;
+
+                // DWARF doesn't specify if a DW_TAG_variable is a local, global
+                // or static variable, so we have to do a little digging by
+                // looking at the location of a varaible to see if it contains
+                // a DW_OP_addr opcode _somewhere_ in the definition. I say
+                // somewhere because clang likes to combine small global variables
+                // into the same symbol and have locations like:
+                // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
+                // So if we don't have a DW_TAG_formal_parameter, we can look at
+                // the location to see if it contains a DW_OP_addr opcode, and
+                // then we can correctly classify  our variables.
+                if (tag == DW_TAG_formal_parameter)
+                    scope = eValueTypeVariableArgument;
+                else
+                {
+                    bool op_error = false;
+                    // Check if the location has a DW_OP_addr with any address value...
+                    addr_t location_has_op_addr = false;
+                    if (!location_is_const_value_data)
+                    {
+                        location_has_op_addr = location.LocationContains_DW_OP_addr (LLDB_INVALID_ADDRESS, op_error);
+                        if (op_error)
+                        {
+                            StreamString strm;
+                            location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
+                            GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), strm.GetString().c_str());
+                        }
+                    }
+
+                    if (location_has_op_addr)
+                    {
+                        if (is_external)
+                        {
+                            scope = eValueTypeVariableGlobal;
+
+                            if (GetDebugMapSymfile ())
+                            {
+                                // When leaving the DWARF in the .o files on darwin,
+                                // when we have a global variable that wasn't initialized,
+                                // the .o file might not have allocated a virtual
+                                // address for the global variable. In this case it will
+                                // have created a symbol for the global variable
+                                // that is undefined and external and the value will
+                                // be the byte size of the variable. When we do the
+                                // address map in SymbolFileDWARFDebugMap we rely on
+                                // having an address, we need to do some magic here
+                                // so we can get the correct address for our global 
+                                // variable. The address for all of these entries
+                                // will be zero, and there will be an undefined symbol
+                                // in this object file, and the executable will have
+                                // a matching symbol with a good address. So here we
+                                // dig up the correct address and replace it in the
+                                // location for the variable, and set the variable's
+                                // symbol context scope to be that of the main executable
+                                // so the file address will resolve correctly.
+                                if (location.LocationContains_DW_OP_addr (0, op_error))
+                                {
+                                    
+                                    // we have a possible uninitialized extern global
+                                    Symtab *symtab = m_obj_file->GetSymtab();
+                                    if (symtab)
+                                    {
+                                        ConstString const_name(name);
+                                        Symbol *undefined_symbol = symtab->FindFirstSymbolWithNameAndType (const_name,
+                                                                                                           eSymbolTypeUndefined, 
+                                                                                                           Symtab::eDebugNo, 
+                                                                                                           Symtab::eVisibilityExtern);
+                                        
+                                        if (undefined_symbol)
+                                        {
+                                            ObjectFile *debug_map_objfile = m_debug_map_symfile->GetObjectFile();
+                                            if (debug_map_objfile)
+                                            {
+                                                Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
+                                                Symbol *defined_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
+                                                                                                                           eSymbolTypeData, 
+                                                                                                                           Symtab::eDebugYes, 
+                                                                                                                           Symtab::eVisibilityExtern);
+                                                if (defined_symbol)
+                                                {
+                                                    if (defined_symbol->ValueIsAddress())
+                                                    {
+                                                        const addr_t defined_addr = defined_symbol->GetAddress().GetFileAddress();
+                                                        if (defined_addr != LLDB_INVALID_ADDRESS)
+                                                        {
+                                                            if (location.Update_DW_OP_addr (defined_addr))
+                                                            {
+                                                                symbol_context_scope = defined_symbol;
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        else  
+                        {
+                            scope = eValueTypeVariableStatic;
+                        }
+                    }
+                    else
+                    {
+                        scope = eValueTypeVariableLocal;
+                    }
+                }
+
+                if (symbol_context_scope == NULL)
+                {
+                    switch (parent_tag)
+                    {
+                    case DW_TAG_subprogram:
+                    case DW_TAG_inlined_subroutine:
+                    case DW_TAG_lexical_block:
+                        if (sc.function)
+                        {
+                            symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
+                            if (symbol_context_scope == NULL)
+                                symbol_context_scope = sc.function;
+                        }
+                        break;
+                    
+                    default:
+                        symbol_context_scope = sc.comp_unit;
+                        break;
+                    }
+                }
+
+                if (symbol_context_scope)
+                {
+                    var_sp.reset (new Variable (MakeUserID(die->GetOffset()), 
+                                                name, 
+                                                mangled,
+                                                SymbolFileTypeSP (new SymbolFileType(*this, type_uid)),
+                                                scope, 
+                                                symbol_context_scope, 
+                                                &decl, 
+                                                location, 
+                                                is_external, 
+                                                is_artificial));
+                    
+                    var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
+                }
+                else
+                {
+                    // Not ready to parse this variable yet. It might be a global
+                    // or static variable that is in a function scope and the function
+                    // in the symbol context wasn't filled in yet
+                    return var_sp;
+                }
+            }
+        }
+        // Cache var_sp even if NULL (the variable was just a specification or
+        // was missing vital information to be able to be displayed in the debugger
+        // (missing location due to optimization, etc)) so we don't re-parse
+        // this DIE over and over later...
+        m_die_to_variable_sp[die] = var_sp;
+    }
+    return var_sp;
+}
+
+
+const DWARFDebugInfoEntry *
+SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset, 
+                                                   dw_offset_t spec_block_die_offset,
+                                                   DWARFCompileUnit **result_die_cu_handle)
+{
+    // Give the concrete function die specified by "func_die_offset", find the 
+    // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
+    // to "spec_block_die_offset"
+    DWARFDebugInfo* info = DebugInfo();
+
+    const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
+    if (die)
+    {
+        assert (*result_die_cu_handle);
+        return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
+    }
+    return NULL;
+}
+
+
+const DWARFDebugInfoEntry *
+SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
+                                                  const DWARFDebugInfoEntry *die,
+                                                  dw_offset_t spec_block_die_offset,
+                                                  DWARFCompileUnit **result_die_cu_handle)
+{
+    if (die)
+    {
+        switch (die->Tag())
+        {
+        case DW_TAG_subprogram:
+        case DW_TAG_inlined_subroutine:
+        case DW_TAG_lexical_block:
+            {
+                if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
+                {
+                    *result_die_cu_handle = dwarf_cu;
+                    return die;
+                }
+
+                if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
+                {
+                    *result_die_cu_handle = dwarf_cu;
+                    return die;
+                }
+            }
+            break;
+        }
+
+        // Give the concrete function die specified by "func_die_offset", find the 
+        // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
+        // to "spec_block_die_offset"
+        for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
+        {
+            const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
+                                                                                      child_die,
+                                                                                      spec_block_die_offset,
+                                                                                      result_die_cu_handle);
+            if (result_die)
+                return result_die;
+        }
+    }
+    
+    *result_die_cu_handle = NULL;
+    return NULL;
+}
+
+size_t
+SymbolFileDWARF::ParseVariables
+(
+    const SymbolContext& sc,
+    DWARFCompileUnit* dwarf_cu,
+    const lldb::addr_t func_low_pc,
+    const DWARFDebugInfoEntry *orig_die,
+    bool parse_siblings,
+    bool parse_children,
+    VariableList* cc_variable_list
+)
+{
+    if (orig_die == NULL)
+        return 0;
+
+    VariableListSP variable_list_sp;
+
+    size_t vars_added = 0;
+    const DWARFDebugInfoEntry *die = orig_die;
+    while (die != NULL)
+    {
+        dw_tag_t tag = die->Tag();
+
+        // Check to see if we have already parsed this variable or constant?
+        if (m_die_to_variable_sp[die])
+        {
+            if (cc_variable_list)
+                cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
+        }
+        else
+        {
+            // We haven't already parsed it, lets do that now.
+            if ((tag == DW_TAG_variable) ||
+                (tag == DW_TAG_constant) ||
+                (tag == DW_TAG_formal_parameter && sc.function))
+            {
+                if (variable_list_sp.get() == NULL)
+                {
+                    const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
+                    dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
+                    switch (parent_tag)
+                    {
+                        case DW_TAG_compile_unit:
+                            if (sc.comp_unit != NULL)
+                            {
+                                variable_list_sp = sc.comp_unit->GetVariableList(false);
+                                if (variable_list_sp.get() == NULL)
+                                {
+                                    variable_list_sp.reset(new VariableList());
+                                    sc.comp_unit->SetVariableList(variable_list_sp);
+                                }
+                            }
+                            else
+                            {
+                                GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8llx %s with no valid compile unit in symbol context for 0x%8.8llx %s.\n",
+                                                                           MakeUserID(sc_parent_die->GetOffset()),
+                                                                           DW_TAG_value_to_name (parent_tag),
+                                                                           MakeUserID(orig_die->GetOffset()),
+                                                                           DW_TAG_value_to_name (orig_die->Tag()));
+                            }
+                            break;
+                            
+                        case DW_TAG_subprogram:
+                        case DW_TAG_inlined_subroutine:
+                        case DW_TAG_lexical_block:
+                            if (sc.function != NULL)
+                            {
+                                // Check to see if we already have parsed the variables for the given scope
+                                
+                                Block *block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
+                                if (block == NULL)
+                                {
+                                    // This must be a specification or abstract origin with 
+                                    // a concrete block couterpart in the current function. We need
+                                    // to find the concrete block so we can correctly add the 
+                                    // variable to it
+                                    DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
+                                    const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(), 
+                                                                                                                      sc_parent_die->GetOffset(), 
+                                                                                                                      &concrete_block_die_cu);
+                                    if (concrete_block_die)
+                                        block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(concrete_block_die->GetOffset()));
+                                }
+                                
+                                if (block != NULL)
+                                {
+                                    const bool can_create = false;
+                                    variable_list_sp = block->GetBlockVariableList (can_create);
+                                    if (variable_list_sp.get() == NULL)
+                                    {
+                                        variable_list_sp.reset(new VariableList());
+                                        block->SetVariableList(variable_list_sp);
+                                    }
+                                }
+                            }
+                            break;
+                            
+                        default:
+                             GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8llx %s.\n",
+                                                                        MakeUserID(orig_die->GetOffset()),
+                                                                        DW_TAG_value_to_name (orig_die->Tag()));
+                            break;
+                    }
+                }
+                
+                if (variable_list_sp)
+                {
+                    VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
+                    if (var_sp)
+                    {
+                        variable_list_sp->AddVariableIfUnique (var_sp);
+                        if (cc_variable_list)
+                            cc_variable_list->AddVariableIfUnique (var_sp);
+                        ++vars_added;
+                    }
+                }
+            }
+        }
+
+        bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
+
+        if (!skip_children && parse_children && die->HasChildren())
+        {
+            vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
+        }
+
+        if (parse_siblings)
+            die = die->GetSibling();
+        else
+            die = NULL;
+    }
+    return vars_added;
+}
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+const char *
+SymbolFileDWARF::GetPluginName()
+{
+    return "SymbolFileDWARF";
+}
+
+const char *
+SymbolFileDWARF::GetShortPluginName()
+{
+    return GetPluginNameStatic();
+}
+
+uint32_t
+SymbolFileDWARF::GetPluginVersion()
+{
+    return 1;
+}
+
+void
+SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
+{
+    SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
+    clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
+    if (clang_type)
+        symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
+}
+
+void
+SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
+{
+    SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
+    clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
+    if (clang_type)
+        symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
+}
+
+void
+SymbolFileDWARF::DumpIndexes ()
+{
+    StreamFile s(stdout, false);
+    
+    s.Printf ("DWARF index for (%s) '%s/%s':", 
+              GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
+              GetObjectFile()->GetFileSpec().GetDirectory().AsCString(), 
+              GetObjectFile()->GetFileSpec().GetFilename().AsCString());
+    s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
+    s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
+    s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
+    s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
+    s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
+    s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s); 
+    s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
+    s.Printf("\nNamepaces:\n");             m_namespace_index.Dump (&s);
+}
+
+void
+SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context, 
+                                    const char *name, 
+                                    llvm::SmallVectorImpl <clang::NamedDecl *> *results)
+{    
+    DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
+    
+    if (iter == m_decl_ctx_to_die.end())
+        return;
+    
+    for (DIEPointerSet::iterator pos = iter->second.begin(), end = iter->second.end(); pos != end; ++pos)
+    {
+        const DWARFDebugInfoEntry *context_die = *pos;
+    
+        if (!results)
+            return;
+        
+        DWARFDebugInfo* info = DebugInfo();
+        
+        DIEArray die_offsets;
+        
+        DWARFCompileUnit* dwarf_cu = NULL;
+        const DWARFDebugInfoEntry* die = NULL;
+        
+        if (m_using_apple_tables)
+        {
+            if (m_apple_types_ap.get())
+                m_apple_types_ap->FindByName (name, die_offsets);
+        }
+        else
+        {
+            if (!m_indexed)
+                Index ();
+            
+            m_type_index.Find (ConstString(name), die_offsets);
+        }
+        
+        const size_t num_matches = die_offsets.size();
+        
+        if (num_matches)
+        {
+            for (size_t i = 0; i < num_matches; ++i)
+            {
+                const dw_offset_t die_offset = die_offsets[i];
+                die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
+
+                if (die->GetParent() != context_die)
+                    continue;
+                
+                Type *matching_type = ResolveType (dwarf_cu, die);
+                
+                lldb::clang_type_t type = matching_type->GetClangForwardType();
+                clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
+                
+                if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
+                {
+                    clang::TagDecl *tag_decl = tag_type->getDecl();
+                    results->push_back(tag_decl);
+                }
+                else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
+                {
+                    clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
+                    results->push_back(typedef_decl); 
+                }
+            }
+        }
+    }
+}
+
+void
+SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
+                                                 const clang::DeclContext *decl_context,
+                                                 clang::DeclarationName decl_name,
+                                                 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
+{
+    
+    switch (decl_context->getDeclKind())
+    {
+    case clang::Decl::Namespace:
+    case clang::Decl::TranslationUnit:
+        {
+            SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
+            symbol_file_dwarf->SearchDeclContext (decl_context, decl_name.getAsString().c_str(), results);
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+bool 
+SymbolFileDWARF::LayoutRecordType (void *baton, 
+                                   const clang::RecordDecl *record_decl,
+                                   uint64_t &size, 
+                                   uint64_t &alignment,
+                                   llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets,
+                                   llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
+                                   llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
+{
+    SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
+    return symbol_file_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets);
+}
+
+
+bool 
+SymbolFileDWARF::LayoutRecordType (const clang::RecordDecl *record_decl,
+                                   uint64_t &bit_size, 
+                                   uint64_t &alignment,
+                                   llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets,
+                                   llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
+                                   llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
+{
+    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
+    RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl);
+    bool success = false;
+    base_offsets.clear();
+    vbase_offsets.clear();
+    if (pos != m_record_decl_to_layout_map.end())
+    {
+        bit_size = pos->second.bit_size;
+        alignment = pos->second.alignment;
+        field_offsets.swap(pos->second.field_offsets);
+        m_record_decl_to_layout_map.erase(pos);
+        success = true;
+    }
+    else
+    {
+        bit_size = 0;
+        alignment = 0;
+        field_offsets.clear();
+    }
+    
+    if (log)
+        GetObjectFile()->GetModule()->LogMessage (log.get(), 
+                                                  "SymbolFileDWARF::LayoutRecordType (record_decl = %p, bit_size = %llu, alignment = %llu, field_offsets[%u],base_offsets[%u], vbase_offsets[%u]) success = %i",
+                                                  record_decl,
+                                                  bit_size,
+                                                  alignment,
+                                                  (uint32_t)field_offsets.size(),
+                                                  (uint32_t)base_offsets.size(),
+                                                  (uint32_t)vbase_offsets.size(),
+                                                  success);
+    return success;
+}
+
+
+SymbolFileDWARFDebugMap *
+SymbolFileDWARF::GetDebugMapSymfile ()
+{
+    if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired())
+    {
+        lldb::ModuleSP module_sp (m_debug_map_module_wp.lock());
+        if (module_sp)
+        {
+            SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
+            if (sym_vendor)
+                m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
+        }
+    }
+    return m_debug_map_symfile;
+}
+
+

Modified: lldb/branches/windows/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp (original)
+++ lldb/branches/windows/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp Thu Nov  1 02:04:04 2012
@@ -12,6 +12,7 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/RegularExpression.h"
 #include "lldb/Core/Timer.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -403,11 +404,13 @@
         
         ClangASTContext &ast = GetClangASTContext();
         
+        ClangASTMetadata metadata;
+        metadata.SetUserID(0xffaaffaaffaaffaall);
         lldb::clang_type_t objc_object_type = ast.CreateObjCClass (name.AsCString(), 
                                                                    ast.GetTranslationUnitDecl(), 
                                                                    isForwardDecl, 
                                                                    isInternal,
-                                                                   0xffaaffaaffaaffaall);
+                                                                   &metadata);
         
         Declaration decl;
         

Modified: lldb/branches/windows/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp (original)
+++ lldb/branches/windows/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp Thu Nov  1 02:04:04 2012
@@ -108,12 +108,13 @@
                 // copy of the CFI at that point into prologue_completed_row for possible
                 // use later.
                 int instructions_since_last_prologue_insn = 0;     // # of insns since last CFI was update
-                bool prologue_complete = false;                    // true if we have finished prologue setup
 
                 bool reinstate_prologue_next_instruction = false;  // Next iteration, re-install the prologue row of CFI
 
                 bool last_instruction_restored_return_addr_reg = false;  // re-install the prologue row of CFI if the next instruction is a branch immediate
 
+                bool return_address_register_has_been_saved = false; // if we've seen the ra register get saved yet
+
                 UnwindPlan::RowSP prologue_completed_row;          // copy of prologue row of CFI
 
                 // cache the pc register number (in whatever register numbering this UnwindPlan uses) for
@@ -137,6 +138,7 @@
                 for (size_t idx=0; idx<num_instructions; ++idx)
                 {
                     m_curr_row_modified = false;
+                    m_curr_insn_restored_a_register = false;
                     inst = inst_list.GetInstructionAtIndex (idx).get();
                     if (inst)
                     {
@@ -166,15 +168,33 @@
                             *newrow = *m_curr_row.get();
                             m_curr_row.reset(newrow);
 
-                            instructions_since_last_prologue_insn = 0;
+                            // If m_curr_insn_restored_a_register == true, we're looking at an epilogue instruction.
+                            // Set instructions_since_last_prologue_insn to a very high number so we don't append 
+                            // any of these epilogue instructions to our prologue_complete row.
+                            if (m_curr_insn_restored_a_register == false && instructions_since_last_prologue_insn < 8)
+                              instructions_since_last_prologue_insn = 0;
+                            else
+                              instructions_since_last_prologue_insn = 99;
+
+                            UnwindPlan::Row::RegisterLocation pc_regloc;
+                            UnwindPlan::Row::RegisterLocation ra_regloc;
+
+                            // While parsing the instructions of this function, if we've ever
+                            // seen the return address register (aka lr on arm) in a non-IsSame() state,
+                            // it has been saved on the stack.  If it's evern back to IsSame(), we've
+                            // executed an epilogue.
+                            if (ra_reg_num != LLDB_INVALID_REGNUM
+                                && m_curr_row->GetRegisterInfo (ra_reg_num, ra_regloc)
+                                && !ra_regloc.IsSame())
+                            {
+                                return_address_register_has_been_saved = true;
+                            }
 
                             // If the caller's pc is "same", we've just executed an epilogue and we return to the caller
                             // after this instruction completes executing.
                             // If there are any instructions past this, there must have been flow control over this
                             // epilogue so we'll reinstate the original prologue setup instructions.
-                            UnwindPlan::Row::RegisterLocation pc_regloc;
-                            UnwindPlan::Row::RegisterLocation ra_regloc;
-                            if (prologue_complete
+                            if (prologue_completed_row.get()
                                 && pc_reg_num != LLDB_INVALID_REGNUM 
                                 && m_curr_row->GetRegisterInfo (pc_reg_num, pc_regloc)
                                 && pc_regloc.IsSame())
@@ -183,7 +203,8 @@
                                     log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- pc is <same>, restore prologue instructions.");
                                 reinstate_prologue_next_instruction = true;
                             }
-                            else if (prologue_complete
+                            else if (prologue_completed_row.get()
+                                     && return_address_register_has_been_saved
                                      && ra_reg_num != LLDB_INVALID_REGNUM
                                      && m_curr_row->GetRegisterInfo (ra_reg_num, ra_regloc)
                                      && ra_regloc.IsSame())
@@ -230,16 +251,15 @@
                                 m_curr_insn_is_branch_immediate = false;
                             }
  
-                            // If we haven't seen any prologue instructions for a while (4 instructions in a row),
-                            // the function prologue has probably completed.  Save a copy of that Row.
-                            if (prologue_complete == false && instructions_since_last_prologue_insn++ > 3)
+                            // Stop updating the prologue instructions if we've seen 8 non-prologue instructions
+                            // in a row.
+                            if (instructions_since_last_prologue_insn++ < 8)
                             {
-                                prologue_complete = true;
                                 UnwindPlan::Row *newrow = new UnwindPlan::Row;
                                 *newrow = *m_curr_row.get();
                                 prologue_completed_row.reset(newrow);
                                 if (log && log->GetVerbose())
-                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- prologue has been set up, saving a copy.");
+                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- saving a copy of the current row as the prologue row.");
                             }
                         }
                     }
@@ -622,6 +642,7 @@
                 {
                     m_curr_row->SetRegisterLocationToSame (reg_num, must_replace);
                     m_curr_row_modified = true;
+                    m_curr_insn_restored_a_register = true;
                 }
             }
             break;

Modified: lldb/branches/windows/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h (original)
+++ lldb/branches/windows/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h Thu Nov  1 02:04:04 2012
@@ -134,12 +134,13 @@
         m_thread_ptr (NULL),
         m_unwind_plan_ptr (NULL),
         m_curr_row (),
-        m_curr_row_modified (false),
-        m_curr_insn_is_branch_immediate (false),
         m_cfa_reg_info (),
         m_fp_is_cfa (false),
         m_register_values (),
-        m_pushed_regs()
+        m_pushed_regs(),
+        m_curr_row_modified (false),
+        m_curr_insn_is_branch_immediate (false),
+        m_curr_insn_restored_a_register (false)
     {
         if (m_inst_emulator_ap.get())
         {
@@ -164,8 +165,6 @@
     lldb_private::Thread* m_thread_ptr;
     lldb_private::UnwindPlan* m_unwind_plan_ptr;
     lldb_private::UnwindPlan::RowSP m_curr_row;
-    bool m_curr_row_modified;
-    bool m_curr_insn_is_branch_immediate;
     typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap;
     uint64_t m_initial_sp;
     lldb_private::RegisterInfo m_cfa_reg_info;
@@ -173,6 +172,17 @@
     typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap;
     RegisterValueMap m_register_values;
     PushedRegisterToAddrMap m_pushed_regs;
+
+    // While processing the instruction stream, we need to communicate some state change
+    // information up to the higher level loop that makes decisions about how to push
+    // the unwind instructions for the UnwindPlan we're constructing.
+    
+    // The instruction we're processing updated the UnwindPlan::Row contents
+    bool m_curr_row_modified;
+    // The instruction we're examining is a branch immediate instruction
+    bool m_curr_insn_is_branch_immediate;
+    // The instruction we're processing restored a caller's reg value (e.g. in an epilogue)
+    bool m_curr_insn_restored_a_register;
 };
 
 #endif // liblldb_UnwindAssemblyInstEmulation_h_

Modified: lldb/branches/windows/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp (original)
+++ lldb/branches/windows/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp Thu Nov  1 02:04:04 2012
@@ -738,6 +738,8 @@
     }
     
     unwind_plan.SetSourceName ("assembly insn profiling");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
 
     return true;
 }
@@ -822,6 +824,9 @@
     row.reset(newrow);
 
     unwind_plan.SetPlanValidAddressRange (func);
+    unwind_plan.SetSourceName ("fast unwind assembly profiling");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
     return true;
 }
 

Modified: lldb/branches/windows/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Symbol/ClangASTContext.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/branches/windows/source/Symbol/ClangASTContext.cpp Thu Nov  1 02:04:04 2012
@@ -566,7 +566,7 @@
     if (m_diagnostics_engine_ap.get() == NULL)
     {
         llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
-        m_diagnostics_engine_ap.reset(new DiagnosticsEngine(diag_id_sp));
+        m_diagnostics_engine_ap.reset(new DiagnosticsEngine(diag_id_sp, new DiagnosticOptions()));
     }
     return m_diagnostics_engine_ap.get();
 }
@@ -1127,7 +1127,7 @@
 #pragma mark Structure, Unions, Classes
 
 clang_type_t
-ClangASTContext::CreateRecordType (DeclContext *decl_ctx, AccessType access_type, const char *name, int kind, LanguageType language, uint64_t metadata)
+ClangASTContext::CreateRecordType (DeclContext *decl_ctx, AccessType access_type, const char *name, int kind, LanguageType language, ClangASTMetadata *metadata)
 {
     ASTContext *ast = getASTContext();
     assert (ast != NULL);
@@ -1155,8 +1155,8 @@
                                                  SourceLocation(),
                                                  name && name[0] ? &ast->Idents.get(name) : NULL);
     
-    if (decl)
-        SetMetadata(ast, (uintptr_t)decl, metadata);
+    if (decl && metadata)
+        SetMetadata(ast, (uintptr_t)decl, *metadata);
     
     if (decl_ctx)
     {
@@ -2263,7 +2263,7 @@
     DeclContext *decl_ctx, 
     bool isForwardDecl, 
     bool isInternal,
-    uint64_t metadata
+    ClangASTMetadata *metadata
 )
 {
     ASTContext *ast = getASTContext();
@@ -2286,8 +2286,8 @@
                                                          /*isForwardDecl,*/
                                                          isInternal);
     
-    if (decl)
-        SetMetadata(ast, (uintptr_t)decl, metadata);
+    if (decl && metadata)
+        SetMetadata(ast, (uintptr_t)decl, *metadata);
     
     return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
 }
@@ -2401,7 +2401,7 @@
     const char *property_setter_name,
     const char *property_getter_name,
     uint32_t property_attributes,
-    uint64_t metadata
+    ClangASTMetadata *metadata
 )
 {
     if (class_opaque_type == NULL || property_name == NULL || property_name[0] == '\0')
@@ -2448,7 +2448,8 @@
                 
                 if (property_decl)
                 {
-                    SetMetadata(ast, (uintptr_t)property_decl, metadata);
+                    if (metadata)
+                        SetMetadata(ast, (uintptr_t)property_decl, *metadata);
                     
                     class_interface_decl->addDecl (property_decl);
                     
@@ -2527,8 +2528,8 @@
                                                                         impControl,
                                                                         HasRelatedResultType);
                         
-                        if (getter)
-                            SetMetadata(ast, (uintptr_t)getter, metadata);
+                        if (getter && metadata)
+                            SetMetadata(ast, (uintptr_t)getter, *metadata);
                                                 
                         getter->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(), ArrayRef<SourceLocation>());
                         
@@ -2562,8 +2563,8 @@
                                                                         impControl,
                                                                         HasRelatedResultType);
                         
-                        if (setter)
-                            SetMetadata(ast, (uintptr_t)setter, metadata);
+                        if (setter && metadata)
+                            SetMetadata(ast, (uintptr_t)setter, *metadata);
                         
                         llvm::SmallVector<ParmVarDecl *, 1> params;
 
@@ -6401,9 +6402,18 @@
 }
 
 void
+ClangASTContext::SetMetadataAsUserID (uintptr_t object,
+                                      user_id_t user_id)
+{
+    ClangASTMetadata meta_data;
+    meta_data.SetUserID (user_id);
+    SetMetadata (object, meta_data);
+}
+
+void
 ClangASTContext::SetMetadata (clang::ASTContext *ast,
                               uintptr_t object,
-                              uint64_t metadata)
+                              ClangASTMetadata &metadata)
 {
     ClangExternalASTSourceCommon *external_source =
         static_cast<ClangExternalASTSourceCommon*>(ast->getExternalSource());
@@ -6412,7 +6422,7 @@
         external_source->SetMetadata(object, metadata);
 }
 
-uint64_t
+ClangASTMetadata *
 ClangASTContext::GetMetadata (clang::ASTContext *ast,
                               uintptr_t object)
 {
@@ -6422,7 +6432,7 @@
     if (external_source && external_source->HasMetadata(object))
         return external_source->GetMetadata(object);
     else
-        return 0;
+        return NULL;
 }
 
 clang::DeclContext *
@@ -6479,6 +6489,17 @@
             language = eLanguageTypeObjC;
             return true;
         }
+        else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_ctx))
+        {
+            ClangASTMetadata *metadata = GetMetadata (&decl_ctx->getParentASTContext(), (uintptr_t) function_decl);
+            if (metadata && metadata->HasObjectPtr())
+            {
+                language_object_name.SetCString (metadata->GetObjectPtrName());
+                language = eLanguageTypeObjC;
+                is_instance_method = true;
+            }
+            return true;
+        }
     }
     return false;
 }

Added: lldb/branches/windows/source/Symbol/ClangASTContext.cpp.orig
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Symbol/ClangASTContext.cpp.orig?rev=167218&view=auto
==============================================================================
--- lldb/branches/windows/source/Symbol/ClangASTContext.cpp.orig (added)
+++ lldb/branches/windows/source/Symbol/ClangASTContext.cpp.orig Thu Nov  1 02:04:04 2012
@@ -0,0 +1,6449 @@
+//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/ClangASTContext.h"
+
+// C Includes
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+
+// Clang headers like to use NDEBUG inside of them to enable/disable debug 
+// releated features using "#ifndef NDEBUG" preprocessor blocks to do one thing
+// or another. This is bad because it means that if clang was built in release
+// mode, it assumes that you are building in release mode which is not always
+// the case. You can end up with functions that are defined as empty in header
+// files when NDEBUG is not defined, and this can cause link errors with the
+// clang .a files that you have since you might be missing functions in the .a
+// file. So we have to define NDEBUG when including clang headers to avoid any
+// mismatches. This is covered by rdar://problem/8691220
+
+#if !defined(NDEBUG) && !defined(LLVM_NDEBUG_OFF)
+#define LLDB_DEFINED_NDEBUG_FOR_CLANG
+#define NDEBUG
+// Need to include assert.h so it is as clang would expect it to be (disabled)
+#include <assert.h>
+#endif
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTImporter.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/Frontend/FrontendOptions.h"
+#include "clang/Frontend/LangStandard.h"
+#include "clang/Basic/Version.h"
+
+#ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG
+#undef NDEBUG
+#undef LLDB_DEFINED_NDEBUG_FOR_CLANG
+// Need to re-include assert.h so it is as _we_ would expect it to be (enabled)
+#include <assert.h>
+#endif
+
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/dwarf.h"
+#include "lldb/Core/Flags.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Expression/ASTDumper.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/VerifyDecl.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+
+
+#include <stdio.h>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+using namespace clang;
+
+
+static bool
+GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool allow_completion = true)
+{
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+    case clang::Type::ConstantArray:
+        {
+            const clang::ArrayType *array_type = dyn_cast<clang::ArrayType>(qual_type.getTypePtr());
+            
+            if (array_type)
+                return GetCompleteQualType (ast, array_type->getElementType(), allow_completion);
+        }
+        break;
+            
+    case clang::Type::Record:
+    case clang::Type::Enum:
+        {
+            const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr());
+            if (tag_type)
+            {
+                clang::TagDecl *tag_decl = tag_type->getDecl();
+                if (tag_decl)
+                {
+                    if (tag_decl->isCompleteDefinition())
+                        return true;
+                    
+                    if (!allow_completion)
+                        return false;
+
+                    if (tag_decl->hasExternalLexicalStorage())
+                    {
+                        if (ast)
+                        {
+                            ExternalASTSource *external_ast_source = ast->getExternalSource();
+                            if (external_ast_source)
+                            {
+                                external_ast_source->CompleteType(tag_decl);
+                                return !tag_type->isIncompleteType();
+                            }
+                        }
+                    }
+                    return false;
+                }
+            }
+
+        }
+        break;
+
+    case clang::Type::ObjCObject:
+    case clang::Type::ObjCInterface:
+        {
+            const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type);
+            if (objc_class_type)
+            {
+                clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                // We currently can't complete objective C types through the newly added ASTContext
+                // because it only supports TagDecl objects right now...
+                if (class_interface_decl)
+                {
+                    if (class_interface_decl->getDefinition())
+                        return true;
+                    
+                    if (!allow_completion)
+                        return false;
+
+                    if (class_interface_decl->hasExternalLexicalStorage())
+                    {
+                        if (ast)
+                        {
+                            ExternalASTSource *external_ast_source = ast->getExternalSource();
+                            if (external_ast_source)
+                            {
+                                external_ast_source->CompleteType (class_interface_decl);
+                                return !objc_class_type->isIncompleteType();
+                            }
+                        }
+                    }
+                    return false;
+                }
+            }
+        }
+        break;
+
+    case clang::Type::Typedef:
+        return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion);
+    
+    case clang::Type::Elaborated:
+        return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType(), allow_completion);
+
+    default:
+        break;
+    }
+
+    return true;
+}
+
+static AccessSpecifier
+ConvertAccessTypeToAccessSpecifier (AccessType access)
+{
+    switch (access)
+    {
+    default:               break;
+    case eAccessNone:      return AS_none;
+    case eAccessPublic:    return AS_public;
+    case eAccessPrivate:   return AS_private;
+    case eAccessProtected: return AS_protected;
+    }
+    return AS_none;
+}
+
+static ObjCIvarDecl::AccessControl
+ConvertAccessTypeToObjCIvarAccessControl (AccessType access)
+{
+    switch (access)
+    {
+    default:               break;
+    case eAccessNone:      return ObjCIvarDecl::None;
+    case eAccessPublic:    return ObjCIvarDecl::Public;
+    case eAccessPrivate:   return ObjCIvarDecl::Private;
+    case eAccessProtected: return ObjCIvarDecl::Protected;
+    case eAccessPackage:   return ObjCIvarDecl::Package;
+    }
+    return ObjCIvarDecl::None;
+}
+
+
+static void
+ParseLangArgs
+(
+    LangOptions &Opts,
+    InputKind IK
+)
+{
+    // FIXME: Cleanup per-file based stuff.
+
+    // Set some properties which depend soley on the input kind; it would be nice
+    // to move these to the language standard, and have the driver resolve the
+    // input kind + language standard.
+    if (IK == IK_Asm) {
+        Opts.AsmPreprocessor = 1;
+    } else if (IK == IK_ObjC ||
+               IK == IK_ObjCXX ||
+               IK == IK_PreprocessedObjC ||
+               IK == IK_PreprocessedObjCXX) {
+        Opts.ObjC1 = Opts.ObjC2 = 1;
+    }
+
+    LangStandard::Kind LangStd = LangStandard::lang_unspecified;
+
+    if (LangStd == LangStandard::lang_unspecified) {
+        // Based on the base language, pick one.
+        switch (IK) {
+            case IK_None:
+            case IK_AST:
+            case IK_LLVM_IR:
+                assert (!"Invalid input kind!");
+            case IK_OpenCL:
+                LangStd = LangStandard::lang_opencl;
+                break;
+            case IK_CUDA:
+                LangStd = LangStandard::lang_cuda;
+                break;
+            case IK_Asm:
+            case IK_C:
+            case IK_PreprocessedC:
+            case IK_ObjC:
+            case IK_PreprocessedObjC:
+                LangStd = LangStandard::lang_gnu99;
+                break;
+            case IK_CXX:
+            case IK_PreprocessedCXX:
+            case IK_ObjCXX:
+            case IK_PreprocessedObjCXX:
+                LangStd = LangStandard::lang_gnucxx98;
+                break;
+        }
+    }
+
+    const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
+    Opts.BCPLComment = Std.hasBCPLComments();
+    Opts.C99 = Std.isC99();
+    Opts.CPlusPlus = Std.isCPlusPlus();
+    Opts.CPlusPlus0x = Std.isCPlusPlus0x();
+    Opts.Digraphs = Std.hasDigraphs();
+    Opts.GNUMode = Std.isGNUMode();
+    Opts.GNUInline = !Std.isC99();
+    Opts.HexFloats = Std.hasHexFloats();
+    Opts.ImplicitInt = Std.hasImplicitInt();
+
+    // OpenCL has some additional defaults.
+    if (LangStd == LangStandard::lang_opencl) {
+        Opts.OpenCL = 1;
+        Opts.AltiVec = 1;
+        Opts.CXXOperatorNames = 1;
+        Opts.LaxVectorConversions = 1;
+    }
+
+    // OpenCL and C++ both have bool, true, false keywords.
+    Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
+
+//    if (Opts.CPlusPlus)
+//        Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
+//
+//    if (Args.hasArg(OPT_fobjc_gc_only))
+//        Opts.setGCMode(LangOptions::GCOnly);
+//    else if (Args.hasArg(OPT_fobjc_gc))
+//        Opts.setGCMode(LangOptions::HybridGC);
+//
+//    if (Args.hasArg(OPT_print_ivar_layout))
+//        Opts.ObjCGCBitmapPrint = 1;
+//
+//    if (Args.hasArg(OPT_faltivec))
+//        Opts.AltiVec = 1;
+//
+//    if (Args.hasArg(OPT_pthread))
+//        Opts.POSIXThreads = 1;
+//
+//    llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
+//                                          "default");
+//    if (Vis == "default")
+        Opts.setVisibilityMode(DefaultVisibility);
+//    else if (Vis == "hidden")
+//        Opts.setVisibilityMode(LangOptions::Hidden);
+//    else if (Vis == "protected")
+//        Opts.setVisibilityMode(LangOptions::Protected);
+//    else
+//        Diags.Report(diag::err_drv_invalid_value)
+//        << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
+
+//    Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
+
+    // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
+    // is specified, or -std is set to a conforming mode.
+    Opts.Trigraphs = !Opts.GNUMode;
+//    if (Args.hasArg(OPT_trigraphs))
+//        Opts.Trigraphs = 1;
+//
+//    Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers,
+//                                     OPT_fno_dollars_in_identifiers,
+//                                     !Opts.AsmPreprocessor);
+//    Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
+//    Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
+//    Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
+//    if (Args.hasArg(OPT_fno_lax_vector_conversions))
+//        Opts.LaxVectorConversions = 0;
+//    Opts.Exceptions = Args.hasArg(OPT_fexceptions);
+//    Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
+//    Opts.Blocks = Args.hasArg(OPT_fblocks);
+//    Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char);
+//    Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
+//    Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
+//    Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
+//    Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
+//    Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
+//    Opts.AccessControl = Args.hasArg(OPT_faccess_control);
+//    Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
+//    Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
+//    Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
+//                                                 Diags);
+//    Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
+//    Opts.ObjCConstantStringClass = getLastArgValue(Args,
+//                                                   OPT_fconstant_string_class);
+//    Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
+//    Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
+//    Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
+//    Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
+//    Opts.Static = Args.hasArg(OPT_static_define);
+    Opts.OptimizeSize = 0;
+
+    // FIXME: Eliminate this dependency.
+//    unsigned Opt =
+//    Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags);
+//    Opts.Optimize = Opt != 0;
+    unsigned Opt = 0;
+
+    // This is the __NO_INLINE__ define, which just depends on things like the
+    // optimization level and -fno-inline, not actually whether the backend has
+    // inlining enabled.
+    //
+    // FIXME: This is affected by other options (-fno-inline).
+<<<<<<< .working
+#if (CLANG_VERSION_MAJOR <= 3 && CLANG_VERSION_MINOR < 2)
+    Opts.NoInline = !Opt;
+=======
+    Opts.NoInlineDefine = !Opt;
+>>>>>>> .merge-right.r164814
+#endif
+
+//    unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
+//    switch (SSP) {
+//        default:
+//            Diags.Report(diag::err_drv_invalid_value)
+//            << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
+//            break;
+//        case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
+//        case 1: Opts.setStackProtectorMode(LangOptions::SSPOn);  break;
+//        case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break;
+//    }
+}
+
+
+ClangASTContext::ClangASTContext (const char *target_triple) :   
+    m_target_triple(),
+    m_ast_ap(),
+    m_language_options_ap(),
+    m_source_manager_ap(),
+    m_diagnostics_engine_ap(),
+    m_target_options_ap(),
+    m_target_info_ap(),
+    m_identifier_table_ap(),
+    m_selector_table_ap(),
+    m_builtins_ap(),
+    m_callback_tag_decl (NULL),
+    m_callback_objc_decl (NULL),
+    m_callback_baton (NULL)
+
+{
+    if (target_triple && target_triple[0])
+        SetTargetTriple (target_triple);
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+ClangASTContext::~ClangASTContext()
+{
+    m_builtins_ap.reset();
+    m_selector_table_ap.reset();
+    m_identifier_table_ap.reset();
+    m_target_info_ap.reset();
+    m_target_options_ap.reset();
+    m_diagnostics_engine_ap.reset();
+    m_source_manager_ap.reset();
+    m_language_options_ap.reset();
+    m_ast_ap.reset();
+}
+
+
+void
+ClangASTContext::Clear()
+{
+    m_ast_ap.reset();
+    m_language_options_ap.reset();
+    m_source_manager_ap.reset();
+    m_diagnostics_engine_ap.reset();
+    m_target_options_ap.reset();
+    m_target_info_ap.reset();
+    m_identifier_table_ap.reset();
+    m_selector_table_ap.reset();
+    m_builtins_ap.reset();
+}
+
+const char *
+ClangASTContext::GetTargetTriple ()
+{
+    return m_target_triple.c_str();
+}
+
+void
+ClangASTContext::SetTargetTriple (const char *target_triple)
+{
+    Clear();
+    m_target_triple.assign(target_triple);
+}
+
+void
+ClangASTContext::SetArchitecture (const ArchSpec &arch)
+{
+    SetTargetTriple(arch.GetTriple().str().c_str());
+}
+
+bool
+ClangASTContext::HasExternalSource ()
+{
+    ASTContext *ast = getASTContext();
+    if (ast)
+        return ast->getExternalSource () != NULL;
+    return false;
+}
+
+void
+ClangASTContext::SetExternalSource (llvm::OwningPtr<ExternalASTSource> &ast_source_ap)
+{
+    ASTContext *ast = getASTContext();
+    if (ast)
+    {
+        ast->setExternalSource (ast_source_ap);
+        ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true);
+        //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true);
+    }
+}
+
+void
+ClangASTContext::RemoveExternalSource ()
+{
+    ASTContext *ast = getASTContext();
+    
+    if (ast)
+    {
+        llvm::OwningPtr<ExternalASTSource> empty_ast_source_ap;
+        ast->setExternalSource (empty_ast_source_ap);
+        ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false);
+        //ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false);
+    }
+}
+
+
+
+ASTContext *
+ClangASTContext::getASTContext()
+{
+    if (m_ast_ap.get() == NULL)
+    {
+        m_ast_ap.reset(new ASTContext (*getLanguageOptions(),
+                                       *getSourceManager(),
+                                       getTargetInfo(),
+                                       *getIdentifierTable(),
+                                       *getSelectorTable(),
+                                       *getBuiltinContext(),
+                                       0));
+        
+        if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton)
+        {
+            m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage();
+            //m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage();
+        }
+        
+        m_ast_ap->getDiagnostics().setClient(getDiagnosticConsumer(), false);
+    }
+    return m_ast_ap.get();
+}
+
+Builtin::Context *
+ClangASTContext::getBuiltinContext()
+{
+    if (m_builtins_ap.get() == NULL)
+        m_builtins_ap.reset (new Builtin::Context());
+    return m_builtins_ap.get();
+}
+
+IdentifierTable *
+ClangASTContext::getIdentifierTable()
+{
+    if (m_identifier_table_ap.get() == NULL)
+        m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL));
+    return m_identifier_table_ap.get();
+}
+
+LangOptions *
+ClangASTContext::getLanguageOptions()
+{
+    if (m_language_options_ap.get() == NULL)
+    {
+        m_language_options_ap.reset(new LangOptions());
+        ParseLangArgs(*m_language_options_ap, IK_ObjCXX);
+//        InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
+    }
+    return m_language_options_ap.get();
+}
+
+SelectorTable *
+ClangASTContext::getSelectorTable()
+{
+    if (m_selector_table_ap.get() == NULL)
+        m_selector_table_ap.reset (new SelectorTable());
+    return m_selector_table_ap.get();
+}
+
+clang::FileManager *
+ClangASTContext::getFileManager()
+{
+    if (m_file_manager_ap.get() == NULL)
+    {
+        clang::FileSystemOptions file_system_options;
+        m_file_manager_ap.reset(new clang::FileManager(file_system_options));
+    }
+    return m_file_manager_ap.get();
+}
+
+clang::SourceManager *
+ClangASTContext::getSourceManager()
+{
+    if (m_source_manager_ap.get() == NULL)
+        m_source_manager_ap.reset(new clang::SourceManager(*getDiagnosticsEngine(), *getFileManager()));
+    return m_source_manager_ap.get();
+}
+
+clang::DiagnosticsEngine *
+ClangASTContext::getDiagnosticsEngine()
+{
+    if (m_diagnostics_engine_ap.get() == NULL)
+    {
+        llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs());
+        m_diagnostics_engine_ap.reset(new DiagnosticsEngine(diag_id_sp));
+    }
+    return m_diagnostics_engine_ap.get();
+}
+
+class NullDiagnosticConsumer : public DiagnosticConsumer
+{
+public:
+    NullDiagnosticConsumer ()
+    {
+        m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+    }
+    
+    void HandleDiagnostic (DiagnosticsEngine::Level DiagLevel, const Diagnostic &info)
+    {
+        if (m_log)
+        {
+            llvm::SmallVector<char, 32> diag_str(10);
+            info.FormatDiagnostic(diag_str);
+            diag_str.push_back('\0');
+            m_log->Printf("Compiler diagnostic: %s\n", diag_str.data());
+        }
+    }
+    
+    DiagnosticConsumer *clone (DiagnosticsEngine &Diags) const
+    {
+        return new NullDiagnosticConsumer ();
+    }
+private:
+    LogSP m_log;
+};
+
+DiagnosticConsumer *
+ClangASTContext::getDiagnosticConsumer()
+{
+    if (m_diagnostic_consumer_ap.get() == NULL)
+        m_diagnostic_consumer_ap.reset(new NullDiagnosticConsumer);
+    
+    return m_diagnostic_consumer_ap.get();
+}
+
+TargetOptions *
+ClangASTContext::getTargetOptions()
+{
+    if (m_target_options_ap.get() == NULL && !m_target_triple.empty())
+    {
+        m_target_options_ap.reset (new TargetOptions());
+        if (m_target_options_ap.get())
+            m_target_options_ap->Triple = m_target_triple;
+    }
+    return m_target_options_ap.get();
+}
+
+
+TargetInfo *
+ClangASTContext::getTargetInfo()
+{
+    // target_triple should be something like "x86_64-apple-macosx"
+    if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
+        m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(), *getTargetOptions()));
+    return m_target_info_ap.get();
+}
+
+#pragma mark Basic Types
+
+static inline bool
+QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type)
+{
+    uint64_t qual_type_bit_size = ast->getTypeSize(qual_type);
+    if (qual_type_bit_size == bit_size)
+        return true;
+    return false;
+}
+
+clang_type_t
+ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size)
+{
+    ASTContext *ast = getASTContext();
+
+    assert (ast != NULL);
+
+    return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size);
+}
+
+clang_type_t
+ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size)
+{
+    if (!ast)
+        return NULL;
+    
+    switch (encoding)
+    {
+    case eEncodingInvalid:
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
+            return ast->VoidPtrTy.getAsOpaquePtr();
+        break;
+        
+    case eEncodingUint:
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
+            return ast->UnsignedCharTy.getAsOpaquePtr();
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
+            return ast->UnsignedShortTy.getAsOpaquePtr();
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
+            return ast->UnsignedIntTy.getAsOpaquePtr();
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
+            return ast->UnsignedLongTy.getAsOpaquePtr();
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
+            return ast->UnsignedLongLongTy.getAsOpaquePtr();
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
+            return ast->UnsignedInt128Ty.getAsOpaquePtr();
+        break;
+        
+    case eEncodingSint:
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
+            return ast->CharTy.getAsOpaquePtr();
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
+            return ast->ShortTy.getAsOpaquePtr();
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
+            return ast->IntTy.getAsOpaquePtr();
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
+            return ast->LongTy.getAsOpaquePtr();
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
+            return ast->LongLongTy.getAsOpaquePtr();
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
+            return ast->Int128Ty.getAsOpaquePtr();
+        break;
+        
+    case eEncodingIEEE754:
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
+            return ast->FloatTy.getAsOpaquePtr();
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
+            return ast->DoubleTy.getAsOpaquePtr();
+        if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
+            return ast->LongDoubleTy.getAsOpaquePtr();
+        break;
+        
+    case eEncodingVector:
+        // Sanity check that bit_size is a multiple of 8's.
+        if (bit_size && !(bit_size & 0x7u))
+            return ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8).getAsOpaquePtr();
+        break;
+    default:
+        break;
+    }
+    
+    return NULL;
+}
+
+clang_type_t
+ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size)
+{
+    ASTContext *ast = getASTContext();
+    
+#define streq(a,b) strcmp(a,b) == 0
+    assert (ast != NULL);
+    if (ast)
+    {
+        switch (dw_ate)
+        {
+            default:
+                break;
+                
+            case DW_ATE_address:
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy))
+                    return ast->VoidPtrTy.getAsOpaquePtr();
+                break;
+                
+            case DW_ATE_boolean:
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy))
+                    return ast->BoolTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
+                    return ast->UnsignedCharTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
+                    return ast->UnsignedShortTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
+                    return ast->UnsignedIntTy.getAsOpaquePtr();
+                break;
+                
+            case DW_ATE_lo_user:
+                // This has been seen to mean DW_AT_complex_integer
+                if (type_name)
+                {
+                    if (::strstr(type_name, "complex"))
+                    {
+                        clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2);
+                        return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr();
+                    }
+                }
+                break;
+                
+            case DW_ATE_complex_float:
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy))
+                    return ast->FloatComplexTy.getAsOpaquePtr();
+                else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy))
+                    return ast->DoubleComplexTy.getAsOpaquePtr();
+                else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy))
+                    return ast->LongDoubleComplexTy.getAsOpaquePtr();
+                else 
+                {
+                    clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2);
+                    return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr();
+                }
+                break;
+                
+            case DW_ATE_float:
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy))
+                    return ast->FloatTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy))
+                    return ast->DoubleTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy))
+                    return ast->LongDoubleTy.getAsOpaquePtr();
+                break;
+                
+            case DW_ATE_signed:
+                if (type_name)
+                {
+                    if (streq(type_name, "wchar_t") &&
+                        QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy))
+                        return ast->WCharTy.getAsOpaquePtr();
+                    if (streq(type_name, "void") &&
+                        QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy))
+                        return ast->VoidTy.getAsOpaquePtr();
+                    if (strstr(type_name, "long long") &&
+                        QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
+                        return ast->LongLongTy.getAsOpaquePtr();
+                    if (strstr(type_name, "long") &&
+                        QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
+                        return ast->LongTy.getAsOpaquePtr();
+                    if (strstr(type_name, "short") &&
+                        QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
+                        return ast->ShortTy.getAsOpaquePtr();
+                    if (strstr(type_name, "char"))
+                    {
+                        if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
+                            return ast->CharTy.getAsOpaquePtr();
+                        if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
+                            return ast->SignedCharTy.getAsOpaquePtr();
+                    }
+                    if (strstr(type_name, "int"))
+                    {
+                        if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
+                            return ast->IntTy.getAsOpaquePtr();
+                        if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
+                            return ast->Int128Ty.getAsOpaquePtr();
+                    }
+                }
+                // We weren't able to match up a type name, just search by size
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
+                    return ast->CharTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy))
+                    return ast->ShortTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy))
+                    return ast->IntTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy))
+                    return ast->LongTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy))
+                    return ast->LongLongTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty))
+                    return ast->Int128Ty.getAsOpaquePtr();
+                break;
+                
+            case DW_ATE_signed_char:
+                if (type_name)
+                {
+                    if (streq(type_name, "signed char"))
+                    {
+                        if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
+                            return ast->SignedCharTy.getAsOpaquePtr();
+                    }
+                }
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy))
+                    return ast->CharTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy))
+                    return ast->SignedCharTy.getAsOpaquePtr();
+                break;
+                
+            case DW_ATE_unsigned:
+                if (type_name)
+                {
+                    if (strstr(type_name, "long long"))
+                    {
+                        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
+                            return ast->UnsignedLongLongTy.getAsOpaquePtr();
+                    }
+                    else if (strstr(type_name, "long"))
+                    {
+                        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
+                            return ast->UnsignedLongTy.getAsOpaquePtr();
+                    }
+                    else if (strstr(type_name, "short"))
+                    {
+                        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
+                            return ast->UnsignedShortTy.getAsOpaquePtr();
+                    }
+                    else if (strstr(type_name, "char"))
+                    {
+                        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
+                            return ast->UnsignedCharTy.getAsOpaquePtr();
+                    }
+                    else if (strstr(type_name, "int"))
+                    {
+                        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
+                            return ast->UnsignedIntTy.getAsOpaquePtr();
+                        if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
+                            return ast->UnsignedInt128Ty.getAsOpaquePtr();
+                    }
+                }
+                // We weren't able to match up a type name, just search by size
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
+                    return ast->UnsignedCharTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
+                    return ast->UnsignedShortTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy))
+                    return ast->UnsignedIntTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy))
+                    return ast->UnsignedLongTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy))
+                    return ast->UnsignedLongLongTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty))
+                    return ast->UnsignedInt128Ty.getAsOpaquePtr();
+                break;
+                
+            case DW_ATE_unsigned_char:
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy))
+                    return ast->UnsignedCharTy.getAsOpaquePtr();
+                if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy))
+                    return ast->UnsignedShortTy.getAsOpaquePtr();
+                break;
+                
+            case DW_ATE_imaginary_float:
+                break;
+                
+            case DW_ATE_UTF:
+                if (type_name)
+                {
+                    if (streq(type_name, "char16_t"))
+                    {
+                        return ast->Char16Ty.getAsOpaquePtr();
+                    }
+                    else if (streq(type_name, "char32_t"))
+                    {
+                        return ast->Char32Ty.getAsOpaquePtr();
+                    }
+                }
+                break;
+        }
+    }
+    // This assert should fire for anything that we don't catch above so we know
+    // to fix any issues we run into.
+    if (type_name)
+    {
+        Host::SystemLog (Host::eSystemLogError, "error: need to add support for DW_TAG_base_type '%s' encoded with DW_ATE = 0x%x, bit_size = %u\n", type_name, dw_ate, bit_size);
+    }
+    else
+    {
+        Host::SystemLog (Host::eSystemLogError, "error: need to add support for DW_TAG_base_type encoded with DW_ATE = 0x%x, bit_size = %u\n", dw_ate, bit_size);
+    }
+    return NULL;
+}
+
+clang_type_t
+ClangASTContext::GetBuiltInType_void(ASTContext *ast)
+{
+    return ast->VoidTy.getAsOpaquePtr();
+}
+
+clang_type_t
+ClangASTContext::GetBuiltInType_bool()
+{
+    return getASTContext()->BoolTy.getAsOpaquePtr();
+}
+
+clang_type_t
+ClangASTContext::GetBuiltInType_objc_id()
+{
+    return getASTContext()->getObjCIdType().getAsOpaquePtr();
+}
+
+clang_type_t
+ClangASTContext::GetBuiltInType_objc_Class()
+{
+    return getASTContext()->getObjCClassType().getAsOpaquePtr();
+}
+
+clang_type_t
+ClangASTContext::GetBuiltInType_objc_selector()
+{
+    return getASTContext()->getObjCSelType().getAsOpaquePtr();
+}
+
+clang_type_t
+ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast)
+{
+    return ast->UnknownAnyTy.getAsOpaquePtr();
+}
+
+clang_type_t
+ClangASTContext::GetCStringType (bool is_const)
+{
+    QualType char_type(getASTContext()->CharTy);
+    
+    if (is_const)
+        char_type.addConst();
+    
+    return getASTContext()->getPointerType(char_type).getAsOpaquePtr();
+}
+
+clang_type_t
+ClangASTContext::GetVoidType()
+{
+    return GetVoidType(getASTContext());
+}
+
+clang_type_t
+ClangASTContext::GetVoidType(ASTContext *ast)
+{
+    return ast->VoidTy.getAsOpaquePtr();
+}
+
+clang_type_t
+ClangASTContext::GetVoidPtrType (bool is_const)
+{
+    return GetVoidPtrType(getASTContext(), is_const);
+}
+
+clang_type_t
+ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const)
+{
+    QualType void_ptr_type(ast->VoidPtrTy);
+    
+    if (is_const)
+        void_ptr_type.addConst();
+    
+    return void_ptr_type.getAsOpaquePtr();
+}
+
+clang::DeclContext *
+ClangASTContext::GetTranslationUnitDecl (clang::ASTContext *ast)
+{
+    return ast->getTranslationUnitDecl();
+}
+
+clang_type_t
+ClangASTContext::CopyType (ASTContext *dst_ast, 
+                           ASTContext *src_ast,
+                           clang_type_t clang_type)
+{
+    FileSystemOptions file_system_options;
+    FileManager file_manager (file_system_options);
+    ASTImporter importer(*dst_ast, file_manager,
+                         *src_ast, file_manager,
+                         false);
+    
+    QualType src (QualType::getFromOpaquePtr(clang_type));
+    QualType dst (importer.Import(src));
+    
+    return dst.getAsOpaquePtr();
+}
+
+
+clang::Decl *
+ClangASTContext::CopyDecl (ASTContext *dst_ast, 
+                           ASTContext *src_ast,
+                           clang::Decl *source_decl)
+{    
+    FileSystemOptions file_system_options;
+    FileManager file_manager (file_system_options);
+    ASTImporter importer(*dst_ast, file_manager,
+                         *src_ast, file_manager,
+                         false);
+    
+    return importer.Import(source_decl);
+}
+
+bool
+ClangASTContext::AreTypesSame (ASTContext *ast,
+                               clang_type_t type1,
+                               clang_type_t type2,
+                               bool ignore_qualifiers)
+{
+    if (type1 == type2)
+        return true;
+
+    QualType type1_qual = QualType::getFromOpaquePtr(type1);
+    QualType type2_qual = QualType::getFromOpaquePtr(type2);
+    
+    if (ignore_qualifiers)
+    {
+        type1_qual = type1_qual.getUnqualifiedType();
+        type2_qual = type2_qual.getUnqualifiedType();
+    }
+    
+    return ast->hasSameType (type1_qual,
+                             type2_qual);
+}
+
+#pragma mark CVR modifiers
+
+clang_type_t
+ClangASTContext::AddConstModifier (clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        QualType result(QualType::getFromOpaquePtr(clang_type));
+        result.addConst();
+        return result.getAsOpaquePtr();
+    }
+    return NULL;
+}
+
+clang_type_t
+ClangASTContext::AddRestrictModifier (clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        QualType result(QualType::getFromOpaquePtr(clang_type));
+        result.getQualifiers().setRestrict (true);
+        return result.getAsOpaquePtr();
+    }
+    return NULL;
+}
+
+clang_type_t
+ClangASTContext::AddVolatileModifier (clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        QualType result(QualType::getFromOpaquePtr(clang_type));
+        result.getQualifiers().setVolatile (true);
+        return result.getAsOpaquePtr();
+    }
+    return NULL;
+}
+
+
+clang_type_t
+ClangASTContext::GetTypeForDecl (TagDecl *decl)
+{
+    // No need to call the getASTContext() accessor (which can create the AST
+    // if it isn't created yet, because we can't have created a decl in this
+    // AST if our AST didn't already exist...
+    if (m_ast_ap.get())
+        return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr();
+    return NULL;
+}
+
+clang_type_t
+ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl)
+{
+    // No need to call the getASTContext() accessor (which can create the AST
+    // if it isn't created yet, because we can't have created a decl in this
+    // AST if our AST didn't already exist...
+    if (m_ast_ap.get())
+        return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr();
+    return NULL;
+}
+
+#pragma mark Structure, Unions, Classes
+
+clang_type_t
+ClangASTContext::CreateRecordType (DeclContext *decl_ctx, AccessType access_type, const char *name, int kind, LanguageType language, uint64_t metadata)
+{
+    ASTContext *ast = getASTContext();
+    assert (ast != NULL);
+     
+    if (decl_ctx == NULL)
+        decl_ctx = ast->getTranslationUnitDecl();
+
+
+    if (language == eLanguageTypeObjC || language == eLanguageTypeObjC_plus_plus)
+    {
+        bool isForwardDecl = true;
+        bool isInternal = false;
+        return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal, metadata);
+    }
+
+    // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
+    // we will need to update this code. I was told to currently always use
+    // the CXXRecordDecl class since we often don't know from debug information
+    // if something is struct or a class, so we default to always use the more
+    // complete definition just in case.
+    CXXRecordDecl *decl = CXXRecordDecl::Create (*ast,
+                                                 (TagDecl::TagKind)kind,
+                                                 decl_ctx,
+                                                 SourceLocation(),
+                                                 SourceLocation(),
+                                                 name && name[0] ? &ast->Idents.get(name) : NULL);
+    
+    if (decl)
+        SetMetadata(ast, (uintptr_t)decl, metadata);
+    
+    if (decl_ctx)
+    {
+        if (access_type != eAccessNone)
+            decl->setAccess (ConvertAccessTypeToAccessSpecifier (access_type));
+        decl_ctx->addDecl (decl);
+    }
+    return ast->getTagDeclType(decl).getAsOpaquePtr();
+}
+
+static TemplateParameterList *
+CreateTemplateParameterList (ASTContext *ast, 
+                             const ClangASTContext::TemplateParameterInfos &template_param_infos,
+                             llvm::SmallVector<NamedDecl *, 8> &template_param_decls)
+{
+    const bool parameter_pack = false;
+    const bool is_typename = false;
+    const unsigned depth = 0;
+    const size_t num_template_params = template_param_infos.GetSize();
+    for (size_t i=0; i<num_template_params; ++i)
+    {
+        const char *name = template_param_infos.names[i];
+<<<<<<< .working
+        if (template_param_infos.args[i].getAsIntegral().getBoolValue())
+=======
+        if (template_param_infos.args[i].getKind() == TemplateArgument::Integral)
+>>>>>>> .merge-right.r164814
+        {
+            template_param_decls.push_back (NonTypeTemplateParmDecl::Create (*ast,
+                                                                             ast->getTranslationUnitDecl(), // Is this the right decl context?, SourceLocation StartLoc,
+                                                                             SourceLocation(), 
+                                                                             SourceLocation(), 
+                                                                             depth, 
+                                                                             i,
+                                                                             &ast->Idents.get(name), 
+                                                                             template_param_infos.args[i].getIntegralType(), 
+                                                                             parameter_pack, 
+                                                                             NULL));
+            
+        }
+        else
+        {
+            template_param_decls.push_back (TemplateTypeParmDecl::Create (*ast, 
+                                                                          ast->getTranslationUnitDecl(), // Is this the right decl context?
+                                                                          SourceLocation(),
+                                                                          SourceLocation(),
+                                                                          depth, 
+                                                                          i,
+                                                                          &ast->Idents.get(name), 
+                                                                          is_typename,
+                                                                          parameter_pack));
+        }
+    }
+
+    TemplateParameterList *template_param_list = TemplateParameterList::Create (*ast,
+                                                                                SourceLocation(),
+                                                                                SourceLocation(),
+                                                                                &template_param_decls.front(),
+                                                                                template_param_decls.size(),
+                                                                                SourceLocation());
+    return template_param_list;
+}
+
+clang::FunctionTemplateDecl *
+ClangASTContext::CreateFunctionTemplateDecl (clang::DeclContext *decl_ctx,
+                                             clang::FunctionDecl *func_decl,
+                                             const char *name, 
+                                             const TemplateParameterInfos &template_param_infos)
+{
+//    /// \brief Create a function template node.
+    ASTContext *ast = getASTContext();
+    
+    llvm::SmallVector<NamedDecl *, 8> template_param_decls;
+
+    TemplateParameterList *template_param_list = CreateTemplateParameterList (ast,
+                                                                              template_param_infos, 
+                                                                              template_param_decls);
+    FunctionTemplateDecl *func_tmpl_decl = FunctionTemplateDecl::Create (*ast,
+                                                                         decl_ctx,
+                                                                         func_decl->getLocation(),
+                                                                         func_decl->getDeclName(),
+                                                                         template_param_list,
+                                                                         func_decl);
+    
+    for (size_t i=0, template_param_decl_count = template_param_decls.size();
+         i < template_param_decl_count;
+         ++i)
+    {
+        // TODO: verify which decl context we should put template_param_decls into..
+        template_param_decls[i]->setDeclContext (func_decl); 
+    }
+
+    return func_tmpl_decl;
+}
+
+void
+ClangASTContext::CreateFunctionTemplateSpecializationInfo (FunctionDecl *func_decl, 
+                                                           clang::FunctionTemplateDecl *func_tmpl_decl,
+                                                           const TemplateParameterInfos &infos)
+{
+    TemplateArgumentList template_args (TemplateArgumentList::OnStack,
+                                        infos.args.data(), 
+                                        infos.args.size());
+
+    func_decl->setFunctionTemplateSpecialization (func_tmpl_decl,
+                                                  &template_args,
+                                                  NULL);
+}
+
+
+ClassTemplateDecl *
+ClangASTContext::CreateClassTemplateDecl (DeclContext *decl_ctx,
+                                          lldb::AccessType access_type,
+                                          const char *class_name, 
+                                          int kind, 
+                                          const TemplateParameterInfos &template_param_infos)
+{
+    ASTContext *ast = getASTContext();
+    
+    ClassTemplateDecl *class_template_decl = NULL;
+    if (decl_ctx == NULL)
+        decl_ctx = ast->getTranslationUnitDecl();
+    
+    IdentifierInfo &identifier_info = ast->Idents.get(class_name);
+    DeclarationName decl_name (&identifier_info);
+
+    clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
+    for (clang::DeclContext::lookup_iterator pos = result.first, end = result.second; pos != end; ++pos) 
+    {
+        class_template_decl = dyn_cast<clang::ClassTemplateDecl>(*pos);
+        if (class_template_decl)
+            return class_template_decl;
+    }
+
+    llvm::SmallVector<NamedDecl *, 8> template_param_decls;
+
+    TemplateParameterList *template_param_list = CreateTemplateParameterList (ast,
+                                                                              template_param_infos, 
+                                                                              template_param_decls);
+
+    CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create (*ast,
+                                                              (TagDecl::TagKind)kind,
+                                                              decl_ctx,  // What decl context do we use here? TU? The actual decl context?
+                                                              SourceLocation(),
+                                                              SourceLocation(),
+                                                              &identifier_info);
+
+    for (size_t i=0, template_param_decl_count = template_param_decls.size();
+         i < template_param_decl_count;
+         ++i)
+    {
+        template_param_decls[i]->setDeclContext (template_cxx_decl);
+    }
+
+    // With templated classes, we say that a class is templated with
+    // specializations, but that the bare class has no functions.
+    template_cxx_decl->startDefinition();
+    template_cxx_decl->completeDefinition();
+    
+    class_template_decl = ClassTemplateDecl::Create (*ast,
+                                                     decl_ctx,  // What decl context do we use here? TU? The actual decl context?
+                                                     SourceLocation(),
+                                                     decl_name,
+                                                     template_param_list,
+                                                     template_cxx_decl,
+                                                     NULL);
+    
+    if (class_template_decl)
+    {
+        if (access_type != eAccessNone)
+            class_template_decl->setAccess (ConvertAccessTypeToAccessSpecifier (access_type));
+        
+        //if (TagDecl *ctx_tag_decl = dyn_cast<TagDecl>(decl_ctx))
+        //    CompleteTagDeclarationDefinition(GetTypeForDecl(ctx_tag_decl));
+        
+        decl_ctx->addDecl (class_template_decl);
+        
+#ifdef LLDB_CONFIGURATION_DEBUG
+        VerifyDecl(class_template_decl);
+#endif
+    }
+
+    return class_template_decl;
+}
+
+
+ClassTemplateSpecializationDecl *
+ClangASTContext::CreateClassTemplateSpecializationDecl (DeclContext *decl_ctx,
+                                                        ClassTemplateDecl *class_template_decl,
+                                                        int kind,
+                                                        const TemplateParameterInfos &template_param_infos)
+{
+    ASTContext *ast = getASTContext();
+    ClassTemplateSpecializationDecl *class_template_specialization_decl = ClassTemplateSpecializationDecl::Create (*ast, 
+                                                                                                                   (TagDecl::TagKind)kind,
+                                                                                                                   decl_ctx,
+                                                                                                                   SourceLocation(), 
+                                                                                                                   SourceLocation(),
+                                                                                                                   class_template_decl,
+                                                                                                                   &template_param_infos.args.front(),
+                                                                                                                   template_param_infos.args.size(),
+                                                                                                                   NULL);
+    
+    return class_template_specialization_decl;
+}
+
+lldb::clang_type_t
+ClangASTContext::CreateClassTemplateSpecializationType (ClassTemplateSpecializationDecl *class_template_specialization_decl)
+{
+    if (class_template_specialization_decl)
+    {
+        ASTContext *ast = getASTContext();
+        if (ast)
+            return ast->getTagDeclType(class_template_specialization_decl).getAsOpaquePtr();
+    }
+    return NULL;
+}
+
+bool
+ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern)
+{
+    if (clang_type == NULL)
+        return false;
+
+    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+    case clang::Type::Record:
+        {
+            CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+            if (cxx_record_decl)
+            {
+                cxx_record_decl->setHasExternalLexicalStorage (has_extern);
+                cxx_record_decl->setHasExternalVisibleStorage (has_extern);
+                return true;
+            }
+        }
+        break;
+
+    case clang::Type::Enum:
+        {
+            EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl();
+            if (enum_decl)
+            {
+                enum_decl->setHasExternalLexicalStorage (has_extern);
+                enum_decl->setHasExternalVisibleStorage (has_extern);
+                return true;
+            }
+        }
+        break;
+
+    case clang::Type::ObjCObject:
+    case clang::Type::ObjCInterface:
+        {
+            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+            assert (objc_class_type);
+            if (objc_class_type)
+            {
+                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+            
+                if (class_interface_decl)
+                {
+                    class_interface_decl->setHasExternalLexicalStorage (has_extern);
+                    class_interface_decl->setHasExternalVisibleStorage (has_extern);
+                    return true;
+                }
+            }
+        }
+        break;
+
+    case clang::Type::Typedef:
+        return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern);
+    
+    case clang::Type::Elaborated:
+        return ClangASTContext::SetHasExternalStorage (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), has_extern);
+
+    default:
+        break;
+    }
+    return false;
+}
+
+static bool
+IsOperator (const char *name, OverloadedOperatorKind &op_kind)
+{
+    if (name == NULL || name[0] == '\0')
+        return false;
+    
+#define OPERATOR_PREFIX "operator"
+#define OPERATOR_PREFIX_LENGTH (sizeof (OPERATOR_PREFIX) - 1)
+    
+    const char *post_op_name = NULL;
+
+    bool no_space = true;
+    
+    if (::strncmp(name, OPERATOR_PREFIX, OPERATOR_PREFIX_LENGTH))
+        return false;
+    
+    post_op_name = name + OPERATOR_PREFIX_LENGTH;
+    
+    if (post_op_name[0] == ' ')
+    {
+        post_op_name++;
+        no_space = false;
+    }
+    
+#undef OPERATOR_PREFIX
+#undef OPERATOR_PREFIX_LENGTH
+    
+    // This is an operator, set the overloaded operator kind to invalid
+    // in case this is a conversion operator...
+    op_kind = NUM_OVERLOADED_OPERATORS;
+
+    switch (post_op_name[0])
+    {
+    default:
+        if (no_space)
+            return false;
+        break;
+    case 'n':
+        if (no_space)
+            return false;
+        if  (strcmp (post_op_name, "new") == 0)  
+            op_kind = OO_New;
+        else if (strcmp (post_op_name, "new[]") == 0)  
+            op_kind = OO_Array_New;
+        break;
+
+    case 'd':
+        if (no_space)
+            return false;
+        if (strcmp (post_op_name, "delete") == 0)
+            op_kind = OO_Delete;
+        else if (strcmp (post_op_name, "delete[]") == 0)  
+            op_kind = OO_Array_Delete;
+        break;
+    
+    case '+':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Plus;
+        else if (post_op_name[2] == '\0')
+        {
+            if (post_op_name[1] == '=')
+                op_kind = OO_PlusEqual;
+            else if (post_op_name[1] == '+')
+                op_kind = OO_PlusPlus;
+        }
+        break;
+
+    case '-':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Minus;
+        else if (post_op_name[2] == '\0')
+        {
+            switch (post_op_name[1])
+            {
+            case '=': op_kind = OO_MinusEqual; break;
+            case '-': op_kind = OO_MinusMinus; break;
+            case '>': op_kind = OO_Arrow; break;
+            }
+        }
+        else if (post_op_name[3] == '\0')
+        {
+            if (post_op_name[2] == '*')
+                op_kind = OO_ArrowStar; break;
+        }
+        break;
+        
+    case '*':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Star;
+        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+            op_kind = OO_StarEqual;
+        break;
+    
+    case '/':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Slash;
+        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+            op_kind = OO_SlashEqual;
+        break;
+    
+    case '%':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Percent;
+        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+            op_kind = OO_PercentEqual;
+        break;
+
+
+    case '^':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Caret;
+        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+            op_kind = OO_CaretEqual;
+        break;
+
+    case '&':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Amp;
+        else if (post_op_name[2] == '\0')
+        {
+            switch (post_op_name[1])
+            {
+            case '=': op_kind = OO_AmpEqual; break;
+            case '&': op_kind = OO_AmpAmp; break;
+            }   
+        }
+        break;
+
+    case '|':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Pipe;
+        else if (post_op_name[2] == '\0')
+        {
+            switch (post_op_name[1])
+            {
+            case '=': op_kind = OO_PipeEqual; break;
+            case '|': op_kind = OO_PipePipe; break;
+            }   
+        }
+        break;
+    
+    case '~':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Tilde;
+        break;
+    
+    case '!':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Exclaim;
+        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+            op_kind = OO_ExclaimEqual;
+        break;
+
+    case '=':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Equal;
+        else if (post_op_name[1] == '=' && post_op_name[2] == '\0')
+            op_kind = OO_EqualEqual;
+        break;
+    
+    case '<':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Less;
+        else if (post_op_name[2] == '\0')
+        {
+            switch (post_op_name[1])
+            {
+            case '<': op_kind = OO_LessLess; break;
+            case '=': op_kind = OO_LessEqual; break;
+            }   
+        }
+        else if (post_op_name[3] == '\0')
+        {
+            if (post_op_name[2] == '=')
+                op_kind = OO_LessLessEqual;
+        }
+        break;
+
+    case '>':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Greater;
+        else if (post_op_name[2] == '\0')
+        {
+            switch (post_op_name[1])
+            {
+            case '>': op_kind = OO_GreaterGreater; break;
+            case '=': op_kind = OO_GreaterEqual; break;
+            }   
+        }
+        else if (post_op_name[1] == '>' && 
+                 post_op_name[2] == '=' && 
+                 post_op_name[3] == '\0')
+        {
+                op_kind = OO_GreaterGreaterEqual;
+        }
+        break;
+        
+    case ',':
+        if (post_op_name[1] == '\0')
+            op_kind = OO_Comma;
+        break;
+    
+    case '(':
+        if (post_op_name[1] == ')' && post_op_name[2] == '\0')
+            op_kind = OO_Call;
+        break;
+    
+    case '[':
+        if (post_op_name[1] == ']' && post_op_name[2] == '\0')
+            op_kind = OO_Subscript;
+        break;
+    }
+
+    return true;
+}
+
+static inline bool
+check_op_param (uint32_t op_kind, bool unary, bool binary, uint32_t num_params)
+{
+    // Special-case call since it can take any number of operands
+    if(op_kind == OO_Call)
+        return true;
+    
+    // The parameter count doens't include "this"
+    if (num_params == 0)
+        return unary;
+    if (num_params == 1)
+        return binary;
+    else 
+    return false;
+}
+
+bool
+ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, uint32_t num_params)
+{
+    switch (op_kind)
+    {
+    default:
+        break;
+    // C++ standard allows any number of arguments to new/delete
+    case OO_New:
+    case OO_Array_New:
+    case OO_Delete:
+    case OO_Array_Delete:
+        return true;
+    }
+    
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) case OO_##Name: return check_op_param (op_kind, Unary, Binary, num_params);
+    switch (op_kind)
+    {
+#include "clang/Basic/OperatorKinds.def"
+        default: break;
+    }
+    return false;
+}
+
+CXXMethodDecl *
+ClangASTContext::AddMethodToCXXRecordType
+(
+    ASTContext *ast,
+    clang_type_t record_opaque_type,
+    const char *name,
+    clang_type_t method_opaque_type,
+    lldb::AccessType access,
+    bool is_virtual,
+    bool is_static,
+    bool is_inline,
+    bool is_explicit,
+    bool is_attr_used,
+    bool is_artificial
+)
+{
+    if (!record_opaque_type || !method_opaque_type || !name)
+        return NULL;
+    
+    assert(ast);
+    
+    IdentifierTable *identifier_table = &ast->Idents;
+    
+    assert(identifier_table);
+    
+    QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type));
+
+    CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl();
+    
+    if (cxx_record_decl == NULL)
+        return NULL;
+    
+    QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
+    
+    CXXMethodDecl *cxx_method_decl = NULL;
+    
+    DeclarationName decl_name (&identifier_table->get(name));
+
+    const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr());
+    
+    if (function_Type == NULL)
+        return NULL;
+
+    const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type));
+    
+    if (!method_function_prototype)
+        return NULL;
+    
+    unsigned int num_params = method_function_prototype->getNumArgs();
+    
+    CXXDestructorDecl *cxx_dtor_decl(NULL);
+    CXXConstructorDecl *cxx_ctor_decl(NULL);
+    
+    if (name[0] == '~')
+    {
+        cxx_dtor_decl = CXXDestructorDecl::Create (*ast,
+                                                   cxx_record_decl,
+                                                   SourceLocation(),
+                                                   DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
+                                                   method_qual_type,
+                                                   NULL,
+                                                   is_inline,
+                                                   is_artificial);
+        cxx_method_decl = cxx_dtor_decl;
+    }
+    else if (decl_name == cxx_record_decl->getDeclName())
+    {
+       cxx_ctor_decl = CXXConstructorDecl::Create (*ast,
+                                                   cxx_record_decl,
+                                                   SourceLocation(),
+                                                   DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()),
+                                                   method_qual_type,
+                                                   NULL, // TypeSourceInfo *
+                                                   is_explicit, 
+                                                   is_inline,
+                                                   is_artificial,
+                                                   false /*is_constexpr*/);
+        cxx_method_decl = cxx_ctor_decl;
+    }
+    else
+    {   
+    
+        OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS;
+        if (IsOperator (name, op_kind))
+        {
+            if (op_kind != NUM_OVERLOADED_OPERATORS)
+            {
+                // Check the number of operator parameters. Sometimes we have 
+                // seen bad DWARF that doesn't correctly describe operators and
+                // if we try to create a methed and add it to the class, clang
+                // will assert and crash, so we need to make sure things are
+                // acceptable.
+                if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params))
+                    return NULL;
+                cxx_method_decl = CXXMethodDecl::Create (*ast,
+                                                         cxx_record_decl,
+                                                         SourceLocation(),
+                                                         DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()),
+                                                         method_qual_type,
+                                                         NULL, // TypeSourceInfo *
+                                                         is_static,
+                                                         SC_None,
+                                                         is_inline,
+                                                         false /*is_constexpr*/,
+                                                         SourceLocation());
+            }
+            else if (num_params == 0)
+            {
+                // Conversion operators don't take params...
+                cxx_method_decl = CXXConversionDecl::Create (*ast,
+                                                             cxx_record_decl,
+                                                             SourceLocation(),
+                                                             DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()),
+                                                             method_qual_type,
+                                                             NULL, // TypeSourceInfo *
+                                                             is_inline,
+                                                             is_explicit,
+                                                             false /*is_constexpr*/,
+                                                             SourceLocation());
+            }
+        }
+        
+        if (cxx_method_decl == NULL)
+        {
+            cxx_method_decl = CXXMethodDecl::Create (*ast,
+                                                     cxx_record_decl,
+                                                     SourceLocation(),
+                                                     DeclarationNameInfo (decl_name, SourceLocation()),
+                                                     method_qual_type,
+                                                     NULL, // TypeSourceInfo *
+                                                     is_static,
+                                                     SC_None,
+                                                     is_inline,
+                                                     false /*is_constexpr*/,
+                                                     SourceLocation());
+        }
+    }
+
+    AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access);
+    
+    cxx_method_decl->setAccess (access_specifier);
+    cxx_method_decl->setVirtualAsWritten (is_virtual);
+    
+    if (is_attr_used)
+        cxx_method_decl->addAttr(::new (*ast) UsedAttr(SourceRange(), *ast));
+    
+    // Populate the method decl with parameter decls
+    
+    llvm::SmallVector<ParmVarDecl *, 12> params;
+    
+    for (int param_index = 0;
+         param_index < num_params;
+         ++param_index)
+    {
+        params.push_back (ParmVarDecl::Create (*ast,
+                                               cxx_method_decl,
+                                               SourceLocation(),
+                                               SourceLocation(),
+                                               NULL, // anonymous
+                                               method_function_prototype->getArgType(param_index), 
+                                               NULL,
+                                               SC_None,
+                                               SC_None,
+                                               NULL));
+    }
+    
+    cxx_method_decl->setParams (ArrayRef<ParmVarDecl*>(params));
+    
+    cxx_record_decl->addDecl (cxx_method_decl);
+    
+    // Sometimes the debug info will mention a constructor (default/copy/move), 
+    // destructor, or assignment operator (copy/move) but there won't be any
+    // version of this in the code. So we check if the function was artificially
+    // generated and if it is trivial and this lets the compiler/backend know
+    // that it can inline the IR for these when it needs to and we can avoid a
+    // "missing function" error when running expressions.
+    
+    if (is_artificial)
+    {
+        if (cxx_ctor_decl && 
+            ((cxx_ctor_decl->isDefaultConstructor() && cxx_record_decl->hasTrivialDefaultConstructor ()) ||
+             (cxx_ctor_decl->isCopyConstructor()    && cxx_record_decl->hasTrivialCopyConstructor    ()) ||
+             (cxx_ctor_decl->isMoveConstructor()    && cxx_record_decl->hasTrivialMoveConstructor    ()) ))
+        {
+            cxx_ctor_decl->setDefaulted();
+            cxx_ctor_decl->setTrivial(true);
+        }
+        else if (cxx_dtor_decl)
+        {
+            if (cxx_record_decl->hasTrivialDestructor())
+            {
+                cxx_dtor_decl->setDefaulted();
+                cxx_dtor_decl->setTrivial(true);
+            }
+        }
+        else if ((cxx_method_decl->isCopyAssignmentOperator() && cxx_record_decl->hasTrivialCopyAssignment()) ||
+                 (cxx_method_decl->isMoveAssignmentOperator() && cxx_record_decl->hasTrivialMoveAssignment()))
+        {
+            cxx_method_decl->setDefaulted();
+            cxx_method_decl->setTrivial(true);
+        }
+    }
+    
+#ifdef LLDB_CONFIGURATION_DEBUG
+    VerifyDecl(cxx_method_decl);
+#endif
+
+//    printf ("decl->isPolymorphic()             = %i\n", cxx_record_decl->isPolymorphic());
+//    printf ("decl->isAggregate()               = %i\n", cxx_record_decl->isAggregate());
+//    printf ("decl->isPOD()                     = %i\n", cxx_record_decl->isPOD());
+//    printf ("decl->isEmpty()                   = %i\n", cxx_record_decl->isEmpty());
+//    printf ("decl->isAbstract()                = %i\n", cxx_record_decl->isAbstract());
+//    printf ("decl->hasTrivialConstructor()     = %i\n", cxx_record_decl->hasTrivialConstructor());
+//    printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor());
+//    printf ("decl->hasTrivialCopyAssignment()  = %i\n", cxx_record_decl->hasTrivialCopyAssignment());
+//    printf ("decl->hasTrivialDestructor()      = %i\n", cxx_record_decl->hasTrivialDestructor());
+    return cxx_method_decl;
+}
+
+clang::FieldDecl *
+ClangASTContext::AddFieldToRecordType 
+(
+    ASTContext *ast,
+    clang_type_t record_clang_type, 
+    const char *name, 
+    clang_type_t field_type, 
+    AccessType access, 
+    uint32_t bitfield_bit_size
+)
+{
+    if (record_clang_type == NULL || field_type == NULL)
+        return NULL;
+
+    FieldDecl *field = NULL;
+    IdentifierTable *identifier_table = &ast->Idents;
+
+    assert (ast != NULL);
+    assert (identifier_table != NULL);
+
+    QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
+
+    const clang::Type *clang_type = record_qual_type.getTypePtr();
+    if (clang_type)
+    {
+        const RecordType *record_type = dyn_cast<RecordType>(clang_type);
+
+        if (record_type)
+        {
+            RecordDecl *record_decl = record_type->getDecl();
+
+            clang::Expr *bit_width = NULL;
+            if (bitfield_bit_size != 0)
+            {
+                APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
+                bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
+            }
+            field = FieldDecl::Create (*ast,
+<<<<<<< .working
+                                                  record_decl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  name ? &identifier_table->get(name) : NULL, // Identifier
+                                                  QualType::getFromOpaquePtr(field_type), // Field type
+                                                  NULL,       // TInfo *
+                                                  bit_width,  // BitWidth
+                                                  false,      // Mutable
+                                                  ICIS_NoInit); // HasInit
+=======
+                                       record_decl,
+                                       SourceLocation(),
+                                       SourceLocation(),
+                                       name ? &identifier_table->get(name) : NULL, // Identifier
+                                       QualType::getFromOpaquePtr(field_type), // Field type
+                                       NULL,            // TInfo *
+                                       bit_width,       // BitWidth
+                                       false,           // Mutable
+                                       ICIS_NoInit);    // HasInit
+>>>>>>> .merge-right.r164814
+            
+            if (!name) {
+                // Determine whether this field corresponds to an anonymous
+                // struct or union.
+                if (const TagType *TagT = field->getType()->getAs<TagType>()) {
+                  if (RecordDecl *Rec = dyn_cast<RecordDecl>(TagT->getDecl()))
+                    if (!Rec->getDeclName()) {
+                      Rec->setAnonymousStructOrUnion(true);
+                      field->setImplicit();
+
+                    }
+                }
+            }
+
+            field->setAccess (ConvertAccessTypeToAccessSpecifier (access));
+
+            if (field)
+            {
+                record_decl->addDecl(field);
+                
+#ifdef LLDB_CONFIGURATION_DEBUG
+                VerifyDecl(field);
+#endif
+            }
+        }
+        else
+        {
+            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type);
+            if (objc_class_type)
+            {
+                bool is_synthesized = false;
+                field = ClangASTContext::AddObjCClassIVar (ast,
+                                                   record_clang_type,
+                                                   name,
+                                                   field_type,
+                                                   access,
+                                                   bitfield_bit_size,
+                                                   is_synthesized);
+            }
+        }
+    }
+    return field;
+}
+
+static clang::AccessSpecifier UnifyAccessSpecifiers (clang::AccessSpecifier lhs,
+                                                     clang::AccessSpecifier rhs)
+{
+    clang::AccessSpecifier ret = lhs;
+    
+    // Make the access equal to the stricter of the field and the nested field's access
+    switch (ret)
+    {
+        case clang::AS_none:
+            break;
+        case clang::AS_private:
+            break;
+        case clang::AS_protected:
+            if (rhs == AS_private)
+                ret = AS_private;
+            break;
+        case clang::AS_public:
+            ret = rhs;
+            break;
+    }
+    
+    return ret;
+}
+
+void
+ClangASTContext::BuildIndirectFields (clang::ASTContext *ast,
+                                      lldb::clang_type_t record_clang_type)
+{
+    QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type));
+
+    const RecordType *record_type = record_qual_type->getAs<RecordType>();
+    
+    if (!record_type)
+        return;
+    
+    RecordDecl *record_decl = record_type->getDecl();
+    
+    if (!record_decl)
+        return;
+    
+    typedef llvm::SmallVector <IndirectFieldDecl *, 1> IndirectFieldVector;
+    
+    IndirectFieldVector indirect_fields;
+    
+    for (RecordDecl::field_iterator fi = record_decl->field_begin(), fe = record_decl->field_end();
+         fi != fe;
+         ++fi)
+    {
+        if (fi->isAnonymousStructOrUnion())
+        {
+            QualType field_qual_type = fi->getType();
+            
+            const RecordType *field_record_type = field_qual_type->getAs<RecordType>();
+            
+            if (!field_record_type)
+                continue;
+            
+            RecordDecl *field_record_decl = field_record_type->getDecl();
+            
+            if (!field_record_decl)
+                continue;
+            
+            for (RecordDecl::decl_iterator di = field_record_decl->decls_begin(), de = field_record_decl->decls_end();
+                 di != de;
+                 ++di)
+            {
+                if (FieldDecl *nested_field_decl = dyn_cast<FieldDecl>(*di))
+                {
+                    NamedDecl **chain = new (*ast) NamedDecl*[2];
+                    chain[0] = *fi;
+                    chain[1] = nested_field_decl;
+                    IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast,
+                                                                                  record_decl,
+                                                                                  SourceLocation(),
+                                                                                  nested_field_decl->getIdentifier(),
+                                                                                  nested_field_decl->getType(),
+                                                                                  chain,
+                                                                                  2);
+                    
+                    indirect_field->setAccess(UnifyAccessSpecifiers(fi->getAccess(),
+                                                                    nested_field_decl->getAccess()));
+                    
+                    indirect_fields.push_back(indirect_field);
+                }
+                else if (IndirectFieldDecl *nested_indirect_field_decl = dyn_cast<IndirectFieldDecl>(*di))
+                {
+                    int nested_chain_size = nested_indirect_field_decl->getChainingSize();
+                    NamedDecl **chain = new (*ast) NamedDecl*[nested_chain_size + 1];
+                    chain[0] = *fi;
+                    
+                    int chain_index = 1;
+                    for (IndirectFieldDecl::chain_iterator nci = nested_indirect_field_decl->chain_begin(),
+                         nce = nested_indirect_field_decl->chain_end();
+                         nci < nce;
+                         ++nci)
+                    {
+                        chain[chain_index] = *nci;
+                        chain_index++;
+                    }
+                    
+                    IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast,
+                                                                                  record_decl,
+                                                                                  SourceLocation(),
+                                                                                  nested_indirect_field_decl->getIdentifier(),
+                                                                                  nested_indirect_field_decl->getType(),
+                                                                                  chain,
+                                                                                  nested_chain_size + 1);
+                                        
+                    indirect_field->setAccess(UnifyAccessSpecifiers(fi->getAccess(),
+                                                                    nested_indirect_field_decl->getAccess()));
+                    
+                    indirect_fields.push_back(indirect_field);
+                }
+            }
+        }
+    }
+    
+    for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), ife = indirect_fields.end();
+         ifi < ife;
+         ++ifi)
+    {
+        record_decl->addDecl(*ifi);
+    }
+}
+
+bool
+ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size)
+{
+    return FieldIsBitfield(getASTContext(), field, bitfield_bit_size);
+}
+
+bool
+ClangASTContext::FieldIsBitfield
+(
+    ASTContext *ast,
+    FieldDecl* field,
+    uint32_t& bitfield_bit_size
+)
+{
+    if (ast == NULL || field == NULL)
+        return false;
+
+    if (field->isBitField())
+    {
+        Expr* bit_width_expr = field->getBitWidth();
+        if (bit_width_expr)
+        {
+            llvm::APSInt bit_width_apsint;
+            if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast))
+            {
+                bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX);
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::RecordHasFields (const RecordDecl *record_decl)
+{
+    if (record_decl == NULL)
+        return false;
+
+    if (!record_decl->field_empty())
+        return true;
+
+    // No fields, lets check this is a CXX record and check the base classes
+    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+    if (cxx_record_decl)
+    {
+        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+             base_class != base_class_end;
+             ++base_class)
+        {
+            const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+            if (RecordHasFields(base_class_decl))
+                return true;
+        }
+    }
+    return false;
+}
+
+void
+ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities)
+{
+    if (clang_type)
+    {
+        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+
+        const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
+        if (record_type)
+        {
+            RecordDecl *record_decl = record_type->getDecl();
+            if (record_decl)
+            {
+                uint32_t field_idx;
+                RecordDecl::field_iterator field, field_end;
+                for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0;
+                     field != field_end;
+                     ++field, ++field_idx)
+                {
+                    // If no accessibility was assigned, assign the correct one
+                    if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none)
+                        field->setAccess ((AccessSpecifier)default_accessibility);
+                }
+            }
+        }
+    }
+}
+
+#pragma mark C++ Base Classes
+
+CXXBaseSpecifier *
+ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class)
+{
+    if (base_class_type)
+        return new CXXBaseSpecifier (SourceRange(), 
+                                     is_virtual, 
+                                     base_of_class, 
+                                     ConvertAccessTypeToAccessSpecifier (access), 
+                                     getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)),
+                                     SourceLocation());
+    return NULL;
+}
+
+void
+ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes)
+{
+    for (unsigned i=0; i<num_base_classes; ++i)
+    {
+        delete base_classes[i];
+        base_classes[i] = NULL;
+    }
+}
+
+bool
+ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes)
+{
+    if (class_clang_type)
+    {
+        CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl();
+        if (cxx_record_decl)
+        {
+            cxx_record_decl->setBases(base_classes, num_base_classes);
+            return true;
+        }
+    }
+    return false;
+}
+#pragma mark Objective C Classes
+
+clang_type_t
+ClangASTContext::CreateObjCClass
+(
+    const char *name, 
+    DeclContext *decl_ctx, 
+    bool isForwardDecl, 
+    bool isInternal,
+    uint64_t metadata
+)
+{
+    ASTContext *ast = getASTContext();
+    assert (ast != NULL);
+    assert (name && name[0]);
+    if (decl_ctx == NULL)
+        decl_ctx = ast->getTranslationUnitDecl();
+
+    // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and
+    // we will need to update this code. I was told to currently always use
+    // the CXXRecordDecl class since we often don't know from debug information
+    // if something is struct or a class, so we default to always use the more
+    // complete definition just in case.
+    ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast,
+                                                         decl_ctx,
+                                                         SourceLocation(),
+                                                         &ast->Idents.get(name),
+                                                         NULL,
+                                                         SourceLocation(),
+                                                         /*isForwardDecl,*/
+                                                         isInternal);
+    
+    if (decl)
+        SetMetadata(ast, (uintptr_t)decl, metadata);
+    
+    return ast->getObjCInterfaceType(decl).getAsOpaquePtr();
+}
+
+bool
+ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type)
+{
+    if (class_opaque_type && super_opaque_type)
+    {
+        QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
+        QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type));
+        const clang::Type *class_type = class_qual_type.getTypePtr();
+        const clang::Type *super_type = super_qual_type.getTypePtr();
+        if (class_type && super_type)
+        {
+            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
+            const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type);
+            if (objc_class_type && objc_super_type)
+            {
+                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface();
+                if (class_interface_decl && super_interface_decl)
+                {
+                    class_interface_decl->setSuperClass(super_interface_decl);
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+
+FieldDecl *
+ClangASTContext::AddObjCClassIVar 
+(
+    ASTContext *ast,
+    clang_type_t class_opaque_type, 
+    const char *name, 
+    clang_type_t ivar_opaque_type, 
+    AccessType access, 
+    uint32_t bitfield_bit_size, 
+    bool is_synthesized
+)
+{
+    if (class_opaque_type == NULL || ivar_opaque_type == NULL)
+        return NULL;
+
+    ObjCIvarDecl *field = NULL;
+    
+    IdentifierTable *identifier_table = &ast->Idents;
+
+    assert (ast != NULL);
+    assert (identifier_table != NULL);
+
+    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
+
+    const clang::Type *class_type = class_qual_type.getTypePtr();
+    if (class_type)
+    {
+        const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
+
+        if (objc_class_type)
+        {
+            ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+            
+            if (class_interface_decl)
+            {
+                clang::Expr *bit_width = NULL;
+                if (bitfield_bit_size != 0)
+                {
+                    APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size);
+                    bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation());
+                }
+                
+                field = ObjCIvarDecl::Create (*ast,
+                                              class_interface_decl,
+                                              SourceLocation(),
+                                              SourceLocation(),
+                                              &identifier_table->get(name), // Identifier
+                                              QualType::getFromOpaquePtr(ivar_opaque_type), // Field type
+                                              NULL, // TypeSourceInfo *
+                                              ConvertAccessTypeToObjCIvarAccessControl (access),
+                                              bit_width,
+                                              is_synthesized);
+                
+                if (field)
+                {
+                    class_interface_decl->addDecl(field);
+                    
+#ifdef LLDB_CONFIGURATION_DEBUG
+                    VerifyDecl(field);
+#endif
+                    
+                    return field;
+                }
+            }
+        }
+    }
+    return NULL;
+}
+
+bool
+ClangASTContext::AddObjCClassProperty 
+(
+    ASTContext *ast,
+    clang_type_t class_opaque_type, 
+    const char *property_name,
+    clang_type_t property_opaque_type,  
+    ObjCIvarDecl *ivar_decl,
+    const char *property_setter_name,
+    const char *property_getter_name,
+    uint32_t property_attributes,
+    uint64_t metadata
+)
+{
+    if (class_opaque_type == NULL || property_name == NULL || property_name[0] == '\0')
+        return false;
+
+    IdentifierTable *identifier_table = &ast->Idents;
+
+    assert (ast != NULL);
+    assert (identifier_table != NULL);
+
+    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
+    const clang::Type *class_type = class_qual_type.getTypePtr();
+    if (class_type)
+    {
+        const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
+
+        if (objc_class_type)
+        {
+            ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+            
+            clang_type_t property_opaque_type_to_access = NULL;
+            
+            if (property_opaque_type)
+                property_opaque_type_to_access = property_opaque_type;
+            else if (ivar_decl)
+                property_opaque_type_to_access = ivar_decl->getType().getAsOpaquePtr();
+                        
+            if (class_interface_decl && property_opaque_type_to_access)
+            {
+                clang::TypeSourceInfo *prop_type_source;
+                if (ivar_decl)
+                    prop_type_source = ast->CreateTypeSourceInfo (ivar_decl->getType());
+                else
+                    prop_type_source = ast->CreateTypeSourceInfo (QualType::getFromOpaquePtr(property_opaque_type));
+                
+                ObjCPropertyDecl *property_decl = ObjCPropertyDecl::Create(*ast, 
+                                                                           class_interface_decl, 
+                                                                           SourceLocation(), // Source Location
+                                                                           &identifier_table->get(property_name),
+                                                                           SourceLocation(), //Source Location for AT
+                                                                           SourceLocation(), //Source location for (
+                                                                           prop_type_source
+                                                                           );
+                
+                if (property_decl)
+                {
+                    SetMetadata(ast, (uintptr_t)property_decl, metadata);
+                    
+                    class_interface_decl->addDecl (property_decl);
+                    
+                    Selector setter_sel, getter_sel;
+                    
+                    if (property_setter_name != NULL)
+                    {
+                        std::string property_setter_no_colon(property_setter_name, strlen(property_setter_name) - 1);
+                        clang::IdentifierInfo *setter_ident = &identifier_table->get(property_setter_no_colon.c_str());
+                        setter_sel = ast->Selectors.getSelector(1, &setter_ident);
+                    }
+                    else if (!(property_attributes & DW_APPLE_PROPERTY_readonly))
+                    {
+                        std::string setter_sel_string("set");
+                        setter_sel_string.push_back(::toupper(property_name[0]));
+                        setter_sel_string.append(&property_name[1]);
+                        clang::IdentifierInfo *setter_ident = &identifier_table->get(setter_sel_string.c_str());
+                        setter_sel = ast->Selectors.getSelector(1, &setter_ident);
+                    }
+                    property_decl->setSetterName(setter_sel);
+                    property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_setter);
+                    
+                    if (property_getter_name != NULL)
+                    {
+                        clang::IdentifierInfo *getter_ident = &identifier_table->get(property_getter_name);
+                        getter_sel = ast->Selectors.getSelector(0, &getter_ident);
+                    }
+                    else
+                    {
+                        clang::IdentifierInfo *getter_ident = &identifier_table->get(property_name);
+                        getter_sel = ast->Selectors.getSelector(0, &getter_ident);
+                    }
+                    property_decl->setGetterName(getter_sel);
+                    property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_getter);
+                        
+                    if (ivar_decl)
+                        property_decl->setPropertyIvarDecl (ivar_decl);
+                        
+                    if (property_attributes & DW_APPLE_PROPERTY_readonly) 
+                        property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readonly);
+                    if (property_attributes & DW_APPLE_PROPERTY_readwrite) 
+                        property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readwrite);
+                    if (property_attributes & DW_APPLE_PROPERTY_assign) 
+                        property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_assign);
+                    if (property_attributes & DW_APPLE_PROPERTY_retain) 
+                        property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_retain);
+                    if (property_attributes & DW_APPLE_PROPERTY_copy) 
+                        property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_copy);
+                    if (property_attributes & DW_APPLE_PROPERTY_nonatomic) 
+                        property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_nonatomic);
+                        
+                    if (!getter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(getter_sel))
+                    {
+                        QualType result_type = QualType::getFromOpaquePtr(property_opaque_type_to_access);
+                        
+                        const bool isInstance = true;
+                        const bool isVariadic = false;
+                        const bool isSynthesized = false;
+                        const bool isImplicitlyDeclared = true;
+                        const bool isDefined = false;
+                        const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None;
+                        const bool HasRelatedResultType = false;
+                        
+                        ObjCMethodDecl *getter = ObjCMethodDecl::Create(*ast, 
+                                                                        SourceLocation(), 
+                                                                        SourceLocation(), 
+                                                                        getter_sel, 
+                                                                        result_type,
+                                                                        NULL, 
+                                                                        class_interface_decl,
+                                                                        isInstance,
+                                                                        isVariadic,
+                                                                        isSynthesized,
+                                                                        isImplicitlyDeclared,
+                                                                        isDefined,
+                                                                        impControl,
+                                                                        HasRelatedResultType);
+                        
+                        if (getter)
+                            SetMetadata(ast, (uintptr_t)getter, metadata);
+                                                
+                        getter->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(), ArrayRef<SourceLocation>());
+                        
+                        class_interface_decl->addDecl(getter);
+                    }
+                    
+                    if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel))
+                    {
+                        QualType result_type = ast->VoidTy;
+                        
+                        const bool isInstance = true;
+                        const bool isVariadic = false;
+                        const bool isSynthesized = false;
+                        const bool isImplicitlyDeclared = true;
+                        const bool isDefined = false;
+                        const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None;
+                        const bool HasRelatedResultType = false;
+                        
+                        ObjCMethodDecl *setter = ObjCMethodDecl::Create(*ast, 
+                                                                        SourceLocation(), 
+                                                                        SourceLocation(), 
+                                                                        setter_sel, 
+                                                                        result_type,
+                                                                        NULL, 
+                                                                        class_interface_decl,
+                                                                        isInstance,
+                                                                        isVariadic,
+                                                                        isSynthesized,
+                                                                        isImplicitlyDeclared,
+                                                                        isDefined,
+                                                                        impControl,
+                                                                        HasRelatedResultType);
+                        
+                        if (setter)
+                            SetMetadata(ast, (uintptr_t)setter, metadata);
+                        
+                        llvm::SmallVector<ParmVarDecl *, 1> params;
+
+                        params.push_back (ParmVarDecl::Create (*ast,
+                                                               setter,
+                                                               SourceLocation(),
+                                                               SourceLocation(),
+                                                               NULL, // anonymous
+                                                               QualType::getFromOpaquePtr(property_opaque_type_to_access), 
+                                                               NULL,
+                                                               SC_Auto, 
+                                                               SC_Auto,
+                                                               NULL));
+                        
+                        setter->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>());
+                        
+                        class_interface_decl->addDecl(setter);
+                    }
+
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass)
+{
+    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
+
+    const clang::Type *class_type = class_qual_type.getTypePtr();
+    if (class_type)
+    {
+        const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
+
+        if (objc_class_type)
+            return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass);
+    }
+    return false;            
+}
+
+bool
+ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass)
+{
+    while (class_interface_decl)
+    {
+        if (class_interface_decl->ivar_size() > 0)
+            return true;
+        
+        if (check_superclass)
+            class_interface_decl = class_interface_decl->getSuperClass();
+        else
+            break;
+    }
+    return false;            
+}
+
+ObjCMethodDecl *
+ClangASTContext::AddMethodToObjCObjectType
+(
+    ASTContext *ast,
+    clang_type_t class_opaque_type, 
+    const char *name,  // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]")
+    clang_type_t method_opaque_type,
+    lldb::AccessType access
+)
+{
+    if (class_opaque_type == NULL || method_opaque_type == NULL)
+        return NULL;
+
+    IdentifierTable *identifier_table = &ast->Idents;
+
+    assert (ast != NULL);
+    assert (identifier_table != NULL);
+
+    QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type));
+
+    const clang::Type *class_type = class_qual_type.getTypePtr();
+    if (class_type == NULL)
+        return NULL;
+
+    const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type);
+
+    if (objc_class_type == NULL)
+        return NULL;
+
+    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+            
+    if (class_interface_decl == NULL)
+        return NULL;
+    
+    const char *selector_start = ::strchr (name, ' ');
+    if (selector_start == NULL)
+        return NULL;
+    
+    selector_start++;
+    if (!(::isalpha (selector_start[0]) || selector_start[0] == '_'))
+        return NULL;
+    llvm::SmallVector<IdentifierInfo *, 12> selector_idents;
+
+    size_t len = 0;
+    const char *start;
+    //printf ("name = '%s'\n", name);
+
+    unsigned num_selectors_with_args = 0;
+    for (start = selector_start;
+         start && *start != '\0' && *start != ']';
+         start += len)
+    {
+        len = ::strcspn(start, ":]");
+        bool has_arg = (start[len] == ':');
+        if (has_arg)
+            ++num_selectors_with_args;
+        selector_idents.push_back (&identifier_table->get (StringRef (start, len)));
+        if (has_arg)
+            len += 1;
+    }
+
+    
+    if (selector_idents.size() == 0)
+        return 0;
+
+    clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0, 
+                                                                          selector_idents.data());
+    
+    QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type));
+
+    // Populate the method decl with parameter decls
+    const clang::Type *method_type(method_qual_type.getTypePtr());
+    
+    if (method_type == NULL)
+        return NULL;
+    
+    const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type));
+    
+    if (!method_function_prototype)
+        return NULL;
+    
+
+    bool is_variadic = false;
+    bool is_synthesized = false;
+    bool is_defined = false;
+    ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
+
+    const unsigned num_args = method_function_prototype->getNumArgs();
+
+    ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
+                                                               SourceLocation(), // beginLoc,
+                                                               SourceLocation(), // endLoc, 
+                                                               method_selector,
+                                                               method_function_prototype->getResultType(),
+                                                               NULL, // TypeSourceInfo *ResultTInfo,
+                                                               GetDeclContextForType (class_opaque_type),
+                                                               name[0] == '-',
+                                                               is_variadic,
+                                                               is_synthesized,
+                                                               true, // is_implicitly_declared
+                                                               is_defined,
+                                                               imp_control,
+                                                               false /*has_related_result_type*/);
+
+
+    if (objc_method_decl == NULL)
+        return NULL;
+
+    if (num_args > 0)
+    {
+        llvm::SmallVector<ParmVarDecl *, 12> params;
+            
+        for (int param_index = 0; param_index < num_args; ++param_index)
+        {
+            params.push_back (ParmVarDecl::Create (*ast,
+                                                   objc_method_decl,
+                                                   SourceLocation(),
+                                                   SourceLocation(),
+                                                   NULL, // anonymous
+                                                   method_function_prototype->getArgType(param_index), 
+                                                   NULL,
+                                                   SC_Auto, 
+                                                   SC_Auto,
+                                                   NULL));
+        }
+        
+        objc_method_decl->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>());
+    }
+    
+    class_interface_decl->addDecl (objc_method_decl);
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+    VerifyDecl(objc_method_decl);
+#endif
+
+    return objc_method_decl;
+}
+
+size_t
+ClangASTContext::GetNumTemplateArguments (clang::ASTContext *ast, clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Record:
+                if (GetCompleteQualType (ast, qual_type))
+                {
+                    const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                    if (cxx_record_decl)
+                    {
+                        const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl);
+                        if (template_decl)
+                            return template_decl->getTemplateArgs().size();
+                    }
+                }
+                break;
+                
+            case clang::Type::Typedef:                         
+                return ClangASTContext::GetNumTemplateArguments (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+            default:
+                break;
+        }
+    }
+    return 0;
+}
+
+clang_type_t
+ClangASTContext::GetTemplateArgument (clang::ASTContext *ast, clang_type_t clang_type, size_t arg_idx, lldb::TemplateArgumentKind &kind)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+            case clang::Type::Record:
+                if (GetCompleteQualType (ast, qual_type))
+                {
+                    const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                    if (cxx_record_decl)
+                    {
+                        const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl);
+                        if (template_decl && arg_idx < template_decl->getTemplateArgs().size())
+                        {
+                            const TemplateArgument &template_arg = template_decl->getTemplateArgs()[arg_idx];
+                            switch (template_arg.getKind())
+                            {
+                                case clang::TemplateArgument::Null:
+                                    kind = eTemplateArgumentKindNull;
+                                    return NULL;
+
+                                case clang::TemplateArgument::Type:
+                                    kind = eTemplateArgumentKindType;
+                                    return template_arg.getAsType().getAsOpaquePtr();
+
+                                case clang::TemplateArgument::Declaration:
+                                    kind = eTemplateArgumentKindDeclaration;
+                                    return NULL;
+
+                                case clang::TemplateArgument::Integral:
+                                    kind = eTemplateArgumentKindIntegral;
+                                    return template_arg.getIntegralType().getAsOpaquePtr();
+
+                                case clang::TemplateArgument::Template:
+                                    kind = eTemplateArgumentKindTemplate;
+                                    return NULL;
+
+                                case clang::TemplateArgument::TemplateExpansion:
+                                    kind = eTemplateArgumentKindTemplateExpansion;
+                                    return NULL;
+
+                                case clang::TemplateArgument::Expression:
+                                    kind = eTemplateArgumentKindExpression;
+                                    return NULL;
+
+                                case clang::TemplateArgument::Pack:
+                                    kind = eTemplateArgumentKindPack;
+                                    return NULL;
+
+                                default:
+                                    assert (!"Unhandled TemplateArgument::ArgKind");
+                                    kind = eTemplateArgumentKindNull;
+                                    return NULL;
+                            }
+                        }
+                    }
+                }
+                break;
+                
+            case clang::Type::Typedef:                         
+                return ClangASTContext::GetTemplateArgument (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), arg_idx, kind);
+            default:
+                break;
+        }
+    }
+    kind = eTemplateArgumentKindNull;
+    return NULL;
+}
+
+uint32_t
+ClangASTContext::GetTypeInfo 
+(
+    clang_type_t clang_type, 
+    clang::ASTContext *ast, 
+    clang_type_t *pointee_or_element_clang_type
+)
+{
+    if (clang_type == NULL)
+        return 0;
+        
+    if (pointee_or_element_clang_type)
+        *pointee_or_element_clang_type = NULL;
+    
+    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+    case clang::Type::Builtin:
+        switch (cast<clang::BuiltinType>(qual_type)->getKind())
+        {
+        case clang::BuiltinType::ObjCId:
+        case clang::BuiltinType::ObjCClass:
+            if (ast && pointee_or_element_clang_type)
+                *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
+            return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue;
+                break;
+        case clang::BuiltinType::Bool:
+        case clang::BuiltinType::Char_U:
+        case clang::BuiltinType::UChar:
+        case clang::BuiltinType::WChar_U:
+        case clang::BuiltinType::Char16:
+        case clang::BuiltinType::Char32:
+        case clang::BuiltinType::UShort:
+        case clang::BuiltinType::UInt:
+        case clang::BuiltinType::ULong:
+        case clang::BuiltinType::ULongLong:
+        case clang::BuiltinType::UInt128:
+        case clang::BuiltinType::Char_S:
+        case clang::BuiltinType::SChar:
+        case clang::BuiltinType::WChar_S:
+        case clang::BuiltinType::Short:
+        case clang::BuiltinType::Int:
+        case clang::BuiltinType::Long:
+        case clang::BuiltinType::LongLong:
+        case clang::BuiltinType::Int128:
+        case clang::BuiltinType::Float:
+        case clang::BuiltinType::Double:
+        case clang::BuiltinType::LongDouble:
+                return eTypeIsBuiltIn | eTypeHasValue | eTypeIsScalar;
+        default: 
+            break;
+        }
+        return eTypeIsBuiltIn | eTypeHasValue;
+
+    case clang::Type::BlockPointer:                     
+        if (pointee_or_element_clang_type)
+            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
+        return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
+
+    case clang::Type::Complex:                          return eTypeIsBuiltIn | eTypeHasValue;
+
+    case clang::Type::ConstantArray:
+    case clang::Type::DependentSizedArray:
+    case clang::Type::IncompleteArray:
+    case clang::Type::VariableArray:                    
+        if (pointee_or_element_clang_type)
+            *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
+        return eTypeHasChildren | eTypeIsArray;
+
+    case clang::Type::DependentName:                    return 0;
+    case clang::Type::DependentSizedExtVector:          return eTypeHasChildren | eTypeIsVector;
+    case clang::Type::DependentTemplateSpecialization:  return eTypeIsTemplate;
+    case clang::Type::Decltype:                         return 0;
+
+    case clang::Type::Enum:
+        if (pointee_or_element_clang_type)
+            *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr();
+        return eTypeIsEnumeration | eTypeHasValue;
+
+    case clang::Type::Elaborated:
+        return ClangASTContext::GetTypeInfo (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+                                             ast, 
+                                             pointee_or_element_clang_type);
+    case clang::Type::ExtVector:                        return eTypeHasChildren | eTypeIsVector;
+    case clang::Type::FunctionProto:                    return eTypeIsFuncPrototype | eTypeHasValue;
+    case clang::Type::FunctionNoProto:                  return eTypeIsFuncPrototype | eTypeHasValue;
+    case clang::Type::InjectedClassName:                return 0;
+
+    case clang::Type::LValueReference:                  
+    case clang::Type::RValueReference:                  
+        if (pointee_or_element_clang_type)
+            *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr();
+        return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
+
+    case clang::Type::MemberPointer:                    return eTypeIsPointer   | eTypeIsMember | eTypeHasValue;
+
+    case clang::Type::ObjCObjectPointer:
+        if (pointee_or_element_clang_type)
+            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
+        return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue;
+
+    case clang::Type::ObjCObject:                       return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
+    case clang::Type::ObjCInterface:                    return eTypeHasChildren | eTypeIsObjC | eTypeIsClass;
+
+    case clang::Type::Pointer:                      	
+        if (pointee_or_element_clang_type)
+            *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr();
+        return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
+
+    case clang::Type::Record:
+        if (qual_type->getAsCXXRecordDecl())
+            return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus;
+        else
+            return eTypeHasChildren | eTypeIsStructUnion;
+        break;
+    case clang::Type::SubstTemplateTypeParm:            return eTypeIsTemplate;
+    case clang::Type::TemplateTypeParm:                 return eTypeIsTemplate;
+    case clang::Type::TemplateSpecialization:           return eTypeIsTemplate;
+
+    case clang::Type::Typedef:                         
+        return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+                                                                  ast, 
+                                                                  pointee_or_element_clang_type);
+
+    case clang::Type::TypeOfExpr:                       return 0;
+    case clang::Type::TypeOf:                           return 0;
+    case clang::Type::UnresolvedUsing:                  return 0;
+    case clang::Type::Vector:                           return eTypeHasChildren | eTypeIsVector;
+    default:                                            return 0;
+    }
+    return 0;
+}
+
+
+#pragma mark Aggregate Types
+
+bool
+ClangASTContext::IsAggregateType (clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return false;
+
+    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+    case clang::Type::IncompleteArray:
+    case clang::Type::VariableArray:
+    case clang::Type::ConstantArray:
+    case clang::Type::ExtVector:
+    case clang::Type::Vector:
+    case clang::Type::Record:
+    case clang::Type::ObjCObject:
+    case clang::Type::ObjCInterface:
+        return true;
+    case clang::Type::Elaborated:
+        return ClangASTContext::IsAggregateType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+    case clang::Type::Typedef:
+        return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+
+    default:
+        break;
+    }
+    // The clang type does have a value
+    return false;
+}
+
+uint32_t
+ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes)
+{
+    if (clang_type == NULL)
+        return 0;
+
+    uint32_t num_children = 0;
+    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+    case clang::Type::Builtin:
+        switch (cast<clang::BuiltinType>(qual_type)->getKind())
+        {
+        case clang::BuiltinType::ObjCId:    // child is Class
+        case clang::BuiltinType::ObjCClass: // child is Class
+            num_children = 1;
+            break;
+
+        default:
+            break;
+        }
+        break;
+
+    case clang::Type::Complex: return 0;
+
+    case clang::Type::Record:
+        if (GetCompleteQualType (ast, qual_type))
+        {
+            const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+            const RecordDecl *record_decl = record_type->getDecl();
+            assert(record_decl);
+            const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+            if (cxx_record_decl)
+            {
+                if (omit_empty_base_classes)
+                {
+                    // Check each base classes to see if it or any of its
+                    // base classes contain any fields. This can help
+                    // limit the noise in variable views by not having to
+                    // show base classes that contain no members.
+                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+                         base_class != base_class_end;
+                         ++base_class)
+                    {
+                        const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+
+                        // Skip empty base classes
+                        if (RecordHasFields(base_class_decl) == false)
+                            continue;
+
+                        num_children++;
+                    }
+                }
+                else
+                {
+                    // Include all base classes
+                    num_children += cxx_record_decl->getNumBases();
+                }
+
+            }
+            RecordDecl::field_iterator field, field_end;
+            for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
+                ++num_children;
+        }
+        break;
+
+    case clang::Type::ObjCObject:
+    case clang::Type::ObjCInterface:
+        if (GetCompleteQualType (ast, qual_type))
+        {
+            const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+            assert (objc_class_type);
+            if (objc_class_type)
+            {
+                ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+            
+                if (class_interface_decl)
+                {
+            
+                    ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                    if (superclass_interface_decl)
+                    {
+                        if (omit_empty_base_classes)
+                        {
+                            if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true))
+                                ++num_children;
+                        }
+                        else
+                            ++num_children;
+                    }
+                    
+                    num_children += class_interface_decl->ivar_size();
+                }
+            }
+        }
+        break;
+        
+    case clang::Type::ObjCObjectPointer:
+        {
+            const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr());
+            QualType pointee_type = pointer_type->getPointeeType();
+            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
+                                                                             pointee_type.getAsOpaquePtr(), 
+                                                                             omit_empty_base_classes);
+            // If this type points to a simple type, then it has 1 child
+            if (num_pointee_children == 0)
+                num_children = 1;
+            else
+                num_children = num_pointee_children;
+        }
+        break;
+
+    case clang::Type::ConstantArray:
+        num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
+        break;
+
+    case clang::Type::Pointer:
+        {
+            const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
+            QualType pointee_type (pointer_type->getPointeeType());
+            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
+                                                                             pointee_type.getAsOpaquePtr(), 
+                                                                             omit_empty_base_classes);
+            if (num_pointee_children == 0)
+            {
+                // We have a pointer to a pointee type that claims it has no children.
+                // We will want to look at
+                num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr());
+            }
+            else
+                num_children = num_pointee_children;
+        }
+        break;
+
+    case clang::Type::LValueReference:
+    case clang::Type::RValueReference:
+        {
+            const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+            QualType pointee_type = reference_type->getPointeeType();
+            uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast,
+                                                                             pointee_type.getAsOpaquePtr(), 
+                                                                             omit_empty_base_classes);
+            // If this type points to a simple type, then it has 1 child
+            if (num_pointee_children == 0)
+                num_children = 1;
+            else
+                num_children = num_pointee_children;
+        }
+        break;
+
+
+    case clang::Type::Typedef:
+        num_children = ClangASTContext::GetNumChildren (ast,
+                                                        cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), 
+                                                        omit_empty_base_classes);
+        break;
+        
+    case clang::Type::Elaborated:
+        num_children = ClangASTContext::GetNumChildren (ast, 
+                                                        cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+                                                        omit_empty_base_classes);
+        break;
+
+    default:
+        break;
+    }
+    return num_children;
+}
+
+uint32_t
+ClangASTContext::GetNumDirectBaseClasses (clang::ASTContext *ast, clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return 0;
+    
+    uint32_t count = 0;
+    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                    count = cxx_record_decl->getNumBases();
+            }
+            break;
+            
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    
+                    if (class_interface_decl && class_interface_decl->getSuperClass())
+                        count = 1;
+                }
+            }
+            break;
+            
+            
+        case clang::Type::Typedef:
+            count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+            break;
+            
+        case clang::Type::Elaborated:
+            count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+            break;
+            
+        default:
+            break;
+    }
+    return count;
+}
+
+uint32_t 
+ClangASTContext::GetNumVirtualBaseClasses (clang::ASTContext *ast, 
+                                           clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return 0;
+    
+    uint32_t count = 0;
+    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                    count = cxx_record_decl->getNumVBases();
+            }
+            break;
+            
+        case clang::Type::Typedef:
+            count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+            break;
+            
+        case clang::Type::Elaborated:
+            count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+            break;
+            
+        default:
+            break;
+    }
+    return count;
+}
+
+uint32_t 
+ClangASTContext::GetNumFields (clang::ASTContext *ast, clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return 0;
+    
+    uint32_t count = 0;
+    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr());
+                if (record_type)
+                {
+                    RecordDecl *record_decl = record_type->getDecl();
+                    if (record_decl)
+                    {
+                        uint32_t field_idx = 0;
+                        RecordDecl::field_iterator field, field_end;
+                        for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field)
+                            ++field_idx;
+                        count = field_idx;
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::Typedef:
+            count = ClangASTContext::GetNumFields (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+            break;
+            
+        case clang::Type::Elaborated:
+            count = ClangASTContext::GetNumFields (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+            break;
+            
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    
+                    if (class_interface_decl)
+                        count = class_interface_decl->ivar_size();
+                }
+            }
+            break;
+
+        default:
+            break;
+    }
+    return count;
+}
+
+clang_type_t
+ClangASTContext::GetDirectBaseClassAtIndex (clang::ASTContext *ast, 
+                                            clang_type_t clang_type,
+                                            uint32_t idx, 
+                                            uint32_t *bit_offset_ptr)
+{
+    if (clang_type == NULL)
+        return 0;
+    
+    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                {
+                    uint32_t curr_idx = 0;
+                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+                         base_class != base_class_end;
+                         ++base_class, ++curr_idx)
+                    {
+                        if (curr_idx == idx)
+                        {
+                            if (bit_offset_ptr)
+                            {
+                                const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl);
+                                const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+//                                if (base_class->isVirtual())
+//                                    *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+//                                else
+                                    *bit_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
+                            }
+                            return base_class->getType().getAsOpaquePtr();
+                        }
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (idx == 0 && GetCompleteQualType (ast, qual_type))
+            {
+                const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    
+                    if (class_interface_decl)
+                    {
+                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                        if (superclass_interface_decl)
+                        {
+                            if (bit_offset_ptr)
+                                *bit_offset_ptr = 0;
+                            return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr();
+                        }
+                    }
+                }
+            }
+            break;
+            
+            
+        case clang::Type::Typedef:
+            return ClangASTContext::GetDirectBaseClassAtIndex (ast, 
+                                                               cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+                                                               idx,
+                                                               bit_offset_ptr);
+            
+        case clang::Type::Elaborated:
+            return  ClangASTContext::GetDirectBaseClassAtIndex (ast, 
+                                                                cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+                                                                idx,
+                                                                bit_offset_ptr);
+            
+        default:
+            break;
+    }
+    return NULL;
+}
+
+clang_type_t
+ClangASTContext::GetVirtualBaseClassAtIndex (clang::ASTContext *ast, 
+                                             clang_type_t clang_type,
+                                             uint32_t idx, 
+                                             uint32_t *bit_offset_ptr)
+{
+    if (clang_type == NULL)
+        return 0;
+    
+    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+                if (cxx_record_decl)
+                {
+                    uint32_t curr_idx = 0;
+                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+                    for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end();
+                         base_class != base_class_end;
+                         ++base_class, ++curr_idx)
+                    {
+                        if (curr_idx == idx)
+                        {
+                            if (bit_offset_ptr)
+                            {
+                                const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl);
+                                const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+                                *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+
+                            }
+                            return base_class->getType().getAsOpaquePtr();
+                        }
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::Typedef:
+            return ClangASTContext::GetVirtualBaseClassAtIndex (ast, 
+                                                                cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+                                                                idx,
+                                                                bit_offset_ptr);
+            
+        case clang::Type::Elaborated:
+            return  ClangASTContext::GetVirtualBaseClassAtIndex (ast, 
+                                                                 cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+                                                                 idx,
+                                                                 bit_offset_ptr);
+            
+        default:
+            break;
+    }
+    return NULL;
+}
+
+clang_type_t
+ClangASTContext::GetFieldAtIndex (clang::ASTContext *ast, 
+                                  clang_type_t clang_type,
+                                  uint32_t idx, 
+                                  std::string& name,
+                                  uint64_t *bit_offset_ptr,
+                                  uint32_t *bitfield_bit_size_ptr,
+                                  bool *is_bitfield_ptr)
+{
+    if (clang_type == NULL)
+        return 0;
+    
+    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+        case clang::Type::Record:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+                const RecordDecl *record_decl = record_type->getDecl();
+                uint32_t field_idx = 0;
+                RecordDecl::field_iterator field, field_end;
+                for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx)
+                {
+                    if (idx == field_idx)
+                    {
+                        // Print the member type if requested
+                        // Print the member name and equal sign
+                        name.assign(field->getNameAsString());
+                        
+                        // Figure out the type byte size (field_type_info.first) and
+                        // alignment (field_type_info.second) from the AST context.
+                        if (bit_offset_ptr)
+                        {
+                            const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
+                            *bit_offset_ptr = record_layout.getFieldOffset (field_idx);
+                        }
+                        
+                        const bool is_bitfield = field->isBitField();
+                        
+                        if (bitfield_bit_size_ptr)
+                        {
+                            *bitfield_bit_size_ptr = 0;
+
+                            if (is_bitfield && ast)
+                            {
+                                Expr *bitfield_bit_size_expr = field->getBitWidth();
+                                llvm::APSInt bitfield_apsint;
+                                if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast))
+                                {
+                                    *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+                                }
+                            }
+                        }
+                        if (is_bitfield_ptr)
+                            *is_bitfield_ptr = is_bitfield;
+
+                        return field->getType().getAsOpaquePtr();
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+                assert (objc_class_type);
+                if (objc_class_type)
+                {
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    
+                    if (class_interface_decl)
+                    {
+                        if (idx < (class_interface_decl->ivar_size()))
+                        {
+                            ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+                            uint32_t ivar_idx = 0;
+
+                            for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx)
+                            {
+                                if (ivar_idx == idx)
+                                {
+                                    const ObjCIvarDecl* ivar_decl = *ivar_pos;
+                                    
+                                    QualType ivar_qual_type(ivar_decl->getType());
+                                    
+                                    name.assign(ivar_decl->getNameAsString());
+
+                                    if (bit_offset_ptr)
+                                    {
+                                        const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
+                                        *bit_offset_ptr = interface_layout.getFieldOffset (ivar_idx);
+                                    }
+                                    
+                                    const bool is_bitfield = ivar_pos->isBitField();
+                                    
+                                    if (bitfield_bit_size_ptr)
+                                    {
+                                        *bitfield_bit_size_ptr = 0;
+                                        
+                                        if (is_bitfield && ast)
+                                        {
+                                            Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth();
+                                            llvm::APSInt bitfield_apsint;
+                                            if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast))
+                                            {
+                                                *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue();
+                                            }
+                                        }
+                                    }
+                                    if (is_bitfield_ptr)
+                                        *is_bitfield_ptr = is_bitfield;
+                                    
+                                    return ivar_qual_type.getAsOpaquePtr();
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            break;
+            
+            
+        case clang::Type::Typedef:
+            return ClangASTContext::GetFieldAtIndex (ast, 
+                                                     cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+                                                     idx,
+                                                     name,
+                                                     bit_offset_ptr,
+                                                     bitfield_bit_size_ptr,
+                                                     is_bitfield_ptr);
+            
+        case clang::Type::Elaborated:
+            return  ClangASTContext::GetFieldAtIndex (ast, 
+                                                      cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+                                                      idx,
+                                                      name,
+                                                      bit_offset_ptr,
+                                                      bitfield_bit_size_ptr,
+                                                      is_bitfield_ptr);
+            
+        default:
+            break;
+    }
+    return NULL;
+}
+
+
+// If a pointer to a pointee type (the clang_type arg) says that it has no 
+// children, then we either need to trust it, or override it and return a 
+// different result. For example, an "int *" has one child that is an integer, 
+// but a function pointer doesn't have any children. Likewise if a Record type
+// claims it has no children, then there really is nothing to show.
+uint32_t
+ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return 0;
+
+    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+    case clang::Type::Builtin:                  
+        switch (cast<clang::BuiltinType>(qual_type)->getKind())
+        {
+        case clang::BuiltinType::UnknownAny:
+        case clang::BuiltinType::Void:
+        case clang::BuiltinType::NullPtr:  
+            return 0;
+        case clang::BuiltinType::Bool:
+        case clang::BuiltinType::Char_U:
+        case clang::BuiltinType::UChar:
+        case clang::BuiltinType::WChar_U:
+        case clang::BuiltinType::Char16:
+        case clang::BuiltinType::Char32:
+        case clang::BuiltinType::UShort:
+        case clang::BuiltinType::UInt:
+        case clang::BuiltinType::ULong:
+        case clang::BuiltinType::ULongLong:
+        case clang::BuiltinType::UInt128:
+        case clang::BuiltinType::Char_S:
+        case clang::BuiltinType::SChar:
+        case clang::BuiltinType::WChar_S:
+        case clang::BuiltinType::Short:
+        case clang::BuiltinType::Int:
+        case clang::BuiltinType::Long:
+        case clang::BuiltinType::LongLong:
+        case clang::BuiltinType::Int128:
+        case clang::BuiltinType::Float:
+        case clang::BuiltinType::Double:
+        case clang::BuiltinType::LongDouble:
+        case clang::BuiltinType::Dependent:
+        case clang::BuiltinType::Overload:
+        case clang::BuiltinType::ObjCId:
+        case clang::BuiltinType::ObjCClass:
+        case clang::BuiltinType::ObjCSel:
+        case clang::BuiltinType::BoundMember:
+        case clang::BuiltinType::Half:          
+        case clang::BuiltinType::ARCUnbridgedCast:          
+        case clang::BuiltinType::PseudoObject:
+        case clang::BuiltinType::BuiltinFn:
+            return 1;
+        }
+        break;
+
+    case clang::Type::Complex:                  return 1;
+    case clang::Type::Pointer:                  return 1;
+    case clang::Type::BlockPointer:             return 0;   // If block pointers don't have debug info, then no children for them
+    case clang::Type::LValueReference:          return 1;
+    case clang::Type::RValueReference:          return 1;
+    case clang::Type::MemberPointer:            return 0;
+    case clang::Type::ConstantArray:            return 0;
+    case clang::Type::IncompleteArray:          return 0;
+    case clang::Type::VariableArray:            return 0;
+    case clang::Type::DependentSizedArray:      return 0;
+    case clang::Type::DependentSizedExtVector:  return 0;
+    case clang::Type::Vector:                   return 0;
+    case clang::Type::ExtVector:                return 0;
+    case clang::Type::FunctionProto:            return 0;   // When we function pointers, they have no children...
+    case clang::Type::FunctionNoProto:          return 0;   // When we function pointers, they have no children...
+    case clang::Type::UnresolvedUsing:          return 0;
+    case clang::Type::Paren:                    return 0;
+    case clang::Type::Typedef:                  return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+    case clang::Type::Elaborated:               return ClangASTContext::GetNumPointeeChildren (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+    case clang::Type::TypeOfExpr:               return 0;
+    case clang::Type::TypeOf:                   return 0;
+    case clang::Type::Decltype:                 return 0;
+    case clang::Type::Record:                   return 0;
+    case clang::Type::Enum:                     return 1;
+    case clang::Type::TemplateTypeParm:         return 1;
+    case clang::Type::SubstTemplateTypeParm:    return 1;
+    case clang::Type::TemplateSpecialization:   return 1;
+    case clang::Type::InjectedClassName:        return 0;
+    case clang::Type::DependentName:            return 1;
+    case clang::Type::DependentTemplateSpecialization:  return 1;
+    case clang::Type::ObjCObject:               return 0;
+    case clang::Type::ObjCInterface:            return 0;
+    case clang::Type::ObjCObjectPointer:        return 1;
+    default: 
+        break;
+    }
+    return 0;
+}
+
+clang_type_t
+ClangASTContext::GetChildClangTypeAtIndex
+(
+    ExecutionContext *exe_ctx,
+    const char *parent_name,
+    clang_type_t parent_clang_type,
+    uint32_t idx,
+    bool transparent_pointers,
+    bool omit_empty_base_classes,
+    bool ignore_array_bounds,
+    std::string& child_name,
+    uint32_t &child_byte_size,
+    int32_t &child_byte_offset,
+    uint32_t &child_bitfield_bit_size,
+    uint32_t &child_bitfield_bit_offset,
+    bool &child_is_base_class,
+    bool &child_is_deref_of_parent
+)
+{
+    if (parent_clang_type)
+
+        return GetChildClangTypeAtIndex (exe_ctx,
+                                         getASTContext(),
+                                         parent_name,
+                                         parent_clang_type,
+                                         idx,
+                                         transparent_pointers,
+                                         omit_empty_base_classes,
+                                         ignore_array_bounds,
+                                         child_name,
+                                         child_byte_size,
+                                         child_byte_offset,
+                                         child_bitfield_bit_size,
+                                         child_bitfield_bit_offset,
+                                         child_is_base_class, 
+                                         child_is_deref_of_parent);
+    return NULL;
+}
+
+clang_type_t
+ClangASTContext::GetChildClangTypeAtIndex
+(
+    ExecutionContext *exe_ctx,
+    ASTContext *ast,
+    const char *parent_name,
+    clang_type_t parent_clang_type,
+    uint32_t idx,
+    bool transparent_pointers,
+    bool omit_empty_base_classes,
+    bool ignore_array_bounds,
+    std::string& child_name,
+    uint32_t &child_byte_size,
+    int32_t &child_byte_offset,
+    uint32_t &child_bitfield_bit_size,
+    uint32_t &child_bitfield_bit_offset,
+    bool &child_is_base_class,
+    bool &child_is_deref_of_parent
+)
+{
+    if (parent_clang_type == NULL)
+        return NULL;
+
+    if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
+    {
+        uint32_t bit_offset;
+        child_bitfield_bit_size = 0;
+        child_bitfield_bit_offset = 0;
+        child_is_base_class = false;
+        QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
+        const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
+        switch (parent_type_class)
+        {
+        case clang::Type::Builtin:
+            switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
+            {
+            case clang::BuiltinType::ObjCId:
+            case clang::BuiltinType::ObjCClass:
+                child_name = "isa";
+                child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT;
+                return ast->ObjCBuiltinClassTy.getAsOpaquePtr();
+                
+            default:
+                break;
+            }
+            break;
+
+        case clang::Type::Record:
+            if (GetCompleteQualType (ast, parent_qual_type))
+            {
+                const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
+                const RecordDecl *record_decl = record_type->getDecl();
+                assert(record_decl);
+                const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
+                uint32_t child_idx = 0;
+
+                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+                if (cxx_record_decl)
+                {
+                    // We might have base classes to print out first
+                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+                         base_class != base_class_end;
+                         ++base_class)
+                    {
+                        const CXXRecordDecl *base_class_decl = NULL;
+
+                        // Skip empty base classes
+                        if (omit_empty_base_classes)
+                        {
+                            base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+                            if (RecordHasFields(base_class_decl) == false)
+                                continue;
+                        }
+
+                        if (idx == child_idx)
+                        {
+                            if (base_class_decl == NULL)
+                                base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+
+
+                            if (base_class->isVirtual())
+                                bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+                            else
+                                bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
+
+                            // Base classes should be a multiple of 8 bits in size
+                            child_byte_offset = bit_offset/8;
+                            
+                            child_name = ClangASTType::GetTypeNameForQualType(ast, base_class->getType());
+
+                            uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
+
+                            // Base classes bit sizes should be a multiple of 8 bits in size
+                            assert (clang_type_info_bit_size % 8 == 0);
+                            child_byte_size = clang_type_info_bit_size / 8;
+                            child_is_base_class = true;
+                            return base_class->getType().getAsOpaquePtr();
+                        }
+                        // We don't increment the child index in the for loop since we might
+                        // be skipping empty base classes
+                        ++child_idx;
+                    }
+                }
+                // Make sure index is in range...
+                uint32_t field_idx = 0;
+                RecordDecl::field_iterator field, field_end;
+                for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
+                {
+                    if (idx == child_idx)
+                    {
+                        // Print the member type if requested
+                        // Print the member name and equal sign
+                        child_name.assign(field->getNameAsString().c_str());
+
+                        // Figure out the type byte size (field_type_info.first) and
+                        // alignment (field_type_info.second) from the AST context.
+                        std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
+                        assert(field_idx < record_layout.getFieldCount());
+
+                        child_byte_size = field_type_info.first / 8;
+
+                        // Figure out the field offset within the current struct/union/class type
+                        bit_offset = record_layout.getFieldOffset (field_idx);
+                        child_byte_offset = bit_offset / 8;
+                        if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
+                            child_bitfield_bit_offset = bit_offset % 8;
+
+                        return field->getType().getAsOpaquePtr();
+                    }
+                }
+            }
+            break;
+
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (GetCompleteQualType (ast, parent_qual_type))
+            {
+                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
+                assert (objc_class_type);
+                if (objc_class_type)
+                {
+                    uint32_t child_idx = 0;
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                
+                    if (class_interface_decl)
+                    {
+                
+                        const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
+                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                        if (superclass_interface_decl)
+                        {
+                            if (omit_empty_base_classes)
+                            {
+                                if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
+                                {
+                                    if (idx == 0)
+                                    {
+                                        QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
+                                        
+
+                                        child_name.assign(superclass_interface_decl->getNameAsString().c_str());
+
+                                        std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
+
+                                        child_byte_size = ivar_type_info.first / 8;
+                                        child_byte_offset = 0;
+                                        child_is_base_class = true;
+
+                                        return ivar_qual_type.getAsOpaquePtr();
+                                    }
+
+                                    ++child_idx;
+                                }
+                            }
+                            else
+                                ++child_idx;
+                        }
+    
+                        const uint32_t superclass_idx = child_idx;
+
+                        if (idx < (child_idx + class_interface_decl->ivar_size()))
+                        {
+                            ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+                            
+                            for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
+                            {
+                                if (child_idx == idx)
+                                {
+                                    ObjCIvarDecl* ivar_decl = *ivar_pos;
+                                    
+                                    QualType ivar_qual_type(ivar_decl->getType());
+
+                                    child_name.assign(ivar_decl->getNameAsString().c_str());
+
+                                    std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
+
+                                    child_byte_size = ivar_type_info.first / 8;
+
+                                    // Figure out the field offset within the current struct/union/class type
+                                    // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
+                                    // that doesn't account for the space taken up by unbacked properties, or from 
+                                    // the changing size of base classes that are newer than this class.
+                                    // So if we have a process around that we can ask about this object, do so.
+                                    child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
+                                    Process *process = NULL;
+                                    if (exe_ctx)
+                                        process = exe_ctx->GetProcessPtr();
+                                    if (process)
+                                    {
+                                        ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
+                                        if (objc_runtime != NULL)
+                                        {
+                                            ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
+                                            child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
+                                        }
+                                    }
+                                    
+                                    // Setting this to UINT32_MAX to make sure we don't compute it twice...
+                                    bit_offset = UINT32_MAX;
+                                    
+                                    if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
+                                    {
+                                        bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
+                                        child_byte_offset = bit_offset / 8;
+                                    }
+                                    
+                                    // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
+                                    // of a bitfield within its containing object.  So regardless of where we get the byte
+                                    // offset from, we still need to get the bit offset for bitfields from the layout.
+                                    
+                                    if (ClangASTContext::FieldIsBitfield (ast, ivar_decl, child_bitfield_bit_size))
+                                    {
+                                        if (bit_offset == UINT32_MAX)
+                                            bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
+                                            
+                                        child_bitfield_bit_offset = bit_offset % 8;
+                                    }
+                                    return ivar_qual_type.getAsOpaquePtr();
+                                }
+                                ++child_idx;
+                            }
+                        }
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            {
+                const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
+                QualType pointee_type = pointer_type->getPointeeType();
+
+                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+                {
+                    child_is_deref_of_parent = false;
+                    bool tmp_child_is_deref_of_parent = false;
+                    return GetChildClangTypeAtIndex (exe_ctx,
+                                                     ast,
+                                                     parent_name,
+                                                     pointer_type->getPointeeType().getAsOpaquePtr(),
+                                                     idx,
+                                                     transparent_pointers,
+                                                     omit_empty_base_classes,
+                                                     ignore_array_bounds,
+                                                     child_name,
+                                                     child_byte_size,
+                                                     child_byte_offset,
+                                                     child_bitfield_bit_size,
+                                                     child_bitfield_bit_offset,
+                                                     child_is_base_class,
+                                                     tmp_child_is_deref_of_parent);
+                }
+                else
+                {
+                    child_is_deref_of_parent = true;
+                    if (parent_name)
+                    {
+                        child_name.assign(1, '*');
+                        child_name += parent_name;
+                    }
+
+                    // We have a pointer to an simple type
+                    if (idx == 0 && GetCompleteQualType(ast, pointee_type))
+                    {
+                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+                        assert(clang_type_info.first % 8 == 0);
+                        child_byte_size = clang_type_info.first / 8;
+                        child_byte_offset = 0;
+                        return pointee_type.getAsOpaquePtr();
+                    }
+                }
+            }
+            break;
+
+        case clang::Type::ConstantArray:
+            {
+                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
+                const uint64_t element_count = array->getSize().getLimitedValue();
+
+                if (ignore_array_bounds || idx < element_count)
+                {
+                    if (GetCompleteQualType (ast, array->getElementType()))
+                    {
+                        std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
+
+                        char element_name[64];
+                        ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
+
+                        child_name.assign(element_name);
+                        assert(field_type_info.first % 8 == 0);
+                        child_byte_size = field_type_info.first / 8;
+                        child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
+                        return array->getElementType().getAsOpaquePtr();
+                    }
+                }
+            }
+            break;
+
+        case clang::Type::Pointer:
+            {
+                const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
+                QualType pointee_type = pointer_type->getPointeeType();
+                
+                // Don't dereference "void *" pointers
+                if (pointee_type->isVoidType())
+                    return NULL;
+
+                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+                {
+                    child_is_deref_of_parent = false;
+                    bool tmp_child_is_deref_of_parent = false;
+                    return GetChildClangTypeAtIndex (exe_ctx,
+                                                     ast,
+                                                     parent_name,
+                                                     pointer_type->getPointeeType().getAsOpaquePtr(),
+                                                     idx,
+                                                     transparent_pointers,
+                                                     omit_empty_base_classes,
+                                                     ignore_array_bounds,
+                                                     child_name,
+                                                     child_byte_size,
+                                                     child_byte_offset,
+                                                     child_bitfield_bit_size,
+                                                     child_bitfield_bit_offset,
+                                                     child_is_base_class,
+                                                     tmp_child_is_deref_of_parent);
+                }
+                else
+                {
+                    child_is_deref_of_parent = true;
+
+                    if (parent_name)
+                    {
+                        child_name.assign(1, '*');
+                        child_name += parent_name;
+                    }
+
+                    // We have a pointer to an simple type
+                    if (idx == 0)
+                    {
+                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+                        assert(clang_type_info.first % 8 == 0);
+                        child_byte_size = clang_type_info.first / 8;
+                        child_byte_offset = 0;
+                        return pointee_type.getAsOpaquePtr();
+                    }
+                }
+            }
+            break;
+
+        case clang::Type::LValueReference:
+        case clang::Type::RValueReference:
+            {
+                const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
+                QualType pointee_type(reference_type->getPointeeType());
+                clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
+                if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
+                {
+                    child_is_deref_of_parent = false;
+                    bool tmp_child_is_deref_of_parent = false;
+                    return GetChildClangTypeAtIndex (exe_ctx,
+                                                     ast,
+                                                     parent_name,
+                                                     pointee_clang_type,
+                                                     idx,
+                                                     transparent_pointers,
+                                                     omit_empty_base_classes,
+                                                     ignore_array_bounds,
+                                                     child_name,
+                                                     child_byte_size,
+                                                     child_byte_offset,
+                                                     child_bitfield_bit_size,
+                                                     child_bitfield_bit_offset,
+                                                     child_is_base_class,
+                                                     tmp_child_is_deref_of_parent);
+                }
+                else
+                {
+                    if (parent_name)
+                    {
+                        child_name.assign(1, '&');
+                        child_name += parent_name;
+                    }
+
+                    // We have a pointer to an simple type
+                    if (idx == 0)
+                    {
+                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+                        assert(clang_type_info.first % 8 == 0);
+                        child_byte_size = clang_type_info.first / 8;
+                        child_byte_offset = 0;
+                        return pointee_type.getAsOpaquePtr();
+                    }
+                }
+            }
+            break;
+
+        case clang::Type::Typedef:
+            return GetChildClangTypeAtIndex (exe_ctx,
+                                             ast,
+                                             parent_name,
+                                             cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+                                             idx,
+                                             transparent_pointers,
+                                             omit_empty_base_classes,
+                                             ignore_array_bounds,
+                                             child_name,
+                                             child_byte_size,
+                                             child_byte_offset,
+                                             child_bitfield_bit_size,
+                                             child_bitfield_bit_offset,
+                                             child_is_base_class,
+                                             child_is_deref_of_parent);
+            break;
+    
+        case clang::Type::Elaborated:
+            return GetChildClangTypeAtIndex (exe_ctx,
+                                             ast,
+                                             parent_name,
+                                             cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
+                                             idx,
+                                             transparent_pointers,
+                                             omit_empty_base_classes,
+                                             ignore_array_bounds,
+                                             child_name,
+                                             child_byte_size,
+                                             child_byte_offset,
+                                             child_bitfield_bit_size,
+                                             child_bitfield_bit_offset,
+                                             child_is_base_class,
+                                             child_is_deref_of_parent); 
+
+        default:
+            break;
+        }
+    }
+    return NULL;
+}
+
+static inline bool
+BaseSpecifierIsEmpty (const CXXBaseSpecifier *b)
+{
+    return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false;
+}
+
+static uint32_t
+GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes)
+{
+    uint32_t num_bases = 0;
+    if (cxx_record_decl)
+    {
+        if (omit_empty_base_classes)
+        {
+            CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+            for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+                 base_class != base_class_end;
+                 ++base_class)
+            {
+                // Skip empty base classes
+                if (omit_empty_base_classes)
+                {
+                    if (BaseSpecifierIsEmpty (base_class))
+                        continue;
+                }
+                ++num_bases;
+            }
+        }
+        else
+            num_bases = cxx_record_decl->getNumBases();
+    }
+    return num_bases;
+}
+
+
+static uint32_t
+GetIndexForRecordBase
+(
+    const RecordDecl *record_decl,
+    const CXXBaseSpecifier *base_spec,
+    bool omit_empty_base_classes
+)
+{
+    uint32_t child_idx = 0;
+
+    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+
+//    const char *super_name = record_decl->getNameAsCString();
+//    const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString();
+//    printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name);
+//
+    if (cxx_record_decl)
+    {
+        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+             base_class != base_class_end;
+             ++base_class)
+        {
+            if (omit_empty_base_classes)
+            {
+                if (BaseSpecifierIsEmpty (base_class))
+                    continue;
+            }
+
+//            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name,
+//                    child_idx,
+//                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
+//
+//
+            if (base_class == base_spec)
+                return child_idx;
+            ++child_idx;
+        }
+    }
+
+    return UINT32_MAX;
+}
+
+
+static uint32_t
+GetIndexForRecordChild
+(
+    const RecordDecl *record_decl,
+    NamedDecl *canonical_decl,
+    bool omit_empty_base_classes
+)
+{
+    uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes);
+
+//    const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+//
+////    printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString());
+//    if (cxx_record_decl)
+//    {
+//        CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+//        for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+//             base_class != base_class_end;
+//             ++base_class)
+//        {
+//            if (omit_empty_base_classes)
+//            {
+//                if (BaseSpecifierIsEmpty (base_class))
+//                    continue;
+//            }
+//
+////            printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n",
+////                    record_decl->getNameAsCString(),
+////                    canonical_decl->getNameAsCString(),
+////                    child_idx,
+////                    base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString());
+//
+//
+//            CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+//            if (curr_base_class_decl == canonical_decl)
+//            {
+//                return child_idx;
+//            }
+//            ++child_idx;
+//        }
+//    }
+//
+//    const uint32_t num_bases = child_idx;
+    RecordDecl::field_iterator field, field_end;
+    for (field = record_decl->field_begin(), field_end = record_decl->field_end();
+         field != field_end;
+         ++field, ++child_idx)
+    {
+//            printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n",
+//                    record_decl->getNameAsCString(),
+//                    canonical_decl->getNameAsCString(),
+//                    child_idx - num_bases,
+//                    field->getNameAsCString());
+
+        if (field->getCanonicalDecl() == canonical_decl)
+            return child_idx;
+    }
+
+    return UINT32_MAX;
+}
+
+// Look for a child member (doesn't include base classes, but it does include
+// their members) in the type hierarchy. Returns an index path into "clang_type"
+// on how to reach the appropriate member.
+//
+//    class A
+//    {
+//    public:
+//        int m_a;
+//        int m_b;
+//    };
+//
+//    class B
+//    {
+//    };
+//
+//    class C :
+//        public B,
+//        public A
+//    {
+//    };
+//
+// If we have a clang type that describes "class C", and we wanted to looked
+// "m_b" in it:
+//
+// With omit_empty_base_classes == false we would get an integer array back with:
+// { 1,  1 }
+// The first index 1 is the child index for "class A" within class C
+// The second index 1 is the child index for "m_b" within class A
+//
+// With omit_empty_base_classes == true we would get an integer array back with:
+// { 0,  1 }
+// The first index 0 is the child index for "class A" within class C (since class B doesn't have any members it doesn't count)
+// The second index 1 is the child index for "m_b" within class A
+
+size_t
+ClangASTContext::GetIndexOfChildMemberWithName
+(
+    ASTContext *ast,
+    clang_type_t clang_type,
+    const char *name,
+    bool omit_empty_base_classes,
+    std::vector<uint32_t>& child_indexes
+)
+{
+    if (clang_type && name && name[0])
+    {
+        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+        case clang::Type::Record:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+                const RecordDecl *record_decl = record_type->getDecl();
+
+                assert(record_decl);
+                uint32_t child_idx = 0;
+
+                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+
+                // Try and find a field that matches NAME
+                RecordDecl::field_iterator field, field_end;
+                StringRef name_sref(name);
+                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
+                     field != field_end;
+                     ++field, ++child_idx)
+                {
+                    if (field->getName().equals (name_sref))
+                    {
+                        // We have to add on the number of base classes to this index!
+                        child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));
+                        return child_indexes.size();
+                    }
+                }
+
+                if (cxx_record_decl)
+                {
+                    const RecordDecl *parent_record_decl = cxx_record_decl;
+
+                    //printf ("parent = %s\n", parent_record_decl->getNameAsCString());
+
+                    //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl();
+                    // Didn't find things easily, lets let clang do its thang...
+                    IdentifierInfo & ident_ref = ast->Idents.get(name_sref);
+                    DeclarationName decl_name(&ident_ref);
+
+                    CXXBasePaths paths;
+                    if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember,
+                                                       decl_name.getAsOpaquePtr(),
+                                                       paths))
+                    {
+                        CXXBasePaths::const_paths_iterator path, path_end = paths.end();
+                        for (path = paths.begin(); path != path_end; ++path)
+                        {
+                            const size_t num_path_elements = path->size();
+                            for (size_t e=0; e<num_path_elements; ++e)
+                            {
+                                CXXBasePathElement elem = (*path)[e];
+
+                                child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes);
+                                if (child_idx == UINT32_MAX)
+                                {
+                                    child_indexes.clear();
+                                    return 0;
+                                }
+                                else
+                                {
+                                    child_indexes.push_back (child_idx);
+                                    parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
+                                }
+                            }
+                            DeclContext::lookup_iterator named_decl_pos;
+                            for (named_decl_pos = path->Decls.first;
+                                 named_decl_pos != path->Decls.second && parent_record_decl;
+                                 ++named_decl_pos)
+                            {
+                                child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
+                                if (child_idx == UINT32_MAX)
+                                {
+                                    child_indexes.clear();
+                                    return 0;
+                                }
+                                else
+                                {
+                                    child_indexes.push_back (child_idx);
+                                }
+                            }
+                        }
+                        return child_indexes.size();
+                    }
+                }
+
+            }
+            break;
+
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                StringRef name_sref(name);
+                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+                assert (objc_class_type);
+                if (objc_class_type)
+                {
+                    uint32_t child_idx = 0;
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                
+                    if (class_interface_decl)
+                    {
+                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                        
+                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx)
+                        {
+                            const ObjCIvarDecl* ivar_decl = *ivar_pos;
+                            
+                            if (ivar_decl->getName().equals (name_sref))
+                            {
+                                if ((!omit_empty_base_classes && superclass_interface_decl) || 
+                                    ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
+                                    ++child_idx;
+
+                                child_indexes.push_back (child_idx);
+                                return child_indexes.size();
+                            }
+                        }
+
+                        if (superclass_interface_decl)
+                        {
+                            // The super class index is always zero for ObjC classes,
+                            // so we push it onto the child indexes in case we find
+                            // an ivar in our superclass...
+                            child_indexes.push_back (0);
+                            
+                            if (GetIndexOfChildMemberWithName (ast,
+                                                               ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(),
+                                                               name,
+                                                               omit_empty_base_classes,
+                                                               child_indexes))
+                            {
+                                // We did find an ivar in a superclass so just
+                                // return the results!
+                                return child_indexes.size();
+                            }
+                            
+                            // We didn't find an ivar matching "name" in our 
+                            // superclass, pop the superclass zero index that
+                            // we pushed on above.
+                            child_indexes.pop_back();
+                        }
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            {
+                return GetIndexOfChildMemberWithName (ast,
+                                                      cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
+                                                      name,
+                                                      omit_empty_base_classes,
+                                                      child_indexes);
+            }
+            break;
+
+
+        case clang::Type::ConstantArray:
+            {
+//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
+//                const uint64_t element_count = array->getSize().getLimitedValue();
+//
+//                if (idx < element_count)
+//                {
+//                    std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
+//
+//                    char element_name[32];
+//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
+//
+//                    child_name.assign(element_name);
+//                    assert(field_type_info.first % 8 == 0);
+//                    child_byte_size = field_type_info.first / 8;
+//                    child_byte_offset = idx * child_byte_size;
+//                    return array->getElementType().getAsOpaquePtr();
+//                }
+            }
+            break;
+
+//        case clang::Type::MemberPointerType:
+//            {
+//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
+//                QualType pointee_type = mem_ptr_type->getPointeeType();
+//
+//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+//                {
+//                    return GetIndexOfChildWithName (ast,
+//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
+//                                                    name);
+//                }
+//            }
+//            break;
+//
+        case clang::Type::LValueReference:
+        case clang::Type::RValueReference:
+            {
+                const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+                QualType pointee_type = reference_type->getPointeeType();
+
+                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+                {
+                    return GetIndexOfChildMemberWithName (ast,
+                                                          reference_type->getPointeeType().getAsOpaquePtr(),
+                                                          name,
+                                                          omit_empty_base_classes,
+                                                          child_indexes);
+                }
+            }
+            break;
+
+        case clang::Type::Pointer:
+            {
+                const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
+                QualType pointee_type = pointer_type->getPointeeType();
+
+                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+                {
+                    return GetIndexOfChildMemberWithName (ast,
+                                                          pointer_type->getPointeeType().getAsOpaquePtr(),
+                                                          name,
+                                                          omit_empty_base_classes,
+                                                          child_indexes);
+                }
+                else
+                {
+//                    if (parent_name)
+//                    {
+//                        child_name.assign(1, '*');
+//                        child_name += parent_name;
+//                    }
+//
+//                    // We have a pointer to an simple type
+//                    if (idx == 0)
+//                    {
+//                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+//                        assert(clang_type_info.first % 8 == 0);
+//                        child_byte_size = clang_type_info.first / 8;
+//                        child_byte_offset = 0;
+//                        return pointee_type.getAsOpaquePtr();
+//                    }
+                }
+            }
+            break;
+
+        case clang::Type::Typedef:
+            return GetIndexOfChildMemberWithName (ast,
+                                                  cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+                                                  name,
+                                                  omit_empty_base_classes,
+                                                  child_indexes);
+
+        default:
+            break;
+        }
+    }
+    return 0;
+}
+
+
+// Get the index of the child of "clang_type" whose name matches. This function
+// doesn't descend into the children, but only looks one level deep and name
+// matches can include base class names.
+
+uint32_t
+ClangASTContext::GetIndexOfChildWithName
+(
+    ASTContext *ast,
+    clang_type_t clang_type,
+    const char *name,
+    bool omit_empty_base_classes
+)
+{
+    if (clang_type && name && name[0])
+    {
+        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+        
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+
+        switch (type_class)
+        {
+        case clang::Type::Record:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr());
+                const RecordDecl *record_decl = record_type->getDecl();
+
+                assert(record_decl);
+                uint32_t child_idx = 0;
+
+                const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+
+                if (cxx_record_decl)
+                {
+                    CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+                    for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+                         base_class != base_class_end;
+                         ++base_class)
+                    {
+                        // Skip empty base classes
+                        CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+                        if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false)
+                            continue;
+
+                        std::string base_class_type_name (ClangASTType::GetTypeNameForQualType(ast, base_class->getType()));
+                        if (base_class_type_name.compare (name) == 0)
+                            return child_idx;
+                        ++child_idx;
+                    }
+                }
+
+                // Try and find a field that matches NAME
+                RecordDecl::field_iterator field, field_end;
+                StringRef name_sref(name);
+                for (field = record_decl->field_begin(), field_end = record_decl->field_end();
+                     field != field_end;
+                     ++field, ++child_idx)
+                {
+                    if (field->getName().equals (name_sref))
+                        return child_idx;
+                }
+
+            }
+            break;
+
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (GetCompleteQualType (ast, qual_type))
+            {
+                StringRef name_sref(name);
+                const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr());
+                assert (objc_class_type);
+                if (objc_class_type)
+                {
+                    uint32_t child_idx = 0;
+                    ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                
+                    if (class_interface_decl)
+                    {
+                        ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+                        ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+                        
+                        for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
+                        {
+                            const ObjCIvarDecl* ivar_decl = *ivar_pos;
+                            
+                            if (ivar_decl->getName().equals (name_sref))
+                            {
+                                if ((!omit_empty_base_classes && superclass_interface_decl) || 
+                                    ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true)))
+                                    ++child_idx;
+
+                                return child_idx;
+                            }
+                        }
+
+                        if (superclass_interface_decl)
+                        {
+                            if (superclass_interface_decl->getName().equals (name_sref))
+                                return 0;
+                        }
+                    }
+                }
+            }
+            break;
+            
+        case clang::Type::ObjCObjectPointer:
+            {
+                return GetIndexOfChildWithName (ast,
+                                                cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(),
+                                                name,
+                                                omit_empty_base_classes);
+            }
+            break;
+
+        case clang::Type::ConstantArray:
+            {
+//                const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
+//                const uint64_t element_count = array->getSize().getLimitedValue();
+//
+//                if (idx < element_count)
+//                {
+//                    std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
+//
+//                    char element_name[32];
+//                    ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx);
+//
+//                    child_name.assign(element_name);
+//                    assert(field_type_info.first % 8 == 0);
+//                    child_byte_size = field_type_info.first / 8;
+//                    child_byte_offset = idx * child_byte_size;
+//                    return array->getElementType().getAsOpaquePtr();
+//                }
+            }
+            break;
+
+//        case clang::Type::MemberPointerType:
+//            {
+//                MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr());
+//                QualType pointee_type = mem_ptr_type->getPointeeType();
+//
+//                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+//                {
+//                    return GetIndexOfChildWithName (ast,
+//                                                    mem_ptr_type->getPointeeType().getAsOpaquePtr(),
+//                                                    name);
+//                }
+//            }
+//            break;
+//
+        case clang::Type::LValueReference:
+        case clang::Type::RValueReference:
+            {
+                const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+                QualType pointee_type = reference_type->getPointeeType();
+
+                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+                {
+                    return GetIndexOfChildWithName (ast,
+                                                    reference_type->getPointeeType().getAsOpaquePtr(),
+                                                    name,
+                                                    omit_empty_base_classes);
+                }
+            }
+            break;
+
+        case clang::Type::Pointer:
+            {
+                const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr());
+                QualType pointee_type = pointer_type->getPointeeType();
+
+                if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+                {
+                    return GetIndexOfChildWithName (ast,
+                                                    pointer_type->getPointeeType().getAsOpaquePtr(),
+                                                    name,
+                                                    omit_empty_base_classes);
+                }
+                else
+                {
+//                    if (parent_name)
+//                    {
+//                        child_name.assign(1, '*');
+//                        child_name += parent_name;
+//                    }
+//
+//                    // We have a pointer to an simple type
+//                    if (idx == 0)
+//                    {
+//                        std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+//                        assert(clang_type_info.first % 8 == 0);
+//                        child_byte_size = clang_type_info.first / 8;
+//                        child_byte_offset = 0;
+//                        return pointee_type.getAsOpaquePtr();
+//                    }
+                }
+            }
+            break;
+
+        case clang::Type::Typedef:
+            return GetIndexOfChildWithName (ast,
+                                            cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+                                            name,
+                                            omit_empty_base_classes);
+
+        default:
+            break;
+        }
+    }
+    return UINT32_MAX;
+}
+
+#pragma mark TagType
+
+bool
+ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind)
+{
+    if (tag_clang_type)
+    {
+        QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type));
+        const clang::Type *clang_type = tag_qual_type.getTypePtr();
+        if (clang_type)
+        {
+            const TagType *tag_type = dyn_cast<TagType>(clang_type);
+            if (tag_type)
+            {
+                TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl());
+                if (tag_decl)
+                {
+                    tag_decl->setTagKind ((TagDecl::TagKind)kind);
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+
+#pragma mark DeclContext Functions
+
+DeclContext *
+ClangASTContext::GetDeclContextForType (clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return NULL;
+
+    QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+    case clang::Type::UnaryTransform:           break;
+    case clang::Type::FunctionNoProto:          break;
+    case clang::Type::FunctionProto:            break;
+    case clang::Type::IncompleteArray:          break;
+    case clang::Type::VariableArray:            break;
+    case clang::Type::ConstantArray:            break;
+    case clang::Type::DependentSizedArray:      break;
+    case clang::Type::ExtVector:                break;
+    case clang::Type::DependentSizedExtVector:  break;
+    case clang::Type::Vector:                   break;
+    case clang::Type::Builtin:                  break;
+    case clang::Type::BlockPointer:             break;
+    case clang::Type::Pointer:                  break;
+    case clang::Type::LValueReference:          break;
+    case clang::Type::RValueReference:          break;
+    case clang::Type::MemberPointer:            break;
+    case clang::Type::Complex:                  break;
+    case clang::Type::ObjCObject:               break;
+    case clang::Type::ObjCInterface:            return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface();
+    case clang::Type::ObjCObjectPointer:        return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr());
+    case clang::Type::Record:                   return cast<RecordType>(qual_type)->getDecl();
+    case clang::Type::Enum:                     return cast<EnumType>(qual_type)->getDecl();
+    case clang::Type::Typedef:                  return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+    case clang::Type::Elaborated:               return ClangASTContext::GetDeclContextForType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+    case clang::Type::TypeOfExpr:               break;
+    case clang::Type::TypeOf:                   break;
+    case clang::Type::Decltype:                 break;
+    //case clang::Type::QualifiedName:          break;
+    case clang::Type::TemplateSpecialization:   break;
+    case clang::Type::DependentTemplateSpecialization:  break;
+    case clang::Type::TemplateTypeParm:         break;
+    case clang::Type::SubstTemplateTypeParm:    break;
+    case clang::Type::SubstTemplateTypeParmPack:break;
+    case clang::Type::PackExpansion:            break;
+    case clang::Type::UnresolvedUsing:          break;
+    case clang::Type::Paren:                    break;
+    case clang::Type::Attributed:               break;
+    case clang::Type::Auto:                     break;
+    case clang::Type::InjectedClassName:        break;
+    case clang::Type::DependentName:            break;
+    case clang::Type::Atomic:                   break;
+    }
+    // No DeclContext in this type...
+    return NULL;
+}
+
+#pragma mark Namespace Declarations
+
+NamespaceDecl *
+ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *decl_ctx)
+{
+    NamespaceDecl *namespace_decl = NULL;
+    ASTContext *ast = getASTContext();
+    TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl ();
+    if (decl_ctx == NULL)
+        decl_ctx = translation_unit_decl;
+    
+    if (name)
+    {
+        IdentifierInfo &identifier_info = ast->Idents.get(name);
+        DeclarationName decl_name (&identifier_info);
+        clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
+        for (clang::DeclContext::lookup_iterator pos = result.first, end = result.second; pos != end; ++pos) 
+        {
+            namespace_decl = dyn_cast<clang::NamespaceDecl>(*pos);
+            if (namespace_decl)
+                return namespace_decl;
+        }
+
+        namespace_decl = NamespaceDecl::Create(*ast, 
+                                               decl_ctx, 
+                                               false, 
+                                               SourceLocation(), 
+                                               SourceLocation(),
+                                               &identifier_info,
+                                               NULL);
+        
+        decl_ctx->addDecl (namespace_decl);        
+    }
+    else
+    {
+        if (decl_ctx == translation_unit_decl)
+        {
+            namespace_decl = translation_unit_decl->getAnonymousNamespace();
+            if (namespace_decl)
+                return namespace_decl;
+            
+            namespace_decl = NamespaceDecl::Create(*ast, 
+                                                   decl_ctx,
+                                                   false,
+                                                   SourceLocation(),
+                                                   SourceLocation(),
+                                                   NULL,
+                                                   NULL);
+            translation_unit_decl->setAnonymousNamespace (namespace_decl);
+            translation_unit_decl->addDecl (namespace_decl);
+            assert (namespace_decl == translation_unit_decl->getAnonymousNamespace());
+        }
+        else
+        {
+            NamespaceDecl *parent_namespace_decl = cast<NamespaceDecl>(decl_ctx);
+            if (parent_namespace_decl)
+            {
+                namespace_decl = parent_namespace_decl->getAnonymousNamespace();
+                if (namespace_decl)
+                    return namespace_decl;
+                namespace_decl = NamespaceDecl::Create(*ast, 
+                                                       decl_ctx, 
+                                                       false,
+                                                       SourceLocation(), 
+                                                       SourceLocation(), 
+                                                       NULL,
+                                                       NULL);
+                parent_namespace_decl->setAnonymousNamespace (namespace_decl);
+                parent_namespace_decl->addDecl (namespace_decl);
+                assert (namespace_decl == parent_namespace_decl->getAnonymousNamespace());
+            }
+            else
+            {
+                // BAD!!!
+            }
+        }
+        
+
+        if (namespace_decl)
+        {
+            // If we make it here, we are creating the anonymous namespace decl
+            // for the first time, so we need to do the using directive magic
+            // like SEMA does
+            UsingDirectiveDecl* using_directive_decl = UsingDirectiveDecl::Create (*ast, 
+                                                                                   decl_ctx, 
+                                                                                   SourceLocation(),
+                                                                                   SourceLocation(),
+                                                                                   NestedNameSpecifierLoc(),
+                                                                                   SourceLocation(),
+                                                                                   namespace_decl,
+                                                                                   decl_ctx);
+            using_directive_decl->setImplicit();
+            decl_ctx->addDecl(using_directive_decl);
+        }
+    }
+#ifdef LLDB_CONFIGURATION_DEBUG
+    VerifyDecl(namespace_decl);
+#endif
+    return namespace_decl;
+}
+
+
+#pragma mark Function Types
+
+FunctionDecl *
+ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, const char *name, clang_type_t function_clang_type, int storage, bool is_inline)
+{
+    FunctionDecl *func_decl = NULL;
+    ASTContext *ast = getASTContext();
+    if (decl_ctx == NULL)
+        decl_ctx = ast->getTranslationUnitDecl();
+
+    if (name && name[0])
+    {
+        func_decl = FunctionDecl::Create (*ast,
+                                          decl_ctx,
+                                          SourceLocation(),
+                                          SourceLocation(),
+                                          DeclarationName (&ast->Idents.get(name)),
+                                          QualType::getFromOpaquePtr(function_clang_type),
+                                          NULL,
+                                          (FunctionDecl::StorageClass)storage,
+                                          (FunctionDecl::StorageClass)storage,
+                                          is_inline);
+    }
+    else
+    {
+        func_decl = FunctionDecl::Create (*ast,
+                                          decl_ctx,
+                                          SourceLocation(),
+                                          SourceLocation(),
+                                          DeclarationName (),
+                                          QualType::getFromOpaquePtr(function_clang_type),
+                                          NULL,
+                                          (FunctionDecl::StorageClass)storage,
+                                          (FunctionDecl::StorageClass)storage,
+                                          is_inline);
+    }
+    if (func_decl)
+        decl_ctx->addDecl (func_decl);
+    
+#ifdef LLDB_CONFIGURATION_DEBUG
+    VerifyDecl(func_decl);
+#endif
+    
+    return func_decl;
+}
+
+clang_type_t
+ClangASTContext::CreateFunctionType (ASTContext *ast,
+                                     clang_type_t result_type, 
+                                     clang_type_t *args, 
+                                     unsigned num_args, 
+                                     bool is_variadic, 
+                                     unsigned type_quals)
+{
+    assert (ast != NULL);
+    std::vector<QualType> qual_type_args;
+    for (unsigned i=0; i<num_args; ++i)
+        qual_type_args.push_back (QualType::getFromOpaquePtr(args[i]));
+
+    // TODO: Detect calling convention in DWARF?
+    FunctionProtoType::ExtProtoInfo proto_info;
+    proto_info.Variadic = is_variadic;
+    proto_info.ExceptionSpecType = EST_None;
+    proto_info.TypeQuals = type_quals;
+    proto_info.RefQualifier = RQ_None;
+    proto_info.NumExceptions = 0;
+    proto_info.Exceptions = NULL;
+    
+    return ast->getFunctionType (QualType::getFromOpaquePtr(result_type),
+                                 qual_type_args.empty() ? NULL : &qual_type_args.front(),
+                                 qual_type_args.size(),
+                                 proto_info).getAsOpaquePtr();    // NoReturn);
+}
+
+ParmVarDecl *
+ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage)
+{
+    ASTContext *ast = getASTContext();
+    assert (ast != NULL);
+    return ParmVarDecl::Create(*ast,
+                                ast->getTranslationUnitDecl(),
+                                SourceLocation(),
+                                SourceLocation(),
+                                name && name[0] ? &ast->Idents.get(name) : NULL,
+                                QualType::getFromOpaquePtr(param_type),
+                                NULL,
+                                (VarDecl::StorageClass)storage,
+                                (VarDecl::StorageClass)storage,
+                                0);
+}
+
+void
+ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params)
+{
+    if (function_decl)
+        function_decl->setParams (ArrayRef<ParmVarDecl*>(params, num_params));
+}
+
+
+#pragma mark Array Types
+
+clang_type_t
+ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
+{
+    if (element_type)
+    {
+        ASTContext *ast = getASTContext();
+        assert (ast != NULL);
+        llvm::APInt ap_element_count (64, element_count);
+        return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
+                                                 ap_element_count,
+                                                 ArrayType::Normal,
+                                                 0).getAsOpaquePtr(); // ElemQuals
+    }
+    return NULL;
+}
+
+
+#pragma mark TagDecl
+
+bool
+ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        const clang::Type *t = qual_type.getTypePtr();
+        if (t)
+        {
+            const TagType *tag_type = dyn_cast<TagType>(t);
+            if (tag_type)
+            {
+                TagDecl *tag_decl = tag_type->getDecl();
+                if (tag_decl)
+                {
+                    tag_decl->startDefinition();
+                    return true;
+                }
+            }
+            
+            const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(t);
+            if (object_type)
+            {
+                ObjCInterfaceDecl *interface_decl = object_type->getInterface();
+                if (interface_decl)
+                {
+                    interface_decl->startDefinition();
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        
+        CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+        
+        if (cxx_record_decl)
+        {
+            cxx_record_decl->completeDefinition();
+            
+            return true;
+        }
+        
+        const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
+        
+        if (enum_type)
+        {
+            EnumDecl *enum_decl = enum_type->getDecl();
+            
+            if (enum_decl)
+            {
+                /// TODO This really needs to be fixed.
+                
+                unsigned NumPositiveBits = 1;
+                unsigned NumNegativeBits = 0;
+                
+                ASTContext *ast = getASTContext();
+
+                QualType promotion_qual_type;
+                // If the enum integer type is less than an integer in bit width,
+                // then we must promote it to an integer size.
+                if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
+                {
+                    if (enum_decl->getIntegerType()->isSignedIntegerType())
+                        promotion_qual_type = ast->IntTy;
+                    else
+                        promotion_qual_type = ast->UnsignedIntTy;
+                }
+                else
+                    promotion_qual_type = enum_decl->getIntegerType();
+
+                enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+
+#pragma mark Enumeration Types
+
+clang_type_t
+ClangASTContext::CreateEnumerationType 
+(
+    const char *name, 
+    DeclContext *decl_ctx, 
+    const Declaration &decl, 
+    clang_type_t integer_qual_type
+)
+{
+    // TODO: Do something intelligent with the Declaration object passed in
+    // like maybe filling in the SourceLocation with it...
+    ASTContext *ast = getASTContext();
+    assert (ast != NULL);
+
+    // TODO: ask about these...
+//    const bool IsScoped = false;
+//    const bool IsFixed = false;
+
+    EnumDecl *enum_decl = EnumDecl::Create (*ast,
+                                            decl_ctx,
+                                            SourceLocation(),
+                                            SourceLocation(),
+                                            name && name[0] ? &ast->Idents.get(name) : NULL,
+                                            NULL, 
+                                            false,  // IsScoped
+                                            false,  // IsScopedUsingClassTag
+                                            false); // IsFixed
+    
+    
+    if (enum_decl)
+    {
+        // TODO: check if we should be setting the promotion type too?
+        enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type));
+        
+        enum_decl->setAccess(AS_public); // TODO respect what's in the debug info
+        
+        return ast->getTagDeclType(enum_decl).getAsOpaquePtr();
+    }
+    return NULL;
+}
+
+clang_type_t
+ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type)
+{
+    QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
+
+    const clang::Type *clang_type = enum_qual_type.getTypePtr();
+    if (clang_type)
+    {
+        const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
+        if (enum_type)
+        {
+            EnumDecl *enum_decl = enum_type->getDecl();
+            if (enum_decl)
+                return enum_decl->getIntegerType().getAsOpaquePtr();
+        }
+    }
+    return NULL;
+}
+bool
+ClangASTContext::AddEnumerationValueToEnumerationType
+(
+    clang_type_t enum_clang_type,
+    clang_type_t enumerator_clang_type,
+    const Declaration &decl,
+    const char *name,
+    int64_t enum_value,
+    uint32_t enum_value_bit_size
+)
+{
+    if (enum_clang_type && enumerator_clang_type && name)
+    {
+        // TODO: Do something intelligent with the Declaration object passed in
+        // like maybe filling in the SourceLocation with it...
+        ASTContext *ast = getASTContext();
+        IdentifierTable *identifier_table = getIdentifierTable();
+
+        assert (ast != NULL);
+        assert (identifier_table != NULL);
+        QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type));
+
+        const clang::Type *clang_type = enum_qual_type.getTypePtr();
+        if (clang_type)
+        {
+            const EnumType *enum_type = dyn_cast<EnumType>(clang_type);
+
+            if (enum_type)
+            {
+                llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false);
+                enum_llvm_apsint = enum_value;
+                EnumConstantDecl *enumerator_decl =
+                    EnumConstantDecl::Create (*ast,
+                                              enum_type->getDecl(),
+                                              SourceLocation(),
+                                              name ? &identifier_table->get(name) : NULL,    // Identifier
+                                              QualType::getFromOpaquePtr(enumerator_clang_type),
+                                              NULL,
+                                              enum_llvm_apsint);
+                
+                if (enumerator_decl)
+                {
+                    enum_type->getDecl()->addDecl(enumerator_decl);
+                    
+#ifdef LLDB_CONFIGURATION_DEBUG
+                    VerifyDecl(enumerator_decl);
+#endif
+                    
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+#pragma mark Pointers & References
+
+clang_type_t
+ClangASTContext::CreatePointerType (clang_type_t clang_type)
+{
+    return CreatePointerType (getASTContext(), clang_type);
+}
+
+clang_type_t
+ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type)
+{
+    if (ast && clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr();
+
+        default:
+            return ast->getPointerType(qual_type).getAsOpaquePtr();
+        }
+    }
+    return NULL;
+}
+
+clang_type_t
+ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast,
+                                            clang_type_t clang_type)
+{
+    if (clang_type)
+        return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
+    return NULL;
+}
+
+clang_type_t
+ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast,
+                                            clang_type_t clang_type)
+{
+    if (clang_type)
+        return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr();
+    return NULL;
+}
+
+clang_type_t
+ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type)
+{
+    if (clang_pointee_type && clang_pointee_type)
+        return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type),
+                                                     QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr();
+    return NULL;
+}
+
+uint32_t
+ClangASTContext::GetPointerBitSize ()
+{
+    ASTContext *ast = getASTContext();
+    return ast->getTypeSize(ast->VoidPtrTy);
+}
+
+bool
+ClangASTContext::IsPossibleDynamicType (clang::ASTContext *ast,
+                                        clang_type_t clang_type,
+                                        clang_type_t *dynamic_pointee_type,
+                                        bool check_cplusplus,
+                                        bool check_objc)
+{
+    QualType pointee_qual_type;
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        bool success = false;
+        switch (type_class)
+        {
+            case clang::Type::Builtin:
+                if (check_objc && cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId)
+                {
+                    if (dynamic_pointee_type)
+                        *dynamic_pointee_type = clang_type;
+                    return true;
+                }
+                break;
+
+            case clang::Type::ObjCObjectPointer:
+                if (check_objc)
+                {
+                    if (dynamic_pointee_type)
+                        *dynamic_pointee_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
+                    return true;
+                }
+                break;
+
+            case clang::Type::Pointer:
+                pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType();
+                success = true;
+                break;
+                
+            case clang::Type::LValueReference:
+            case clang::Type::RValueReference:
+                pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType();
+                success = true;
+                break;
+                
+            case clang::Type::Typedef:
+                return ClangASTContext::IsPossibleDynamicType (ast,
+                                                               cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+                                                               dynamic_pointee_type,
+                                                               check_cplusplus,
+                                                               check_objc);
+            
+            case clang::Type::Elaborated:
+                return ClangASTContext::IsPossibleDynamicType (ast,
+                                                               cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+                                                               dynamic_pointee_type,
+                                                               check_cplusplus,
+                                                               check_objc);
+            
+            default:
+                break;
+        }
+        
+        if (success)
+        {
+            // Check to make sure what we are pointing too is a possible dynamic C++ type
+            // We currently accept any "void *" (in case we have a class that has been
+            // watered down to an opaque pointer) and virtual C++ classes.
+            const clang::Type::TypeClass pointee_type_class = pointee_qual_type->getTypeClass();
+            switch (pointee_type_class)
+            {
+                case clang::Type::Builtin:
+                    switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind())
+                    {
+                        case clang::BuiltinType::UnknownAny:
+                        case clang::BuiltinType::Void:
+                            if (dynamic_pointee_type)
+                                *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
+                            return true;
+                            
+                        case clang::BuiltinType::NullPtr:  
+                        case clang::BuiltinType::Bool:
+                        case clang::BuiltinType::Char_U:
+                        case clang::BuiltinType::UChar:
+                        case clang::BuiltinType::WChar_U:
+                        case clang::BuiltinType::Char16:
+                        case clang::BuiltinType::Char32:
+                        case clang::BuiltinType::UShort:
+                        case clang::BuiltinType::UInt:
+                        case clang::BuiltinType::ULong:
+                        case clang::BuiltinType::ULongLong:
+                        case clang::BuiltinType::UInt128:
+                        case clang::BuiltinType::Char_S:
+                        case clang::BuiltinType::SChar:
+                        case clang::BuiltinType::WChar_S:
+                        case clang::BuiltinType::Short:
+                        case clang::BuiltinType::Int:
+                        case clang::BuiltinType::Long:
+                        case clang::BuiltinType::LongLong:
+                        case clang::BuiltinType::Int128:
+                        case clang::BuiltinType::Float:
+                        case clang::BuiltinType::Double:
+                        case clang::BuiltinType::LongDouble:
+                        case clang::BuiltinType::Dependent:
+                        case clang::BuiltinType::Overload:
+                        case clang::BuiltinType::ObjCId:
+                        case clang::BuiltinType::ObjCClass:
+                        case clang::BuiltinType::ObjCSel:
+                        case clang::BuiltinType::BoundMember:
+                        case clang::BuiltinType::Half:          
+                        case clang::BuiltinType::ARCUnbridgedCast:          
+                        case clang::BuiltinType::PseudoObject:
+                        case clang::BuiltinType::BuiltinFn:
+                            break;
+                    }
+                    break;
+
+                case clang::Type::Record:
+                    if (check_cplusplus)
+                    {
+                        CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl();
+                        if (cxx_record_decl)
+                        {
+                            bool is_complete = cxx_record_decl->isCompleteDefinition();
+                            if (!is_complete)
+                                is_complete = ClangASTContext::GetCompleteType (ast, pointee_qual_type.getAsOpaquePtr());
+
+                            if (is_complete)
+                            {
+                                success = cxx_record_decl->isDynamicClass();
+                            }
+                            else
+                            {
+                                success = false;
+                            }
+
+                            if (success)
+                            {
+                                if (dynamic_pointee_type)
+                                    *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
+                                return true;
+                            }
+                        }
+                    }
+                    break;
+                    
+                case clang::Type::ObjCObject:
+                case clang::Type::ObjCInterface:
+                    if (check_objc)
+                    {
+                        if (dynamic_pointee_type)
+                            *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr();
+                        return true;
+                    }
+                    break;
+
+                default:
+                    break;
+            }
+        }
+    }
+    if (dynamic_pointee_type)
+        *dynamic_pointee_type = NULL;
+    return false;
+}
+
+
+bool
+ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type)
+{
+    return IsPossibleDynamicType (ast,
+                                  clang_type,
+                                  dynamic_pointee_type,
+                                  true,     // Check for dynamic C++ types
+                                  false);   // Check for dynamic ObjC types
+}
+
+bool
+ClangASTContext::IsReferenceType (clang_type_t clang_type, clang_type_t *target_type)
+{
+    if (clang_type == NULL)
+        return false;
+    
+    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+
+    switch (type_class)
+    {
+    case clang::Type::LValueReference:
+        if (target_type)
+            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
+        return true;
+    case clang::Type::RValueReference:
+        if (target_type)
+            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
+        return true;
+    case clang::Type::Typedef:
+        return ClangASTContext::IsReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+    case clang::Type::Elaborated:
+        return ClangASTContext::IsReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+    default:
+        break;
+    }
+    
+    return false;
+}
+
+bool
+ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type)
+{
+    if (clang_type == NULL)
+        return false;
+
+    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+    case clang::Type::Builtin:
+        switch (cast<clang::BuiltinType>(qual_type)->getKind())
+        {
+        default:
+            break;
+        case clang::BuiltinType::ObjCId:
+        case clang::BuiltinType::ObjCClass:
+            return true;
+        }
+        return false;
+    case clang::Type::ObjCObjectPointer:
+        if (target_type)
+            *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
+        return true;
+    case clang::Type::BlockPointer:
+        if (target_type)
+            *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
+        return true;
+    case clang::Type::Pointer:
+        if (target_type)
+            *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
+        return true;
+    case clang::Type::MemberPointer:
+        if (target_type)
+            *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
+        return true;
+    case clang::Type::LValueReference:
+        if (target_type)
+            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
+        return true;
+    case clang::Type::RValueReference:
+        if (target_type)
+            *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr();
+        return true;
+    case clang::Type::Typedef:
+        return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+    case clang::Type::Elaborated:
+        return ClangASTContext::IsPointerOrReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+    default:
+        break;
+    }
+    return false;
+}
+
+bool
+ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed)
+{
+    if (!clang_type)
+        return false;
+    
+    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+    const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal());
+    
+    if (builtin_type)
+    {
+        if (builtin_type->isInteger())
+        {
+            is_signed = builtin_type->isSignedInteger();
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+bool
+ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t *target_type)
+{
+    if (target_type)
+        *target_type = NULL;
+
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+        case clang::Type::Builtin:
+            switch (cast<clang::BuiltinType>(qual_type)->getKind())
+            {
+            default:
+                break;
+            case clang::BuiltinType::ObjCId:
+            case clang::BuiltinType::ObjCClass:
+                return true;
+            }
+            return false;
+        case clang::Type::ObjCObjectPointer:
+            if (target_type)
+                *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
+            return true;
+        case clang::Type::BlockPointer:
+            if (target_type)
+                *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
+            return true;
+        case clang::Type::Pointer:
+            if (target_type)
+                *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
+            return true;
+        case clang::Type::MemberPointer:
+            if (target_type)
+                *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr();
+            return true;
+        case clang::Type::Typedef:
+            return ClangASTContext::IsPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type);
+        case clang::Type::Elaborated:
+            return ClangASTContext::IsPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), target_type);
+        default:
+            break;
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+
+        if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()))
+        {
+            clang::BuiltinType::Kind kind = BT->getKind();
+            if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble)
+            {
+                count = 1;
+                is_complex = false;
+                return true;
+            }
+        }
+        else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()))
+        {
+            if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex))
+            {
+                count = 2;
+                is_complex = true;
+                return true;
+            }
+        }
+        else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()))
+        {
+            if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex))
+            {
+                count = VT->getNumElements();
+                is_complex = false;
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::IsScalarType (lldb::clang_type_t clang_type)
+{
+    bool is_signed;
+    if (ClangASTContext::IsIntegerType(clang_type, is_signed))
+        return true;
+    
+    uint32_t count;
+    bool is_complex;
+    return ClangASTContext::IsFloatingPointType(clang_type, count, is_complex) && !is_complex;
+}
+
+bool
+ClangASTContext::IsPointerToScalarType (lldb::clang_type_t clang_type)
+{
+    if (!IsPointerType(clang_type))
+        return false;
+    
+    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+    lldb::clang_type_t pointee_type = qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr();
+    return IsScalarType(pointee_type);
+}
+
+bool
+ClangASTContext::IsArrayOfScalarType (lldb::clang_type_t clang_type)
+{
+    clang_type = GetAsArrayType(clang_type);
+    
+    if (clang_type == 0)
+        return false;
+    
+    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+    lldb::clang_type_t item_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr();
+    return IsScalarType(item_type);
+}
+
+
+bool
+ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        
+        CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl();
+        if (cxx_record_decl)
+        {
+            class_name.assign (cxx_record_decl->getIdentifier()->getNameStart());
+            return true;
+        }
+    }
+    class_name.clear();
+    return false;
+}
+
+
+bool
+ClangASTContext::IsCXXClassType (clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        if (qual_type->getAsCXXRecordDecl() != NULL)
+            return true;
+    }
+    return false;
+}
+
+bool
+ClangASTContext::IsBeingDefined (lldb::clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type);
+        if (tag_type)
+            return tag_type->isBeingDefined();
+    }
+    return false;
+}
+
+bool 
+ClangASTContext::IsObjCClassType (clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        if (qual_type->isObjCObjectOrInterfaceType())
+            return true;
+    }
+    return false;
+}
+
+bool
+ClangASTContext::IsObjCObjectPointerType (lldb::clang_type_t clang_type, clang_type_t *class_type)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        if (qual_type->isObjCObjectPointerType())
+        {
+            if (class_type)
+            {
+                *class_type = NULL;
+                
+                if (!qual_type->isObjCClassType() &&
+                    !qual_type->isObjCIdType())
+                {
+                    const ObjCObjectPointerType *obj_pointer_type = dyn_cast<ObjCObjectPointerType>(qual_type);
+                    if (!obj_pointer_type)
+                        *class_type = NULL;
+                    else
+                        *class_type = QualType(obj_pointer_type->getInterfaceType(), 0).getAsOpaquePtr();
+                }
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::GetObjCClassName (lldb::clang_type_t clang_type,
+                                   std::string &class_name)
+{
+    if (!clang_type)
+        return false;
+        
+    const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(QualType::getFromOpaquePtr(clang_type));
+    if (!object_type)
+        return false;
+    
+    const ObjCInterfaceDecl *interface = object_type->getInterface();
+    if (!interface)
+        return false;
+    
+    class_name = interface->getNameAsString();
+    return true;
+}
+
+bool 
+ClangASTContext::IsCharType (clang_type_t clang_type)
+{
+    if (clang_type)
+        return QualType::getFromOpaquePtr(clang_type)->isCharType();
+    return false;
+}
+
+bool
+ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length)
+{
+    clang_type_t pointee_or_element_clang_type = NULL;
+    Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type));
+    
+    if (pointee_or_element_clang_type == NULL)
+        return false;
+
+    if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer))
+    {
+        QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type));
+        
+        if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType())
+        {
+            QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+            if (type_flags.Test (eTypeIsArray))
+            {
+                // We know the size of the array and it could be a C string
+                // since it is an array of characters
+                length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue();
+                return true;
+            }
+            else
+            {
+                length = 0;
+                return true;
+            }
+
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::IsFunctionPointerType (clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        
+        if (qual_type->isFunctionPointerType())
+            return true;
+    
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+        default:
+            break;
+        case clang::Type::Typedef:
+            return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+        case clang::Type::Elaborated:
+            return ClangASTContext::IsFunctionPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+
+        case clang::Type::LValueReference:
+        case clang::Type::RValueReference:
+            {
+                const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr());
+                if (reference_type)
+                    return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr());
+            }
+            break;
+        }
+    }
+    return false;
+}
+
+size_t
+ClangASTContext::GetArraySize (clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        QualType qual_type(QualType::getFromOpaquePtr(clang_type));
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+        case clang::Type::ConstantArray:
+            {
+                const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr());
+                if (array)
+                    return array->getSize().getLimitedValue();
+            }
+            break;
+
+        case clang::Type::Typedef:
+            return ClangASTContext::GetArraySize(cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+            
+        case clang::Type::Elaborated:
+            return ClangASTContext::GetArraySize(cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+                
+        default:
+            break;
+        }
+    }
+    return 0;
+}
+
+clang_type_t
+ClangASTContext::GetAsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
+{
+    if (!clang_type)
+        return 0;
+    
+    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+    
+    const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+    switch (type_class)
+    {
+    default:
+        break;
+
+    case clang::Type::ConstantArray:
+        if (member_type)
+            *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr();
+        if (size)
+            *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX);
+        return clang_type;
+
+    case clang::Type::IncompleteArray:
+        if (member_type)
+            *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
+        if (size)
+            *size = 0;
+        return clang_type;
+
+    case clang::Type::VariableArray:
+        if (member_type)
+            *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr();
+        if (size)
+            *size = 0;
+        return clang_type;
+
+    case clang::Type::DependentSizedArray:
+        if (member_type)
+            *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr();
+        if (size)
+            *size = 0;
+        return clang_type;
+    
+    case clang::Type::Typedef:
+        return ClangASTContext::GetAsArrayType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+                                                member_type, 
+                                                size);
+    
+    case clang::Type::Elaborated:
+        return ClangASTContext::GetAsArrayType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+                                                member_type,
+                                                size);
+    }
+    return 0;
+}
+
+
+#pragma mark Typedefs
+
+clang_type_t
+ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        ASTContext *ast = getASTContext();
+        IdentifierTable *identifier_table = getIdentifierTable();
+        assert (ast != NULL);
+        assert (identifier_table != NULL);
+        if (decl_ctx == NULL)
+            decl_ctx = ast->getTranslationUnitDecl();
+        TypedefDecl *decl = TypedefDecl::Create (*ast,
+                                                 decl_ctx,
+                                                 SourceLocation(),
+                                                 SourceLocation(),
+                                                 name ? &identifier_table->get(name) : NULL, // Identifier
+                                                 ast->CreateTypeSourceInfo(qual_type));
+        
+        //decl_ctx->addDecl (decl);
+
+        decl->setAccess(AS_public); // TODO respect proper access specifier
+
+        // Get a uniqued QualType for the typedef decl type
+        return ast->getTypedefType (decl).getAsOpaquePtr();
+    }
+    return NULL;
+}
+
+// Disable this for now since I can't seem to get a nicely formatted float
+// out of the APFloat class without just getting the float, double or quad
+// and then using a formatted print on it which defeats the purpose. We ideally
+// would like to get perfect string values for any kind of float semantics
+// so we can support remote targets. The code below also requires a patch to
+// llvm::APInt.
+//bool
+//ClangASTContext::ConvertFloatValueToString (ASTContext *ast, clang_type_t clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str)
+//{
+//  uint32_t count = 0;
+//  bool is_complex = false;
+//  if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
+//  {
+//      unsigned num_bytes_per_float = byte_size / count;
+//      unsigned num_bits_per_float = num_bytes_per_float * 8;
+//
+//      float_str.clear();
+//      uint32_t i;
+//      for (i=0; i<count; i++)
+//      {
+//          APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order);
+//          bool is_ieee = false;
+//          APFloat ap_float(ap_int, is_ieee);
+//          char s[1024];
+//          unsigned int hex_digits = 0;
+//          bool upper_case = false;
+//
+//          if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0)
+//          {
+//              if (i > 0)
+//                  float_str.append(", ");
+//              float_str.append(s);
+//              if (i == 1 && is_complex)
+//                  float_str.append(1, 'i');
+//          }
+//      }
+//      return !float_str.empty();
+//  }
+//  return false;
+//}
+
+size_t
+ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        uint32_t count = 0;
+        bool is_complex = false;
+        if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex))
+        {
+            // TODO: handle complex and vector types
+            if (count != 1)
+                return false;
+
+            StringRef s_sref(s);
+            APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref);
+
+            const uint64_t bit_size = ast->getTypeSize (qual_type);
+            const uint64_t byte_size = bit_size / 8;
+            if (dst_size >= byte_size)
+            {
+                if (bit_size == sizeof(float)*8)
+                {
+                    float float32 = ap_float.convertToFloat();
+                    ::memcpy (dst, &float32, byte_size);
+                    return byte_size;
+                }
+                else if (bit_size >= 64)
+                {
+                    llvm::APInt ap_int(ap_float.bitcastToAPInt());
+                    ::memcpy (dst, ap_int.getRawData(), byte_size);
+                    return byte_size;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+unsigned
+ClangASTContext::GetTypeQualifiers(clang_type_t clang_type)
+{
+    assert (clang_type);
+    
+    QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+    
+    return qual_type.getQualifiers().getCVRQualifiers();
+}
+
+bool
+ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return false;
+
+    return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type));
+}
+
+
+bool
+ClangASTContext::GetCompleteType (clang_type_t clang_type)
+{   
+    return ClangASTContext::GetCompleteType (getASTContext(), clang_type);
+}
+
+bool
+ClangASTContext::IsCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return false;
+    
+    return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type), false); // just check but don't let it actually complete
+}
+
+
+bool
+ClangASTContext::IsCompleteType (clang_type_t clang_type)
+{   
+    return ClangASTContext::IsCompleteType (getASTContext(), clang_type);
+}
+
+bool
+ClangASTContext::GetCompleteDecl (clang::ASTContext *ast,
+                                  clang::Decl *decl)
+{
+    if (!decl)
+        return false;
+    
+    ExternalASTSource *ast_source = ast->getExternalSource();
+    
+    if (!ast_source)
+        return false;
+        
+    if (clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>(decl))
+    {
+        if (tag_decl->isCompleteDefinition())
+            return true;
+        
+        if (!tag_decl->hasExternalLexicalStorage())
+            return false;
+        
+        ast_source->CompleteType(tag_decl);
+        
+        return !tag_decl->getTypeForDecl()->isIncompleteType();
+    }
+    else if (clang::ObjCInterfaceDecl *objc_interface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl))
+    {
+        if (objc_interface_decl->getDefinition())
+            return true;
+        
+        if (!objc_interface_decl->hasExternalLexicalStorage())
+            return false;
+        
+        ast_source->CompleteType(objc_interface_decl);
+        
+        return !objc_interface_decl->getTypeForDecl()->isIncompleteType();
+    }
+    else
+    {
+        return false;
+    }
+}
+
+void
+ClangASTContext::SetMetadata (clang::ASTContext *ast,
+                              uintptr_t object,
+                              uint64_t metadata)
+{
+    ClangExternalASTSourceCommon *external_source =
+        static_cast<ClangExternalASTSourceCommon*>(ast->getExternalSource());
+    
+    if (external_source)
+        external_source->SetMetadata(object, metadata);
+}
+
+uint64_t
+ClangASTContext::GetMetadata (clang::ASTContext *ast,
+                              uintptr_t object)
+{
+    ClangExternalASTSourceCommon *external_source =
+        static_cast<ClangExternalASTSourceCommon*>(ast->getExternalSource());
+    
+    if (external_source && external_source->HasMetadata(object))
+        return external_source->GetMetadata(object);
+    else
+        return 0;
+}
+
+clang::DeclContext *
+ClangASTContext::GetAsDeclContext (clang::CXXMethodDecl *cxx_method_decl)
+{
+    return llvm::dyn_cast<clang::DeclContext>(cxx_method_decl);
+}
+
+clang::DeclContext *
+ClangASTContext::GetAsDeclContext (clang::ObjCMethodDecl *objc_method_decl)
+{
+    return llvm::dyn_cast<clang::DeclContext>(objc_method_decl);
+}
+
+
+bool
+ClangASTContext::GetClassMethodInfoForDeclContext (clang::DeclContext *decl_ctx,
+                                                   lldb::LanguageType &language,
+                                                   bool &is_instance_method,
+                                                   ConstString &language_object_name)
+{
+    language_object_name.Clear();
+    language = eLanguageTypeUnknown;
+    is_instance_method = false;
+
+    if (decl_ctx)
+    {
+        if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_ctx))
+        {
+            if (method_decl->isStatic())
+            {
+                is_instance_method = false;
+            }
+            else
+            {
+                language_object_name.SetCString("this");
+                is_instance_method = true;
+            }
+            language = eLanguageTypeC_plus_plus;
+            return true;
+        }
+        else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_ctx))
+        {
+            // Both static and instance methods have a "self" object in objective C
+            language_object_name.SetCString("self");
+            if (method_decl->isInstanceMethod())
+            {
+                is_instance_method = true;
+            }
+            else
+            {
+                is_instance_method = false;
+            }
+            language = eLanguageTypeObjC;
+            return true;
+        }
+    }
+    return false;
+}
+

Modified: lldb/branches/windows/source/Symbol/ClangASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Symbol/ClangASTImporter.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Symbol/ClangASTImporter.cpp (original)
+++ lldb/branches/windows/source/Symbol/ClangASTImporter.cpp Thu Nov  1 02:04:04 2012
@@ -60,15 +60,20 @@
 
             if (log)
             {
+                lldb::user_id_t user_id;
+                ClangASTMetadata *metadata = GetDeclMetadata(decl);
+                if (metadata)
+                    user_id = metadata->GetUserID();
+                
                 if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl))
                     log->Printf("  [ClangASTImporter] WARNING: Failed to import a %s '%s', metadata 0x%llx",
                                 decl->getDeclKindName(),
                                 named_decl->getNameAsString().c_str(),
-                                GetDeclMetadata(decl));
+                                user_id);
                 else
                     log->Printf("  [ClangASTImporter] WARNING: Failed to import a %s, metadata 0x%llx",
                                 decl->getDeclKindName(),
-                                GetDeclMetadata(decl));
+                                user_id);
             }
         }
         
@@ -243,7 +248,7 @@
     return true;
 }
 
-uint64_t
+ClangASTMetadata *
 ClangASTImporter::GetDeclMetadata (const clang::Decl *decl)
 {
     DeclOrigin decl_origin = GetDeclOrigin(decl);
@@ -450,6 +455,11 @@
         
     if (log)
     {
+        lldb::user_id_t user_id;
+        ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
+        if (metadata)
+            user_id = metadata->GetUserID();
+        
         if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from))
         {
             std::string name_string;
@@ -462,7 +472,7 @@
                         to,
                         name_string.c_str(),
                         from,
-                        m_master.GetDeclMetadata(from));
+                        user_id);
         }
         else
         {
@@ -470,7 +480,7 @@
                         from->getDeclKindName(),
                         to,
                         from,
-                        m_master.GetDeclMetadata(from));
+                        user_id);
         }
     }
 

Added: lldb/branches/windows/source/Symbol/ClangASTType.cpp.orig
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Symbol/ClangASTType.cpp.orig?rev=167218&view=auto
==============================================================================
--- lldb/branches/windows/source/Symbol/ClangASTType.cpp.orig (added)
+++ lldb/branches/windows/source/Symbol/ClangASTType.cpp.orig Thu Nov  1 02:04:04 2012
@@ -0,0 +1,1789 @@
+//===-- ClangASTType.cpp ---------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/ClangASTType.h"
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/Type.h"
+
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Version.h"
+
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+ClangASTType::~ClangASTType()
+{
+}
+
+std::string
+ClangASTType::GetTypeNameForQualType (clang::ASTContext *ast, clang::QualType qual_type)
+{
+    std::string type_name;
+    
+    clang::PrintingPolicy printing_policy (ast->getPrintingPolicy());
+    printing_policy.SuppressTagKeyword = true;
+    const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
+    if (typedef_type)
+    {
+        const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
+        type_name = typedef_decl->getQualifiedNameAsString(printing_policy);
+    }
+    else
+    {
+        type_name = qual_type.getAsString(printing_policy);
+    }
+    return type_name;
+}
+
+std::string
+ClangASTType::GetTypeNameForOpaqueQualType (clang::ASTContext *ast, clang_type_t opaque_qual_type)
+{
+    return GetTypeNameForQualType (ast, clang::QualType::getFromOpaquePtr(opaque_qual_type));
+}
+
+
+ConstString
+ClangASTType::GetConstTypeName ()
+{
+    // TODO: verify if we actually need to complete a type just to get its type name????
+    if (!ClangASTContext::GetCompleteType (this->m_ast, this->m_type))
+        return ConstString("<invalid>");
+    return GetConstTypeName (m_ast, m_type);
+}
+
+ConstString
+ClangASTType::GetConstQualifiedTypeName ()
+{
+    // TODO: verify if we actually need to complete a type just to get its fully qualified type name????
+    if (!ClangASTContext::GetCompleteType (this->m_ast, this->m_type))
+        return ConstString("<invalid>");
+    return GetConstQualifiedTypeName (m_ast, m_type);
+}
+
+ConstString
+ClangASTType::GetConstQualifiedTypeName (clang::ASTContext *ast, clang_type_t clang_type)
+{
+    if (ast == NULL || clang_type == NULL)
+        return ConstString("<invalid>");
+
+    return ConstString (GetTypeNameForQualType (ast, clang::QualType::getFromOpaquePtr(clang_type)).c_str());
+}
+
+
+ConstString
+ClangASTType::GetConstTypeName (clang::ASTContext *ast, clang_type_t clang_type)
+{
+    if (!clang_type)
+        return ConstString("<invalid>");
+    
+    std::string type_name (GetTypeNameForOpaqueQualType(ast, clang_type));
+    ConstString const_type_name;
+    if (type_name.empty())
+        const_type_name.SetCString ("<invalid>");
+    else
+        const_type_name.SetCString(type_name.c_str());
+    return const_type_name;
+}
+
+clang_type_t
+ClangASTType::GetPointeeType ()
+{
+    return GetPointeeType (m_type);
+}
+
+clang_type_t
+ClangASTType::GetPointeeType (clang_type_t clang_type)
+{
+    if (clang_type)
+    {
+        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+        
+        return qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr();
+    }
+    return NULL;
+}
+
+lldb::clang_type_t
+ClangASTType::GetArrayElementType (uint32_t& stride)
+{
+    return GetArrayElementType(m_ast, m_type, stride);
+}
+
+lldb::clang_type_t
+ClangASTType::GetArrayElementType (clang::ASTContext* ast,
+                                   lldb::clang_type_t opaque_clang_qual_type,
+                                   uint32_t& stride)
+{
+    if (opaque_clang_qual_type)
+    {
+        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
+        
+        lldb::clang_type_t ret_type = qual_type.getTypePtr()->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified().getAsOpaquePtr();
+        
+        // TODO: the real stride will be >= this value.. find the real one!
+        stride = GetTypeByteSize(ast, ret_type);
+        
+        return ret_type;
+        
+    }
+    return NULL;
+
+}
+
+lldb::clang_type_t
+ClangASTType::GetPointerType () const
+{
+    return GetPointerType (m_ast, m_type);
+}
+
+lldb::clang_type_t
+ClangASTType::GetPointerType (clang::ASTContext *ast_context,
+                              lldb::clang_type_t opaque_clang_qual_type)
+{
+    if (opaque_clang_qual_type)
+    {
+        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
+        
+        return ast_context->getPointerType(qual_type).getAsOpaquePtr();
+    }
+    return NULL;
+}
+
+lldb::Encoding
+ClangASTType::GetEncoding (uint32_t &count)
+{
+    return GetEncoding(m_type, count);
+}
+
+
+lldb::LanguageType
+ClangASTType::GetMinimumLanguage ()
+{
+    return ClangASTType::GetMinimumLanguage (m_ast,
+                                             m_type);
+}
+
+lldb::TypeClass
+ClangASTType::GetTypeClass (clang::ASTContext *ast_context, lldb::clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return lldb::eTypeClassInvalid;
+
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+    
+    switch (qual_type->getTypeClass())
+    {
+        case clang::Type::UnaryTransform:           break;
+        case clang::Type::FunctionNoProto:          return lldb::eTypeClassFunction;
+        case clang::Type::FunctionProto:            return lldb::eTypeClassFunction;
+        case clang::Type::IncompleteArray:          return lldb::eTypeClassArray;
+        case clang::Type::VariableArray:            return lldb::eTypeClassArray;
+        case clang::Type::ConstantArray:            return lldb::eTypeClassArray;
+        case clang::Type::DependentSizedArray:      return lldb::eTypeClassArray;
+        case clang::Type::DependentSizedExtVector:  return lldb::eTypeClassVector;
+        case clang::Type::ExtVector:                return lldb::eTypeClassVector;
+        case clang::Type::Vector:                   return lldb::eTypeClassVector;
+        case clang::Type::Builtin:                  return lldb::eTypeClassBuiltin;
+        case clang::Type::ObjCObjectPointer:        return lldb::eTypeClassObjCObjectPointer;
+        case clang::Type::BlockPointer:             return lldb::eTypeClassBlockPointer;
+        case clang::Type::Pointer:                  return lldb::eTypeClassPointer;
+        case clang::Type::LValueReference:          return lldb::eTypeClassReference;
+        case clang::Type::RValueReference:          return lldb::eTypeClassReference;
+        case clang::Type::MemberPointer:            return lldb::eTypeClassMemberPointer;
+        case clang::Type::Complex:
+            if (qual_type->isComplexType())
+                return lldb::eTypeClassComplexFloat;
+            else
+                return lldb::eTypeClassComplexInteger;
+        case clang::Type::ObjCObject:               return lldb::eTypeClassObjCObject;
+        case clang::Type::ObjCInterface:            return lldb::eTypeClassObjCInterface;
+        case clang::Type::Record:
+            if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+            {
+                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+                const clang::RecordDecl *record_decl = record_type->getDecl();
+                if (record_decl->isUnion())
+                    return lldb::eTypeClassUnion;
+                else if (record_decl->isStruct())
+                    return lldb::eTypeClassStruct;
+                else
+                    return lldb::eTypeClassClass;
+            }
+            break;
+        case clang::Type::Enum:                     return lldb::eTypeClassEnumeration;
+        case clang::Type::Typedef:                  return lldb::eTypeClassTypedef;
+        case clang::Type::UnresolvedUsing:          break;
+        case clang::Type::Paren:                    break;
+        case clang::Type::Elaborated:               break;
+        case clang::Type::Attributed:               break;
+        case clang::Type::TemplateTypeParm:         break;
+        case clang::Type::SubstTemplateTypeParm:    break;
+        case clang::Type::SubstTemplateTypeParmPack:break;
+        case clang::Type::Auto:                     break;
+        case clang::Type::InjectedClassName:        break;
+        case clang::Type::DependentName:            break;
+        case clang::Type::DependentTemplateSpecialization: break;
+        case clang::Type::PackExpansion:            break;
+            
+        case clang::Type::TypeOfExpr:               break;
+        case clang::Type::TypeOf:                   break;
+        case clang::Type::Decltype:                 break;
+        case clang::Type::TemplateSpecialization:   break;
+        case clang::Type::Atomic:                   break;
+    }
+    // We don't know hot to display this type...
+    return lldb::eTypeClassOther;
+
+}
+
+
+lldb::LanguageType
+ClangASTType::GetMinimumLanguage (clang::ASTContext *ctx,
+                                  lldb::clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return lldb::eLanguageTypeC;
+
+    // If the type is a reference, then resolve it to what it refers to first:     
+    clang::QualType qual_type (clang::QualType::getFromOpaquePtr(clang_type).getNonReferenceType());
+    if (qual_type->isAnyPointerType())
+    {
+        if (qual_type->isObjCObjectPointerType())
+            return lldb::eLanguageTypeObjC;
+        
+        clang::QualType pointee_type (qual_type->getPointeeType());
+        if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
+            return lldb::eLanguageTypeC_plus_plus;
+        if (pointee_type->isObjCObjectOrInterfaceType())
+            return lldb::eLanguageTypeObjC;
+        if (pointee_type->isObjCClassType())
+            return lldb::eLanguageTypeObjC;
+        if (pointee_type.getTypePtr() == ctx->ObjCBuiltinIdTy.getTypePtr())
+            return lldb::eLanguageTypeObjC;
+    }
+    else
+    {
+        if (qual_type->isObjCObjectOrInterfaceType())
+            return lldb::eLanguageTypeObjC;
+        if (qual_type->getAsCXXRecordDecl())
+            return lldb::eLanguageTypeC_plus_plus;
+        switch (qual_type->getTypeClass())
+        {
+        default:
+                break;
+        case clang::Type::Builtin:
+          switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
+            {
+                default:
+                case clang::BuiltinType::Void:
+                case clang::BuiltinType::Bool:
+                case clang::BuiltinType::Char_U:
+                case clang::BuiltinType::UChar:
+                case clang::BuiltinType::WChar_U:
+                case clang::BuiltinType::Char16:
+                case clang::BuiltinType::Char32:
+                case clang::BuiltinType::UShort:
+                case clang::BuiltinType::UInt:
+                case clang::BuiltinType::ULong:
+                case clang::BuiltinType::ULongLong:
+                case clang::BuiltinType::UInt128:
+                case clang::BuiltinType::Char_S:
+                case clang::BuiltinType::SChar:
+                case clang::BuiltinType::WChar_S:
+                case clang::BuiltinType::Short:
+                case clang::BuiltinType::Int:
+                case clang::BuiltinType::Long:
+                case clang::BuiltinType::LongLong:
+                case clang::BuiltinType::Int128:
+                case clang::BuiltinType::Float:
+                case clang::BuiltinType::Double:
+                case clang::BuiltinType::LongDouble:
+                    break;
+
+                case clang::BuiltinType::NullPtr:   
+                    return eLanguageTypeC_plus_plus;
+                    
+                case clang::BuiltinType::ObjCId:
+                case clang::BuiltinType::ObjCClass:
+                case clang::BuiltinType::ObjCSel:   
+                    return eLanguageTypeObjC;
+
+                case clang::BuiltinType::Dependent:
+                case clang::BuiltinType::Overload:
+                case clang::BuiltinType::BoundMember:
+                case clang::BuiltinType::UnknownAny:
+                    break;
+            }
+            break;
+        case clang::Type::Typedef:
+            return GetMinimumLanguage(ctx,
+                                      llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+        }
+    }
+    return lldb::eLanguageTypeC;
+}
+
+lldb::Encoding
+ClangASTType::GetEncoding (clang_type_t clang_type, uint32_t &count)
+{
+    count = 1;
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+
+    switch (qual_type->getTypeClass())
+    {
+    case clang::Type::UnaryTransform:
+        break;
+            
+    case clang::Type::FunctionNoProto:
+    case clang::Type::FunctionProto:
+        break;
+
+    case clang::Type::IncompleteArray:
+    case clang::Type::VariableArray:
+        break;
+
+    case clang::Type::ConstantArray:
+        break;
+
+    case clang::Type::ExtVector:
+    case clang::Type::Vector:
+        // TODO: Set this to more than one???
+        break;
+
+    case clang::Type::Builtin:
+        switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
+        {
+        default: assert(0 && "Unknown builtin type!");
+        case clang::BuiltinType::Void:
+            break;
+
+        case clang::BuiltinType::Bool:
+        case clang::BuiltinType::Char_S:
+        case clang::BuiltinType::SChar:
+        case clang::BuiltinType::WChar_S:
+        case clang::BuiltinType::Char16:
+        case clang::BuiltinType::Char32:
+        case clang::BuiltinType::Short:
+        case clang::BuiltinType::Int:
+        case clang::BuiltinType::Long:
+        case clang::BuiltinType::LongLong:
+        case clang::BuiltinType::Int128:        return lldb::eEncodingSint;
+
+        case clang::BuiltinType::Char_U:
+        case clang::BuiltinType::UChar:
+        case clang::BuiltinType::WChar_U:
+        case clang::BuiltinType::UShort:
+        case clang::BuiltinType::UInt:
+        case clang::BuiltinType::ULong:
+        case clang::BuiltinType::ULongLong:
+        case clang::BuiltinType::UInt128:       return lldb::eEncodingUint;
+
+        case clang::BuiltinType::Float:
+        case clang::BuiltinType::Double:
+        case clang::BuiltinType::LongDouble:    return lldb::eEncodingIEEE754;
+        
+        case clang::BuiltinType::ObjCClass:
+        case clang::BuiltinType::ObjCId:
+        case clang::BuiltinType::ObjCSel:       return lldb::eEncodingUint;
+
+        case clang::BuiltinType::NullPtr:       return lldb::eEncodingUint;
+        }
+        break;
+    // All pointer types are represented as unsigned integer encodings.
+    // We may nee to add a eEncodingPointer if we ever need to know the
+    // difference
+    case clang::Type::ObjCObjectPointer:
+    case clang::Type::BlockPointer:
+    case clang::Type::Pointer:
+    case clang::Type::LValueReference:
+    case clang::Type::RValueReference:
+    case clang::Type::MemberPointer:            return lldb::eEncodingUint;
+    case clang::Type::Complex:
+        {
+            lldb::Encoding encoding = lldb::eEncodingIEEE754;
+            if (qual_type->isComplexType())
+                encoding = lldb::eEncodingIEEE754;
+            else
+            {
+                const clang::ComplexType *complex_type = qual_type->getAsComplexIntegerType();
+                if (complex_type)
+                    encoding = GetEncoding (complex_type->getElementType().getAsOpaquePtr(), count);
+                else 
+                    encoding = lldb::eEncodingSint;
+            }
+            count = 2;
+            return encoding;
+        }
+
+    case clang::Type::ObjCInterface:            break;
+    case clang::Type::Record:                   break;
+    case clang::Type::Enum:                     return lldb::eEncodingSint;
+    case clang::Type::Typedef:
+            return GetEncoding(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), count);
+        break;
+
+    case clang::Type::DependentSizedArray:
+    case clang::Type::DependentSizedExtVector:
+    case clang::Type::UnresolvedUsing:
+    case clang::Type::Paren:
+    case clang::Type::Elaborated:
+    case clang::Type::Attributed:
+    case clang::Type::TemplateTypeParm:
+    case clang::Type::SubstTemplateTypeParm:
+    case clang::Type::SubstTemplateTypeParmPack:
+    case clang::Type::Auto:
+    case clang::Type::InjectedClassName:
+    case clang::Type::DependentName:
+    case clang::Type::DependentTemplateSpecialization:
+    case clang::Type::PackExpansion:
+    case clang::Type::ObjCObject:
+            
+    case clang::Type::TypeOfExpr:
+    case clang::Type::TypeOf:
+    case clang::Type::Decltype:
+    case clang::Type::TemplateSpecialization:
+    case clang::Type::Atomic:
+        break;
+
+    }
+    count = 0;
+    return lldb::eEncodingInvalid;
+}
+
+lldb::Format
+ClangASTType::GetFormat ()
+{
+    return GetFormat (m_type);
+}
+
+lldb::Format
+ClangASTType::GetFormat (clang_type_t clang_type)
+{
+    if (clang_type == NULL)
+        return lldb::eFormatDefault;
+        
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+
+    switch (qual_type->getTypeClass())
+    {
+    case clang::Type::UnaryTransform:
+        break;
+        
+    case clang::Type::FunctionNoProto:
+    case clang::Type::FunctionProto:
+        break;
+
+    case clang::Type::IncompleteArray:
+    case clang::Type::VariableArray:
+        break;
+
+    case clang::Type::ConstantArray:
+        break;
+
+    case clang::Type::ExtVector:
+    case clang::Type::Vector:
+        break;
+
+    case clang::Type::Builtin:
+        switch (llvm::cast<clang::BuiltinType>(qual_type)->getKind())
+        {
+        //default: assert(0 && "Unknown builtin type!");
+        case clang::BuiltinType::UnknownAny:
+        case clang::BuiltinType::Void:
+        case clang::BuiltinType::BoundMember:
+            break;
+
+        case clang::BuiltinType::Bool:          return lldb::eFormatBoolean;
+        case clang::BuiltinType::Char_S:
+        case clang::BuiltinType::SChar:
+        case clang::BuiltinType::WChar_S:
+        case clang::BuiltinType::Char_U:
+        case clang::BuiltinType::UChar:
+        case clang::BuiltinType::WChar_U:       return lldb::eFormatChar;
+        case clang::BuiltinType::Char16:        return lldb::eFormatUnicode16;
+        case clang::BuiltinType::Char32:        return lldb::eFormatUnicode32;
+        case clang::BuiltinType::UShort:        return lldb::eFormatUnsigned;
+        case clang::BuiltinType::Short:         return lldb::eFormatDecimal;
+        case clang::BuiltinType::UInt:          return lldb::eFormatUnsigned;
+        case clang::BuiltinType::Int:           return lldb::eFormatDecimal;
+        case clang::BuiltinType::ULong:         return lldb::eFormatUnsigned;
+        case clang::BuiltinType::Long:          return lldb::eFormatDecimal;
+        case clang::BuiltinType::ULongLong:     return lldb::eFormatUnsigned;
+        case clang::BuiltinType::LongLong:      return lldb::eFormatDecimal;
+        case clang::BuiltinType::UInt128:       return lldb::eFormatUnsigned;
+        case clang::BuiltinType::Int128:        return lldb::eFormatDecimal;
+        case clang::BuiltinType::Float:         return lldb::eFormatFloat;
+        case clang::BuiltinType::Double:        return lldb::eFormatFloat;
+        case clang::BuiltinType::LongDouble:    return lldb::eFormatFloat;
+        case clang::BuiltinType::NullPtr:       
+        case clang::BuiltinType::Overload:
+        case clang::BuiltinType::Dependent:
+        case clang::BuiltinType::ObjCId:
+        case clang::BuiltinType::ObjCClass:
+        case clang::BuiltinType::ObjCSel:       
+        case clang::BuiltinType::Half:          
+        case clang::BuiltinType::ARCUnbridgedCast:          
+        case clang::BuiltinType::PseudoObject:
+        case clang::BuiltinType::BuiltinFn:
+            return lldb::eFormatHex;
+        }
+        break;
+    case clang::Type::ObjCObjectPointer:        return lldb::eFormatHex;
+    case clang::Type::BlockPointer:             return lldb::eFormatHex;
+    case clang::Type::Pointer:                  return lldb::eFormatHex;
+    case clang::Type::LValueReference:
+    case clang::Type::RValueReference:          return lldb::eFormatHex;
+    case clang::Type::MemberPointer:            break;
+    case clang::Type::Complex:
+        {
+            if (qual_type->isComplexType())
+                return lldb::eFormatComplex;
+            else
+                return lldb::eFormatComplexInteger;
+        }
+    case clang::Type::ObjCInterface:            break;
+    case clang::Type::Record:                   break;
+    case clang::Type::Enum:                     return lldb::eFormatEnum;
+    case clang::Type::Typedef:
+            return ClangASTType::GetFormat(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+
+    case clang::Type::Auto:
+            return ClangASTType::GetFormat(llvm::cast<clang::AutoType>(qual_type)->desugar().getAsOpaquePtr());
+    case clang::Type::DependentSizedArray:
+    case clang::Type::DependentSizedExtVector:
+    case clang::Type::UnresolvedUsing:
+    case clang::Type::Paren:
+    case clang::Type::Elaborated:
+    case clang::Type::Attributed:
+    case clang::Type::TemplateTypeParm:
+    case clang::Type::SubstTemplateTypeParm:
+    case clang::Type::SubstTemplateTypeParmPack:
+    case clang::Type::InjectedClassName:
+    case clang::Type::DependentName:
+    case clang::Type::DependentTemplateSpecialization:
+    case clang::Type::PackExpansion:
+    case clang::Type::ObjCObject:
+            
+    case clang::Type::TypeOfExpr:
+    case clang::Type::TypeOf:
+    case clang::Type::Decltype:
+    case clang::Type::TemplateSpecialization:
+    case clang::Type::Atomic:
+            break;
+    }
+    // We don't know hot to display this type...
+    return lldb::eFormatBytes;
+}
+
+
+void
+ClangASTType::DumpValue
+(
+    ExecutionContext *exe_ctx,
+    Stream *s,
+    lldb::Format format,
+    const lldb_private::DataExtractor &data,
+    uint32_t data_byte_offset,
+    size_t data_byte_size,
+    uint32_t bitfield_bit_size,
+    uint32_t bitfield_bit_offset,
+    bool show_types,
+    bool show_summary,
+    bool verbose,
+    uint32_t depth
+)
+{
+    return DumpValue (m_ast, 
+                      m_type,
+                      exe_ctx,
+                      s,
+                      format,
+                      data,
+                      data_byte_offset,
+                      data_byte_size,
+                      bitfield_bit_size,
+                      bitfield_bit_offset,
+                      show_types,
+                      show_summary,
+                      verbose,
+                      depth);
+}
+                      
+#define DEPTH_INCREMENT 2
+void
+ClangASTType::DumpValue
+(
+    clang::ASTContext *ast_context,
+    clang_type_t clang_type,
+    ExecutionContext *exe_ctx,
+    Stream *s,
+    lldb::Format format,
+    const lldb_private::DataExtractor &data,
+    uint32_t data_byte_offset,
+    size_t data_byte_size,
+    uint32_t bitfield_bit_size,
+    uint32_t bitfield_bit_offset,
+    bool show_types,
+    bool show_summary,
+    bool verbose,
+    uint32_t depth
+)
+{
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+    switch (qual_type->getTypeClass())
+    {
+    case clang::Type::Record:
+        if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+        {
+            const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+            const clang::RecordDecl *record_decl = record_type->getDecl();
+            assert(record_decl);
+            uint32_t field_bit_offset = 0;
+            uint32_t field_byte_offset = 0;
+            const clang::ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl);
+            uint32_t child_idx = 0;
+
+
+            const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+            if (cxx_record_decl)
+            {
+                // We might have base classes to print out first
+                clang::CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+                for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+                     base_class != base_class_end;
+                     ++base_class)
+                {
+                    const clang::CXXRecordDecl *base_class_decl = llvm::cast<clang::CXXRecordDecl>(base_class->getType()->getAs<clang::RecordType>()->getDecl());
+
+                    // Skip empty base classes
+                    if (verbose == false && ClangASTContext::RecordHasFields(base_class_decl) == false)
+                        continue;
+
+                    if (base_class->isVirtual())
+                        field_bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+                    else
+                        field_bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
+                    field_byte_offset = field_bit_offset / 8;
+                    assert (field_bit_offset % 8 == 0);
+                    if (child_idx == 0)
+                        s->PutChar('{');
+                    else
+                        s->PutChar(',');
+
+                    clang::QualType base_class_qual_type = base_class->getType();
+                    std::string base_class_type_name(base_class_qual_type.getAsString());
+
+                    // Indent and print the base class type name
+                    s->Printf("\n%*s%s ", depth + DEPTH_INCREMENT, "", base_class_type_name.c_str());
+
+                    std::pair<uint64_t, unsigned> base_class_type_info = ast_context->getTypeInfo(base_class_qual_type);
+
+                    // Dump the value of the member
+                    DumpValue (ast_context,                        // The clang AST context for this type
+                               base_class_qual_type.getAsOpaquePtr(),// The clang type we want to dump
+                               exe_ctx,
+                               s,                                  // Stream to dump to
+                               ClangASTType::GetFormat(base_class_qual_type.getAsOpaquePtr()), // The format with which to display the member
+                               data,                               // Data buffer containing all bytes for this type
+                               data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
+                               base_class_type_info.first / 8,     // Size of this type in bytes
+                               0,                                  // Bitfield bit size
+                               0,                                  // Bitfield bit offset
+                               show_types,                         // Boolean indicating if we should show the variable types
+                               show_summary,                       // Boolean indicating if we should show a summary for the current type
+                               verbose,                            // Verbose output?
+                               depth + DEPTH_INCREMENT);           // Scope depth for any types that have children
+                    
+                    ++child_idx;
+                }
+            }
+            uint32_t field_idx = 0;
+            clang::RecordDecl::field_iterator field, field_end;
+            for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
+            {
+                // Print the starting squiggly bracket (if this is the
+                // first member) or comman (for member 2 and beyong) for
+                // the struct/union/class member.
+                if (child_idx == 0)
+                    s->PutChar('{');
+                else
+                    s->PutChar(',');
+
+                // Indent
+                s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");
+
+                clang::QualType field_type = field->getType();
+                // Print the member type if requested
+                // Figure out the type byte size (field_type_info.first) and
+                // alignment (field_type_info.second) from the AST context.
+                std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field_type);
+                assert(field_idx < record_layout.getFieldCount());
+                // Figure out the field offset within the current struct/union/class type
+                field_bit_offset = record_layout.getFieldOffset (field_idx);
+                field_byte_offset = field_bit_offset / 8;
+                uint32_t field_bitfield_bit_size = 0;
+                uint32_t field_bitfield_bit_offset = 0;
+                if (ClangASTContext::FieldIsBitfield (ast_context, *field, field_bitfield_bit_size))
+                    field_bitfield_bit_offset = field_bit_offset % 8;
+
+                if (show_types)
+                {
+                    std::string field_type_name(field_type.getAsString());
+                    if (field_bitfield_bit_size > 0)
+                        s->Printf("(%s:%u) ", field_type_name.c_str(), field_bitfield_bit_size);
+                    else
+                        s->Printf("(%s) ", field_type_name.c_str());
+                }
+                // Print the member name and equal sign
+                s->Printf("%s = ", field->getNameAsString().c_str());
+
+
+                // Dump the value of the member
+                DumpValue (ast_context,                    // The clang AST context for this type
+                           field_type.getAsOpaquePtr(),    // The clang type we want to dump
+                           exe_ctx,
+                           s,                              // Stream to dump to
+                           ClangASTType::GetFormat(field_type.getAsOpaquePtr()),   // The format with which to display the member
+                           data,                           // Data buffer containing all bytes for this type
+                           data_byte_offset + field_byte_offset,// Offset into "data" where to grab value from
+                           field_type_info.first / 8,      // Size of this type in bytes
+                           field_bitfield_bit_size,        // Bitfield bit size
+                           field_bitfield_bit_offset,      // Bitfield bit offset
+                           show_types,                     // Boolean indicating if we should show the variable types
+                           show_summary,                   // Boolean indicating if we should show a summary for the current type
+                           verbose,                        // Verbose output?
+                           depth + DEPTH_INCREMENT);       // Scope depth for any types that have children
+            }
+
+            // Indent the trailing squiggly bracket
+            if (child_idx > 0)
+                s->Printf("\n%*s}", depth, "");
+        }
+        return;
+
+    case clang::Type::Enum:
+        if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+        {
+            const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
+            const clang::EnumDecl *enum_decl = enum_type->getDecl();
+            assert(enum_decl);
+            clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
+            uint32_t offset = data_byte_offset;
+            const int64_t enum_value = data.GetMaxU64Bitfield(&offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
+            for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
+            {
+                if (enum_pos->getInitVal() == enum_value)
+                {
+                    s->Printf("%s", enum_pos->getNameAsString().c_str());
+                    return;
+                }
+            }
+            // If we have gotten here we didn't get find the enumerator in the
+            // enum decl, so just print the integer.
+            s->Printf("%lli", enum_value);
+        }
+        return;
+
+    case clang::Type::ConstantArray:
+        {
+            const clang::ConstantArrayType *array = llvm::cast<clang::ConstantArrayType>(qual_type.getTypePtr());
+            bool is_array_of_characters = false;
+            clang::QualType element_qual_type = array->getElementType();
+
+            const clang::Type *canonical_type = element_qual_type->getCanonicalTypeInternal().getTypePtr();
+            if (canonical_type)
+                is_array_of_characters = canonical_type->isCharType();
+
+            const uint64_t element_count = array->getSize().getLimitedValue();
+
+            std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(element_qual_type);
+
+            uint32_t element_idx = 0;
+            uint32_t element_offset = 0;
+            uint64_t element_byte_size = field_type_info.first / 8;
+            uint32_t element_stride = element_byte_size;
+
+            if (is_array_of_characters)
+            {
+                s->PutChar('"');
+                data.Dump(s, data_byte_offset, lldb::eFormatChar, element_byte_size, element_count, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
+                s->PutChar('"');
+                return;
+            }
+            else
+            {
+                lldb::Format element_format = ClangASTType::GetFormat(element_qual_type.getAsOpaquePtr());
+
+                for (element_idx = 0; element_idx < element_count; ++element_idx)
+                {
+                    // Print the starting squiggly bracket (if this is the
+                    // first member) or comman (for member 2 and beyong) for
+                    // the struct/union/class member.
+                    if (element_idx == 0)
+                        s->PutChar('{');
+                    else
+                        s->PutChar(',');
+
+                    // Indent and print the index
+                    s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx);
+
+                    // Figure out the field offset within the current struct/union/class type
+                    element_offset = element_idx * element_stride;
+
+                    // Dump the value of the member
+                    DumpValue (ast_context,                    // The clang AST context for this type
+                               element_qual_type.getAsOpaquePtr(), // The clang type we want to dump
+                               exe_ctx,
+                               s,                              // Stream to dump to
+                               element_format,                 // The format with which to display the element
+                               data,                           // Data buffer containing all bytes for this type
+                               data_byte_offset + element_offset,// Offset into "data" where to grab value from
+                               element_byte_size,              // Size of this type in bytes
+                               0,                              // Bitfield bit size
+                               0,                              // Bitfield bit offset
+                               show_types,                     // Boolean indicating if we should show the variable types
+                               show_summary,                   // Boolean indicating if we should show a summary for the current type
+                               verbose,                        // Verbose output?
+                               depth + DEPTH_INCREMENT);       // Scope depth for any types that have children
+                }
+
+                // Indent the trailing squiggly bracket
+                if (element_idx > 0)
+                    s->Printf("\n%*s}", depth, "");
+            }
+        }
+        return;
+
+    case clang::Type::Typedef:
+        {
+            clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType();
+            lldb::Format typedef_format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr());
+            std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type);
+            uint64_t typedef_byte_size = typedef_type_info.first / 8;
+
+            return DumpValue (ast_context,        // The clang AST context for this type
+                              typedef_qual_type.getAsOpaquePtr(), // The clang type we want to dump
+                              exe_ctx,
+                              s,                  // Stream to dump to
+                              typedef_format,     // The format with which to display the element
+                              data,               // Data buffer containing all bytes for this type
+                              data_byte_offset,   // Offset into "data" where to grab value from
+                              typedef_byte_size,  // Size of this type in bytes
+                              bitfield_bit_size,  // Bitfield bit size
+                              bitfield_bit_offset,// Bitfield bit offset
+                              show_types,         // Boolean indicating if we should show the variable types
+                              show_summary,       // Boolean indicating if we should show a summary for the current type
+                              verbose,            // Verbose output?
+                              depth);             // Scope depth for any types that have children
+        }
+        break;
+
+    default:
+        // We are down the a scalar type that we just need to display.
+        data.Dump(s, data_byte_offset, format, data_byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset);
+
+        if (show_summary)
+            DumpSummary (ast_context, clang_type, exe_ctx, s, data, data_byte_offset, data_byte_size);
+        break;
+    }
+}
+
+
+
+bool
+ClangASTType::DumpTypeValue (Stream *s,
+                             lldb::Format format,
+                             const lldb_private::DataExtractor &data,
+                             uint32_t byte_offset,
+                             size_t byte_size,
+                             uint32_t bitfield_bit_size,
+                             uint32_t bitfield_bit_offset,
+                             ExecutionContextScope *exe_scope)
+{
+    return DumpTypeValue (m_ast,
+                          m_type,
+                          s,
+                          format,
+                          data,
+                          byte_offset,
+                          byte_size,
+                          bitfield_bit_size,
+                          bitfield_bit_offset,
+                          exe_scope);
+}
+
+
+bool
+ClangASTType::DumpTypeValue (clang::ASTContext *ast_context,
+                             clang_type_t clang_type,
+                             Stream *s,
+                             lldb::Format format,
+                             const lldb_private::DataExtractor &data,
+                             uint32_t byte_offset,
+                             size_t byte_size,
+                             uint32_t bitfield_bit_size,
+                             uint32_t bitfield_bit_offset,
+                             ExecutionContextScope *exe_scope)
+{
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+    if (ClangASTContext::IsAggregateType (clang_type))
+    {
+        return 0;
+    }
+    else
+    {
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+            
+        switch (type_class)
+        {
+        case clang::Type::Typedef:
+            {
+                clang::QualType typedef_qual_type = llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType();
+                if (format == eFormatDefault)
+                    format = ClangASTType::GetFormat(typedef_qual_type.getAsOpaquePtr());
+                std::pair<uint64_t, unsigned> typedef_type_info = ast_context->getTypeInfo(typedef_qual_type);
+                uint64_t typedef_byte_size = typedef_type_info.first / 8;
+
+                return ClangASTType::DumpTypeValue (ast_context,            // The clang AST context for this type
+                                                    typedef_qual_type.getAsOpaquePtr(),     // The clang type we want to dump
+                                                    s,
+                                                    format,                 // The format with which to display the element
+                                                    data,                   // Data buffer containing all bytes for this type
+                                                    byte_offset,            // Offset into "data" where to grab value from
+                                                    typedef_byte_size,      // Size of this type in bytes
+                                                    bitfield_bit_size,      // Size in bits of a bitfield value, if zero don't treat as a bitfield
+                                                    bitfield_bit_offset,    // Offset in bits of a bitfield value if bitfield_bit_size != 0
+                                                    exe_scope);
+            }
+            break;
+
+        case clang::Type::Enum:
+            // If our format is enum or default, show the enumeration value as
+            // its enumeration string value, else just display it as requested.
+            if ((format == eFormatEnum || format == eFormatDefault) && ClangASTContext::GetCompleteType (ast_context, clang_type))
+            {
+                const clang::EnumType *enum_type = llvm::cast<clang::EnumType>(qual_type.getTypePtr());
+                const clang::EnumDecl *enum_decl = enum_type->getDecl();
+                assert(enum_decl);
+                clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
+                uint32_t offset = byte_offset;
+                const int64_t enum_value = data.GetMaxU64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
+                for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
+                {
+                    if (enum_pos->getInitVal() == enum_value)
+                    {
+                        s->PutCString (enum_pos->getNameAsString().c_str());
+                        return true;
+                    }
+                }
+                // If we have gotten here we didn't get find the enumerator in the
+                // enum decl, so just print the integer.
+                
+                s->Printf("%lli", enum_value);
+                return true;
+            }
+            // format was not enum, just fall through and dump the value as requested....
+                
+        default:
+            // We are down the a scalar type that we just need to display.
+            {
+                uint32_t item_count = 1;
+                // A few formats, we might need to modify our size and count for depending
+                // on how we are trying to display the value...
+                switch (format)
+                {
+                    default:
+                    case eFormatBoolean:
+                    case eFormatBinary:
+                    case eFormatComplex:
+                    case eFormatCString:         // NULL terminated C strings
+                    case eFormatDecimal:
+                    case eFormatEnum:
+                    case eFormatHex:
+                    case eFormatHexUppercase:
+                    case eFormatFloat:
+                    case eFormatOctal:
+                    case eFormatOSType:
+                    case eFormatUnsigned:
+                    case eFormatPointer:
+                    case eFormatVectorOfChar:
+                    case eFormatVectorOfSInt8:
+                    case eFormatVectorOfUInt8:
+                    case eFormatVectorOfSInt16:
+                    case eFormatVectorOfUInt16:
+                    case eFormatVectorOfSInt32:
+                    case eFormatVectorOfUInt32:
+                    case eFormatVectorOfSInt64:
+                    case eFormatVectorOfUInt64:
+                    case eFormatVectorOfFloat32:
+                    case eFormatVectorOfFloat64:
+                    case eFormatVectorOfUInt128:
+                        break;
+
+                    case eFormatChar: 
+                    case eFormatCharPrintable:  
+                    case eFormatCharArray:
+                    case eFormatBytes:
+                    case eFormatBytesWithASCII:
+                        item_count = byte_size;
+                        byte_size = 1; 
+                        break;
+
+                    case eFormatUnicode16:
+                        item_count = byte_size / 2; 
+                        byte_size = 2; 
+                        break;
+
+                    case eFormatUnicode32:
+                        item_count = byte_size / 4; 
+                        byte_size = 4; 
+                        break;
+                }
+                return data.Dump (s,
+                                  byte_offset,
+                                  format,
+                                  byte_size,
+                                  item_count,
+                                  UINT32_MAX,
+                                  LLDB_INVALID_ADDRESS,
+                                  bitfield_bit_size,
+                                  bitfield_bit_offset,
+                                  exe_scope);
+            }
+            break;
+        }
+    }
+    return 0;
+}
+
+
+
+void
+ClangASTType::DumpSummary
+(
+    ExecutionContext *exe_ctx,
+    Stream *s,
+    const lldb_private::DataExtractor &data,
+    uint32_t data_byte_offset,
+    size_t data_byte_size
+)
+{
+    return DumpSummary (m_ast,
+                        m_type,
+                        exe_ctx, 
+                        s, 
+                        data, 
+                        data_byte_offset, 
+                        data_byte_size);
+}
+
+void
+ClangASTType::DumpSummary
+(
+    clang::ASTContext *ast_context,
+    clang_type_t clang_type,
+    ExecutionContext *exe_ctx,
+    Stream *s,
+    const lldb_private::DataExtractor &data,
+    uint32_t data_byte_offset,
+    size_t data_byte_size
+)
+{
+    uint32_t length = 0;
+    if (ClangASTContext::IsCStringType (clang_type, length))
+    {
+        if (exe_ctx)
+        {
+            Process *process = exe_ctx->GetProcessPtr();
+            if (process)
+            {
+                uint32_t offset = data_byte_offset;
+                lldb::addr_t pointer_addresss = data.GetMaxU64(&offset, data_byte_size);
+                std::vector<uint8_t> buf;
+                if (length > 0)
+                    buf.resize (length);
+                else
+                    buf.resize (256);
+
+                lldb_private::DataExtractor cstr_data(&buf.front(), buf.size(), process->GetByteOrder(), 4);
+                buf.back() = '\0';
+                size_t bytes_read;
+                size_t total_cstr_len = 0;
+                Error error;
+                while ((bytes_read = process->ReadMemory (pointer_addresss, &buf.front(), buf.size(), error)) > 0)
+                {
+                    const size_t len = strlen((const char *)&buf.front());
+                    if (len == 0)
+                        break;
+                    if (total_cstr_len == 0)
+                        s->PutCString (" \"");
+                    cstr_data.Dump(s, 0, lldb::eFormatChar, 1, len, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
+                    total_cstr_len += len;
+                    if (len < buf.size())
+                        break;
+                    pointer_addresss += total_cstr_len;
+                }
+                if (total_cstr_len > 0)
+                    s->PutChar ('"');
+            }
+        }
+    }
+}
+
+uint32_t
+ClangASTType::GetClangTypeBitWidth ()
+{
+    return GetClangTypeBitWidth (m_ast, m_type);
+}
+
+uint32_t
+ClangASTType::GetClangTypeBitWidth (clang::ASTContext *ast_context, clang_type_t clang_type)
+{
+    if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+    {
+        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+        return ast_context->getTypeSize (qual_type);
+    }
+    return 0;
+}
+
+size_t
+ClangASTType::GetTypeBitAlign ()
+{
+    return GetTypeBitAlign (m_ast, m_type);
+}
+
+size_t
+ClangASTType::GetTypeBitAlign (clang::ASTContext *ast_context, clang_type_t clang_type)
+{
+    if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+        return ast_context->getTypeAlign(clang::QualType::getFromOpaquePtr(clang_type));
+    return 0;
+}
+
+
+bool
+ClangASTType::IsDefined()
+{
+    return ClangASTType::IsDefined (m_type);
+}
+
+bool
+ClangASTType::IsDefined (clang_type_t clang_type)
+{
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+    const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
+    if (tag_type)
+    {
+        clang::TagDecl *tag_decl = tag_type->getDecl();
+        if (tag_decl)
+            return tag_decl->isCompleteDefinition();
+        return false;
+    }
+    else
+    {
+        const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type);
+        if (objc_class_type)
+        {
+            clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+            if (class_interface_decl)
+                return class_interface_decl->getDefinition() != NULL;
+            return false;
+        }
+    }
+    return true;
+}
+
+bool
+ClangASTType::IsConst()
+{
+    return ClangASTType::IsConst (m_type);
+}
+
+bool
+ClangASTType::IsConst (lldb::clang_type_t clang_type)
+{
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+    
+    return qual_type.isConstQualified();
+}
+
+void
+ClangASTType::DumpTypeDescription (Stream *s)
+{
+    return DumpTypeDescription (m_ast, m_type, s);
+}
+
+// Dump the full description of a type. For classes this means all of the
+// ivars and member functions, for structs/unions all of the members. 
+void
+ClangASTType::DumpTypeDescription (clang::ASTContext *ast_context, clang_type_t clang_type, Stream *s)
+{
+    if (clang_type)
+    {
+        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+
+        llvm::SmallVector<char, 1024> buf;
+        llvm::raw_svector_ostream llvm_ostrm (buf);
+
+        const clang::Type::TypeClass type_class = qual_type->getTypeClass();
+        switch (type_class)
+        {
+        case clang::Type::ObjCObject:
+        case clang::Type::ObjCInterface:
+            if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+            {
+                const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr());
+                assert (objc_class_type);
+                if (objc_class_type)
+                {
+                    clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+                    if (class_interface_decl)
+                    {
+                        clang::PrintingPolicy policy = ast_context->getPrintingPolicy();
+<<<<<<< .working
+						
+#if CLANG_VERSION_MAJOR > 3 || (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR  >= 2)
+#else
+                        policy.Dump = 1;
+=======
+                        policy.DumpSourceManager = &ast_context->getSourceManager();
+>>>>>>> .merge-right.r164814
+#endif
+                        class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
+                    }
+                }
+            }
+            break;
+        
+        case clang::Type::Typedef:
+            {
+                const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
+                if (typedef_type)
+                {
+                    const clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
+                    std::string clang_typedef_name (typedef_decl->getQualifiedNameAsString());
+                    if (!clang_typedef_name.empty())
+                    {
+                        s->PutCString ("typedef ");
+                        s->PutCString (clang_typedef_name.c_str());
+                    }
+                }
+            }
+            break;
+
+        case clang::Type::Record:
+            if (ClangASTContext::GetCompleteType (ast_context, clang_type))
+            {
+                const clang::RecordType *record_type = llvm::cast<clang::RecordType>(qual_type.getTypePtr());
+                const clang::RecordDecl *record_decl = record_type->getDecl();
+                const clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(record_decl);
+
+                if (cxx_record_decl)
+                    cxx_record_decl->print(llvm_ostrm, ast_context->getPrintingPolicy(), s->GetIndentLevel());
+                else
+                    record_decl->print(llvm_ostrm, ast_context->getPrintingPolicy(), s->GetIndentLevel());
+            }
+            break;
+
+        default:
+            {
+                const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr());
+                if (tag_type)
+                {
+                    clang::TagDecl *tag_decl = tag_type->getDecl();
+                    if (tag_decl)
+                        tag_decl->print(llvm_ostrm, 0);
+                }
+                else
+                {
+                    std::string clang_type_name(qual_type.getAsString());
+                    if (!clang_type_name.empty())
+                        s->PutCString (clang_type_name.c_str());
+                }
+            }
+        }
+        
+        llvm_ostrm.flush();
+        if (buf.size() > 0)
+        {
+            s->Write (buf.data(), buf.size());
+        }
+    }
+}
+
+void
+ClangASTType::DumpTypeCode (Stream *s)
+{
+    DumpTypeCode(m_type, s);
+}
+
+void
+ClangASTType::DumpTypeCode (void *type, 
+                            Stream *s)
+{
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(type));
+    s->PutCString(qual_type.getAsString().c_str());
+}
+
+bool
+ClangASTType::GetValueAsScalar
+(
+    const lldb_private::DataExtractor &data,
+    uint32_t data_byte_offset,
+    size_t data_byte_size,
+    Scalar &value
+)
+{
+    return GetValueAsScalar (m_ast, 
+                             m_type, 
+                             data, 
+                             data_byte_offset, 
+                             data_byte_size, 
+                             value);
+}
+
+bool
+ClangASTType::GetValueAsScalar
+(
+    clang::ASTContext *ast_context,
+    clang_type_t clang_type,
+    const lldb_private::DataExtractor &data,
+    uint32_t data_byte_offset,
+    size_t data_byte_size,
+    Scalar &value
+)
+{
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+
+    if (ClangASTContext::IsAggregateType (clang_type))
+    {
+        return false;   // Aggregate types don't have scalar values
+    }
+    else
+    {
+        uint32_t count = 0;
+        lldb::Encoding encoding = GetEncoding (clang_type, count);
+
+        if (encoding == lldb::eEncodingInvalid || count != 1)
+            return false;
+
+        uint64_t bit_width = ast_context->getTypeSize(qual_type);
+        uint32_t byte_size = (bit_width + 7 ) / 8;
+        uint32_t offset = data_byte_offset;
+        switch (encoding)
+        {
+        case lldb::eEncodingInvalid:
+            break;
+        case lldb::eEncodingVector:
+            break;
+        case lldb::eEncodingUint:
+            if (byte_size <= sizeof(unsigned long long))
+            {
+                uint64_t uval64 = data.GetMaxU64 (&offset, byte_size);
+                if (byte_size <= sizeof(unsigned int))
+                {
+                    value = (unsigned int)uval64;
+                    return true;
+                }
+                else if (byte_size <= sizeof(unsigned long))
+                {
+                    value = (unsigned long)uval64;
+                    return true;
+                }
+                else if (byte_size <= sizeof(unsigned long long))
+                {
+                    value = (unsigned long long )uval64;
+                    return true;
+                }
+                else
+                    value.Clear();
+            }
+            break;
+
+        case lldb::eEncodingSint:
+            if (byte_size <= sizeof(long long))
+            {
+                int64_t sval64 = data.GetMaxS64 (&offset, byte_size);
+                if (byte_size <= sizeof(int))
+                {
+                    value = (int)sval64;
+                    return true;
+                }
+                else if (byte_size <= sizeof(long))
+                {
+                    value = (long)sval64;
+                    return true;
+                }
+                else if (byte_size <= sizeof(long long))
+                {
+                    value = (long long )sval64;
+                    return true;
+                }
+                else
+                    value.Clear();
+            }
+            break;
+
+        case lldb::eEncodingIEEE754:
+            if (byte_size <= sizeof(long double))
+            {
+                uint32_t u32;
+                uint64_t u64;
+                if (byte_size == sizeof(float))
+                {
+                    if (sizeof(float) == sizeof(uint32_t))
+                    {
+                        u32 = data.GetU32(&offset);
+                        value = *((float *)&u32);
+                        return true;
+                    }
+                    else if (sizeof(float) == sizeof(uint64_t))
+                    {
+                        u64 = data.GetU64(&offset);
+                        value = *((float *)&u64);
+                        return true;
+                    }
+                }
+                else
+                if (byte_size == sizeof(double))
+                {
+                    if (sizeof(double) == sizeof(uint32_t))
+                    {
+                        u32 = data.GetU32(&offset);
+                        value = *((double *)&u32);
+                        return true;
+                    }
+                    else if (sizeof(double) == sizeof(uint64_t))
+                    {
+                        u64 = data.GetU64(&offset);
+                        value = *((double *)&u64);
+                        return true;
+                    }
+                }
+                else
+                if (byte_size == sizeof(long double))
+                {
+                    if (sizeof(long double) == sizeof(uint32_t))
+                    {
+                        u32 = data.GetU32(&offset);
+                        value = *((long double *)&u32);
+                        return true;
+                    }
+                    else if (sizeof(long double) == sizeof(uint64_t))
+                    {
+                        u64 = data.GetU64(&offset);
+                        value = *((long double *)&u64);
+                        return true;
+                    }
+                }
+            }
+            break;
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTType::SetValueFromScalar (const Scalar &value, Stream &strm)
+{
+    return SetValueFromScalar (m_ast, m_type, value, strm);
+}
+
+bool
+ClangASTType::SetValueFromScalar
+(
+    clang::ASTContext *ast_context,
+    clang_type_t clang_type,
+    const Scalar &value,
+    Stream &strm
+)
+{
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+
+    // Aggregate types don't have scalar values
+    if (!ClangASTContext::IsAggregateType (clang_type))
+    {
+        strm.GetFlags().Set(Stream::eBinary);
+        uint32_t count = 0;
+        lldb::Encoding encoding = GetEncoding (clang_type, count);
+
+        if (encoding == lldb::eEncodingInvalid || count != 1)
+            return false;
+
+        uint64_t bit_width = ast_context->getTypeSize(qual_type);
+        // This function doesn't currently handle non-byte aligned assignments
+        if ((bit_width % 8) != 0)
+            return false;
+
+        uint32_t byte_size = (bit_width + 7 ) / 8;
+        switch (encoding)
+        {
+        case lldb::eEncodingInvalid:
+            break;
+        case lldb::eEncodingVector:
+            break;
+        case lldb::eEncodingUint:
+            switch (byte_size)
+            {
+            case 1: strm.PutHex8(value.UInt()); return true;
+            case 2: strm.PutHex16(value.UInt()); return true;
+            case 4: strm.PutHex32(value.UInt()); return true;
+            case 8: strm.PutHex64(value.ULongLong()); return true;
+            default:
+                break;
+            }
+            break;
+
+        case lldb::eEncodingSint:
+            switch (byte_size)
+            {
+            case 1: strm.PutHex8(value.SInt()); return true;
+            case 2: strm.PutHex16(value.SInt()); return true;
+            case 4: strm.PutHex32(value.SInt()); return true;
+            case 8: strm.PutHex64(value.SLongLong()); return true;
+            default:
+                break;
+            }
+            break;
+
+        case lldb::eEncodingIEEE754:
+            if (byte_size <= sizeof(long double))
+            {
+                if (byte_size == sizeof(float))
+                {
+                    strm.PutFloat(value.Float());
+                    return true;
+                }
+                else
+                if (byte_size == sizeof(double))
+                {
+                    strm.PutDouble(value.Double());
+                    return true;
+                }
+                else
+                if (byte_size == sizeof(long double))
+                {
+                    strm.PutDouble(value.LongDouble());
+                    return true;
+                }
+            }
+            break;
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTType::ReadFromMemory
+(
+    lldb_private::ExecutionContext *exe_ctx,
+    lldb::addr_t addr,
+    AddressType address_type,
+    lldb_private::DataExtractor &data
+)
+{
+    return ReadFromMemory (m_ast,
+                           m_type,
+                           exe_ctx, 
+                           addr,
+                           address_type,
+                           data);
+}
+
+uint32_t
+ClangASTType::GetTypeByteSize() const
+{
+    return GetTypeByteSize(m_ast,
+                           m_type);
+}
+
+uint32_t
+ClangASTType::GetTypeByteSize(
+                clang::ASTContext *ast_context,
+                lldb::clang_type_t opaque_clang_qual_type)
+{
+    
+    if (ClangASTContext::GetCompleteType (ast_context, opaque_clang_qual_type))
+    {
+        clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
+        
+        uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
+        
+        if (ClangASTContext::IsObjCClassType(opaque_clang_qual_type))
+            byte_size += ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / 8; // isa
+        
+        return byte_size;
+    }
+    return 0;
+}
+
+
+bool
+ClangASTType::ReadFromMemory
+(
+    clang::ASTContext *ast_context,
+    clang_type_t clang_type,
+    lldb_private::ExecutionContext *exe_ctx,
+    lldb::addr_t addr,
+    AddressType address_type,
+    lldb_private::DataExtractor &data
+)
+{
+    if (address_type == eAddressTypeFile)
+    {
+        // Can't convert a file address to anything valid without more
+        // context (which Module it came from)
+        return false;
+    }
+    
+    if (!ClangASTContext::GetCompleteType(ast_context, clang_type))
+        return false;
+    
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+    
+    const uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
+    if (data.GetByteSize() < byte_size)
+    {
+        lldb::DataBufferSP data_sp(new DataBufferHeap (byte_size, '\0'));
+        data.SetData(data_sp);
+    }
+
+    uint8_t* dst = (uint8_t*)data.PeekData(0, byte_size);
+    if (dst != NULL)
+    {
+        if (address_type == eAddressTypeHost)
+        {
+            // The address is an address in this process, so just copy it
+            memcpy (dst, (uint8_t*)NULL + addr, byte_size);
+            return true;
+        }
+        else
+        {
+            Process *process = NULL;
+            if (exe_ctx)
+                process = exe_ctx->GetProcessPtr();
+            if (process)
+            {
+                Error error;
+                return process->ReadMemory(addr, dst, byte_size, error) == byte_size;
+            }
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTType::WriteToMemory
+(
+    lldb_private::ExecutionContext *exe_ctx,
+    lldb::addr_t addr,
+    AddressType address_type,
+    StreamString &new_value
+)
+{
+    return WriteToMemory (m_ast,
+                          m_type,
+                          exe_ctx,
+                          addr,
+                          address_type,
+                          new_value);
+}
+
+bool
+ClangASTType::WriteToMemory
+(
+    clang::ASTContext *ast_context,
+    clang_type_t clang_type,
+    lldb_private::ExecutionContext *exe_ctx,
+    lldb::addr_t addr,
+    AddressType address_type,
+    StreamString &new_value
+)
+{
+    if (address_type == eAddressTypeFile)
+    {
+        // Can't convert a file address to anything valid without more
+        // context (which Module it came from)
+        return false;
+    }
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+    const uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
+
+    if (byte_size > 0)
+    {
+        if (address_type == eAddressTypeHost)
+        {
+            // The address is an address in this process, so just copy it
+            memcpy ((void *)addr, new_value.GetData(), byte_size);
+            return true;
+        }
+        else
+        {
+            Process *process = NULL;
+            if (exe_ctx)
+                process = exe_ctx->GetProcessPtr();
+            if (process)
+            {
+                Error error;
+                return process->WriteMemory(addr, new_value.GetData(), byte_size, error) == byte_size;
+            }
+        }
+    }
+    return false;
+}
+
+
+lldb::clang_type_t
+ClangASTType::RemoveFastQualifiers (lldb::clang_type_t clang_type)
+{
+    clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
+    qual_type.getQualifiers().removeFastQualifiers();
+    return qual_type.getAsOpaquePtr();
+}
+
+
+bool
+lldb_private::operator == (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs)
+{
+    return lhs.GetASTContext() == rhs.GetASTContext() && lhs.GetOpaqueQualType() == rhs.GetOpaqueQualType();
+}
+
+
+bool
+lldb_private::operator != (const lldb_private::ClangASTType &lhs, const lldb_private::ClangASTType &rhs)
+{
+    return lhs.GetASTContext() != rhs.GetASTContext() || lhs.GetOpaqueQualType() != rhs.GetOpaqueQualType();
+}

Modified: lldb/branches/windows/source/Symbol/ClangExternalASTSourceCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Symbol/ClangExternalASTSourceCommon.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Symbol/ClangExternalASTSourceCommon.cpp (original)
+++ lldb/branches/windows/source/Symbol/ClangExternalASTSourceCommon.cpp Thu Nov  1 02:04:04 2012
@@ -27,14 +27,19 @@
     g_TotalSizeOfMetadata -= m_metadata.size();
 }
 
-uint64_t ClangExternalASTSourceCommon::GetMetadata (uintptr_t object)
+ClangASTMetadata *
+ClangExternalASTSourceCommon::GetMetadata (uintptr_t object)
 {
     assert (m_magic == ClangExternalASTSourceCommon_MAGIC);
     
-    return m_metadata[object];
+    if (HasMetadata (object))
+        return &m_metadata[object];
+    else
+        return NULL;
 }
 
-void ClangExternalASTSourceCommon::SetMetadata (uintptr_t object, uint64_t metadata)
+void
+ClangExternalASTSourceCommon::SetMetadata (uintptr_t object, ClangASTMetadata &metadata)
 {
     assert (m_magic == ClangExternalASTSourceCommon_MAGIC);
     
@@ -44,7 +49,8 @@
     g_TotalSizeOfMetadata += (new_size - orig_size);
 }
 
-bool ClangExternalASTSourceCommon::HasMetadata (uintptr_t object)
+bool
+ClangExternalASTSourceCommon::HasMetadata (uintptr_t object)
 {
     assert (m_magic == ClangExternalASTSourceCommon_MAGIC);
 

Modified: lldb/branches/windows/source/Symbol/DWARFCallFrameInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Symbol/DWARFCallFrameInfo.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Symbol/DWARFCallFrameInfo.cpp (original)
+++ lldb/branches/windows/source/Symbol/DWARFCallFrameInfo.cpp Thu Nov  1 02:04:04 2012
@@ -371,11 +371,18 @@
     {
         unwind_plan.SetSourceName ("eh_frame CFI");
         cie_offset = current_entry + 4 - cie_offset;
+        unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
     }
     else
     {
         unwind_plan.SetSourceName ("DWARF CFI");
+        // In theory the debug_frame info should be valid at all call sites
+        // ("asynchronous unwind info" as it is sometimes called) but in practice
+        // gcc et al all emit call frame info for the prologue and call sites, but
+        // not for the epilogue or all the other locations during the function reliably.
+        unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
     }
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolYes);
 
     const CIE *cie = GetCIE (cie_offset);
     assert (cie != NULL);

Modified: lldb/branches/windows/source/Symbol/FuncUnwinders.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Symbol/FuncUnwinders.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Symbol/FuncUnwinders.cpp (original)
+++ lldb/branches/windows/source/Symbol/FuncUnwinders.cpp Thu Nov  1 02:04:04 2012
@@ -236,3 +236,12 @@
     return m_range.GetBaseAddress();
 }
 
+void
+FuncUnwinders::InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& thread)
+{
+    UnwindPlanSP arch_default = GetUnwindPlanArchitectureDefault (thread);
+    if (arch_default && m_tried_unwind_at_call_site)
+    {
+        m_unwind_plan_call_site_sp = arch_default;
+    }
+}

Modified: lldb/branches/windows/source/Symbol/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Symbol/Type.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Symbol/Type.cpp (original)
+++ lldb/branches/windows/source/Symbol/Type.cpp Thu Nov  1 02:04:04 2012
@@ -28,6 +28,8 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 
+#include "llvm/ADT/StringRef.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -728,14 +730,43 @@
 
 
 bool
-Type::GetTypeScopeAndBasename (const char* name_cstr,
+Type::GetTypeScopeAndBasename (const char* &name_cstr,
                                std::string &scope,
-                               std::string &basename)
+                               std::string &basename,
+                               TypeClass &type_class)
 {
     // Protect against null c string.
     
+    type_class = eTypeClassAny;
+
     if (name_cstr && name_cstr[0])
     {
+        llvm::StringRef name_strref(name_cstr);
+        if (name_strref.startswith("struct "))
+        {
+            name_cstr += 7;
+            type_class = eTypeClassStruct;
+        }
+        else if (name_strref.startswith("class "))
+        {
+            name_cstr += 6;
+            type_class = eTypeClassClass;
+        }
+        else if (name_strref.startswith("union "))
+        {
+            name_cstr += 6;
+            type_class = eTypeClassUnion;
+        }
+        else if (name_strref.startswith("enum "))
+        {
+            name_cstr += 5;
+            type_class = eTypeClassEnumeration;
+        }
+        else if (name_strref.startswith("typedef "))
+        {
+            name_cstr += 8;
+            type_class = eTypeClassTypedef;
+        }
         const char *basename_cstr = name_cstr;
         const char* namespace_separator = ::strstr (basename_cstr, "::");
         if (namespace_separator)
@@ -807,15 +838,15 @@
 }
 
 void
-TypeAndOrName::SetName (ConstString &type_name_const_str)
+TypeAndOrName::SetName (const ConstString &type_name)
 {
-    m_type_name = type_name_const_str;
+    m_type_name = type_name;
 }
 
 void
-TypeAndOrName::SetName (const char *type_name_str)
+TypeAndOrName::SetName (const char *type_name_cstr)
 {
-    m_type_name.SetCString (type_name_str);
+    m_type_name.SetCString (type_name_cstr);
 }
 
 void

Modified: lldb/branches/windows/source/Symbol/TypeList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Symbol/TypeList.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Symbol/TypeList.cpp (original)
+++ lldb/branches/windows/source/Symbol/TypeList.cpp Thu Nov  1 02:04:04 2012
@@ -207,17 +207,19 @@
 {
     std::string type_scope;
     std::string type_basename;
-    if (!Type::GetTypeScopeAndBasename (qualified_typename, type_scope, type_basename))
+    TypeClass type_class = eTypeClassAny;
+    if (!Type::GetTypeScopeAndBasename (qualified_typename, type_scope, type_basename, type_class))
     {
         type_basename = qualified_typename;
         type_scope.clear();
     }
-    return RemoveMismatchedTypes (type_scope, type_basename, exact_match);
+    return RemoveMismatchedTypes (type_scope, type_basename, type_class, exact_match);
 }
 
 void
 TypeList::RemoveMismatchedTypes (const std::string &type_scope,
                                  const std::string &type_basename,
+                                 TypeClass type_class,
                                  bool exact_match)
 {
     // Our "collection" type currently is a std::map which doesn't
@@ -232,6 +234,15 @@
     {
         Type* the_type = pos->second.get();
         bool keep_match = false;
+        TypeClass match_type_class = eTypeClassAny;
+
+        if (type_class != eTypeClassAny)
+        {
+            match_type_class = ClangASTType::GetTypeClass (the_type->GetClangAST(),
+                                                           the_type->GetClangForwardType());
+            if ((match_type_class & type_class) == 0)
+                continue;
+        }
 
         ConstString match_type_name_const_str (the_type->GetQualifiedName());
         if (match_type_name_const_str)
@@ -241,7 +252,8 @@
             std::string match_type_basename;
             if (Type::GetTypeScopeAndBasename (match_type_name,
                                                match_type_scope,
-                                               match_type_basename))
+                                               match_type_basename,
+                                               match_type_class))
             {
                 if (match_type_basename == type_basename)
                 {
@@ -299,6 +311,31 @@
     m_types.swap(matching_types);
 }
 
+void
+TypeList::RemoveMismatchedTypes (TypeClass type_class)
+{
+    if (type_class == eTypeClassAny)
+        return;
+
+    // Our "collection" type currently is a std::map which doesn't
+    // have any good way to iterate and remove items from the map
+    // so we currently just make a new list and add all of the matching
+    // types to it, and then swap it into m_types at the end
+    collection matching_types;
+    
+    iterator pos, end = m_types.end();
+    
+    for (pos = m_types.begin(); pos != end; ++pos)
+    {
+        Type* the_type = pos->second.get();
+        TypeClass match_type_class = ClangASTType::GetTypeClass (the_type->GetClangAST(),
+                                                                 the_type->GetClangForwardType());
+        if (match_type_class & type_class)
+            matching_types.insert (*pos);
+    }
+    m_types.swap(matching_types);
+}
+
 //void *
 //TypeList::CreateClangPointerType (Type *type)
 //{

Modified: lldb/branches/windows/source/Symbol/UnwindPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Symbol/UnwindPlan.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Symbol/UnwindPlan.cpp (original)
+++ lldb/branches/windows/source/Symbol/UnwindPlan.cpp Thu Nov  1 02:04:04 2012
@@ -153,7 +153,7 @@
 UnwindPlan::Row::Clear ()
 {
     m_offset = 0;
-    m_cfa_reg_num = 0;
+    m_cfa_reg_num = LLDB_INVALID_REGNUM;
     m_cfa_offset = 0;
     m_register_locations.clear();
 }
@@ -189,7 +189,7 @@
 
 UnwindPlan::Row::Row() :
     m_offset(0),
-    m_cfa_reg_num(0),
+    m_cfa_reg_num(LLDB_INVALID_REGNUM),
     m_cfa_offset(0),
     m_register_locations()
 {

Modified: lldb/branches/windows/source/Target/ABI.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Target/ABI.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Target/ABI.cpp (original)
+++ lldb/branches/windows/source/Target/ABI.cpp Thu Nov  1 02:04:04 2012
@@ -156,6 +156,7 @@
             // we don't do anything with these for now
             break;
         case Value::eValueTypeScalar:
+        case Value::eValueTypeVector:
             clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried;
             clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
             clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;

Modified: lldb/branches/windows/source/Target/LanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Target/LanguageRuntime.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Target/LanguageRuntime.cpp (original)
+++ lldb/branches/windows/source/Target/LanguageRuntime.cpp Thu Nov  1 02:04:04 2012
@@ -162,39 +162,77 @@
         return m_actual_resolver_sp->GetDepth();
 }
 
-static const char *language_names[] =
+/*
+typedef enum LanguageType
 {
-    "unknown",
-    "c89",
-    "c",
-    "ada83",
-    "c++",
-    "cobol74",
-    "cobol85",
-    "fortran77",
-    "fortran90",
-    "pascal83",
-    "modula2",
-    "java",
-    "c99",
-    "ada95",
-    "fortran95",
-    "pli",
-    "objective-c",
-    "objective-c++",
-    "upc",
-    "d",
-    "python"
+    eLanguageTypeUnknown         = 0x0000,   ///< Unknown or invalid language value.
+    eLanguageTypeC89             = 0x0001,   ///< ISO C:1989.
+    eLanguageTypeC               = 0x0002,   ///< Non-standardized C, such as K&R.
+    eLanguageTypeAda83           = 0x0003,   ///< ISO Ada:1983.
+    eLanguageTypeC_plus_plus     = 0x0004,   ///< ISO C++:1998.
+    eLanguageTypeCobol74         = 0x0005,   ///< ISO Cobol:1974.
+    eLanguageTypeCobol85         = 0x0006,   ///< ISO Cobol:1985.
+    eLanguageTypeFortran77       = 0x0007,   ///< ISO Fortran 77.
+    eLanguageTypeFortran90       = 0x0008,   ///< ISO Fortran 90.
+    eLanguageTypePascal83        = 0x0009,   ///< ISO Pascal:1983.
+    eLanguageTypeModula2         = 0x000a,   ///< ISO Modula-2:1996.
+    eLanguageTypeJava            = 0x000b,   ///< Java.
+    eLanguageTypeC99             = 0x000c,   ///< ISO C:1999.
+    eLanguageTypeAda95           = 0x000d,   ///< ISO Ada:1995.
+    eLanguageTypeFortran95       = 0x000e,   ///< ISO Fortran 95.
+    eLanguageTypePLI             = 0x000f,   ///< ANSI PL/I:1976.
+    eLanguageTypeObjC            = 0x0010,   ///< Objective-C.
+    eLanguageTypeObjC_plus_plus  = 0x0011,   ///< Objective-C++.
+    eLanguageTypeUPC             = 0x0012,   ///< Unified Parallel C.
+    eLanguageTypeD               = 0x0013,   ///< D.
+    eLanguageTypePython          = 0x0014    ///< Python.
+} LanguageType;
+ */
+
+struct language_name_pair {
+    const char *name;
+    LanguageType type;
 };
-static uint32_t num_languages = sizeof(language_names) / sizeof (char *);
+
+struct language_name_pair language_names[] =
+{
+    // To allow GetNameForLanguageType to be a simple array lookup, the first
+    // part of this array must follow enum LanguageType exactly.
+    {   "unknown",          eLanguageTypeUnknown        },
+    {   "c89",              eLanguageTypeC89            },
+    {   "c",                eLanguageTypeC              },
+    {   "ada83",            eLanguageTypeAda83          },
+    {   "c++",              eLanguageTypeC_plus_plus    },
+    {   "cobol74",          eLanguageTypeCobol74        },
+    {   "cobol85",          eLanguageTypeCobol85        },
+    {   "fortran77",        eLanguageTypeFortran77      },
+    {   "fortran90",        eLanguageTypeFortran90      },
+    {   "pascal83",         eLanguageTypePascal83       },
+    {   "modula2",          eLanguageTypeModula2        },
+    {   "java",             eLanguageTypeJava           },
+    {   "c99",              eLanguageTypeC99            },
+    {   "ada95",            eLanguageTypeAda95          },
+    {   "fortran95",        eLanguageTypeFortran95      },
+    {   "pli",              eLanguageTypePLI            },
+    {   "objective-c",      eLanguageTypeObjC           },
+    {   "objective-c++",    eLanguageTypeObjC_plus_plus },
+    {   "upc",              eLanguageTypeUPC            },
+    {   "d",                eLanguageTypeD              },
+    {   "python",           eLanguageTypePython         },
+    // Now synonyms, in arbitrary order
+    {   "objc",             eLanguageTypeObjC           },
+    {   "objc++",           eLanguageTypeObjC_plus_plus }
+};
+
+static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair);
 
 LanguageType
 LanguageRuntime::GetLanguageTypeFromString (const char *string)
 {
     for (uint32_t i = 0; i < num_languages; i++)
     {
-        if (strcmp (language_names[i], string) == 0)
-            return (LanguageType) i;
+        if (strcasecmp (language_names[i].name, string) == 0)
+            return (LanguageType) language_names[i].type;
     }
     return eLanguageTypeUnknown;
 }
@@ -203,8 +241,8 @@
 LanguageRuntime::GetNameForLanguageType (LanguageType language)
 {
     if (language < num_languages)
-        return language_names[language];
+        return language_names[language].name;
     else
-        return language_names[eLanguageTypeUnknown];
+        return language_names[eLanguageTypeUnknown].name;
 }
         

Modified: lldb/branches/windows/source/Target/ObjCLanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Target/ObjCLanguageRuntime.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Target/ObjCLanguageRuntime.cpp (original)
+++ lldb/branches/windows/source/Target/ObjCLanguageRuntime.cpp Thu Nov  1 02:04:04 2012
@@ -32,7 +32,7 @@
     LanguageRuntime (process),
     m_has_new_literals_and_indexing (eLazyBoolCalculate),
     m_isa_to_descriptor_cache(),
-    m_isa_to_descriptor_cache_is_up_to_date (false)
+    m_isa_to_descriptor_cache_stop_id (UINT32_MAX)
 {
 
 }
@@ -58,47 +58,6 @@
     return LLDB_INVALID_ADDRESS;
 }
 
-void
-ObjCLanguageRuntime::AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp)
-{
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    if (log)
-    {
-        log->Printf ("Caching: class 0x%llx name: %s.", class_addr, name);
-    }
-    
-    TypeAndOrName class_type_or_name;
-    
-    if (type_sp)
-        class_type_or_name.SetTypeSP (type_sp);
-    else if (name && *name != '\0')
-        class_type_or_name.SetName (name);
-    else 
-        return;
-    m_class_name_cache.insert (std::pair<lldb::addr_t,TypeAndOrName> (class_addr, class_type_or_name));
-}
-
-void
-ObjCLanguageRuntime::AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_type_or_name)
-{
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    if (log)
-    {
-        log->Printf ("Caching: class 0x%llx name: %s.", class_addr, class_type_or_name.GetName().AsCString());
-    }
-    
-    m_class_name_cache.insert (std::pair<lldb::addr_t,TypeAndOrName> (class_addr, class_type_or_name));
-}
-
-TypeAndOrName
-ObjCLanguageRuntime::LookupInClassNameCache (lldb::addr_t class_addr)
-{
-    ClassNameMap::iterator pos, end = m_class_name_cache.end();
-    pos = m_class_name_cache.find (class_addr);
-    if (pos != end)
-        return (*pos).second;
-    return TypeAndOrName ();
-}
 
 lldb::TypeSP
 ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name)
@@ -107,72 +66,77 @@
     
     if (complete_class_iter != m_complete_class_cache.end())
     {
-        TypeSP ret(complete_class_iter->second);
+        // Check the weak pointer to make sure the type hasn't been unloaded
+        TypeSP complete_type_sp (complete_class_iter->second.lock());
         
-        if (!ret)
-            m_complete_class_cache.erase(name);
+        if (complete_type_sp)
+            return complete_type_sp;
         else
-            return TypeSP(complete_class_iter->second);
+            m_complete_class_cache.erase(name);
     }
     
     ModuleList &modules = m_process->GetTarget().GetImages();
-    
+
     SymbolContextList sc_list;
+    const size_t matching_symbols = modules.FindSymbolsWithNameAndType (name,
+                                                                        eSymbolTypeObjCClass,
+                                                                        sc_list);
     
-    modules.FindSymbolsWithNameAndType(name, eSymbolTypeObjCClass, sc_list);
-    
-    if (sc_list.GetSize() == 0)
-        return TypeSP();
-    
-    SymbolContext sc;
-    
-    sc_list.GetContextAtIndex(0, sc);
-    
-    ModuleSP module_sp(sc.module_sp);
-    
-    if (!module_sp)
-        return TypeSP();
-    
-    const SymbolContext null_sc;
-    const bool exact_match = true;
-    const uint32_t max_matches = UINT32_MAX;
-    TypeList types;
-    
-    module_sp->FindTypes (null_sc,
-                          name,
-                          exact_match,
-                          max_matches,
-                          types);
-    
-    if (types.GetSize() == 1)
+    if (matching_symbols)
     {
-        TypeSP candidate_type = types.GetTypeAtIndex(0);
+        SymbolContext sc;
         
-        if (ClangASTContext::IsObjCClassType(candidate_type->GetClangForwardType()))
-        {
-            m_complete_class_cache[name] = TypeWP(candidate_type);
-            return candidate_type;
-        }
-        else
-        {
+        sc_list.GetContextAtIndex(0, sc);
+        
+        ModuleSP module_sp(sc.module_sp);
+        
+        if (!module_sp)
             return TypeSP();
-        }
-    }
-    
-    for (uint32_t ti = 0, te = types.GetSize();
-         ti < te;
-         ++ti)
-    {
-        TypeSP candidate_type = types.GetTypeAtIndex(ti);
         
-        if (candidate_type->IsCompleteObjCClass() &&
-            ClangASTContext::IsObjCClassType(candidate_type->GetClangForwardType()))
+        const SymbolContext null_sc;
+        const bool exact_match = true;
+        const uint32_t max_matches = UINT32_MAX;
+        TypeList types;
+        
+        const uint32_t num_types = module_sp->FindTypes (null_sc,
+                                                         name,
+                                                         exact_match,
+                                                         max_matches,
+                                                         types);
+        
+        if (num_types)
         {
-            m_complete_class_cache[name] = TypeWP(candidate_type);
-            return candidate_type;                                       
+            TypeSP incomplete_type_sp;
+            
+            uint32_t i;
+            for (i = 0; i < num_types; ++i)
+            {
+                TypeSP type_sp (types.GetTypeAtIndex(i));
+                
+                if (ClangASTContext::IsObjCClassType(type_sp->GetClangForwardType()))
+                {
+                    if (type_sp->IsCompleteObjCClass())
+                    {
+                        m_complete_class_cache[name] = type_sp;
+                        return type_sp;
+                    }
+                    else if (!incomplete_type_sp)
+                        incomplete_type_sp = type_sp;
+                }
+            }
+           
+            // We didn't find any "real" definitions, so just use any??? Why was
+            // this being done? Prior to this, if there was 1 match only, then it
+            // would always use any objc definition, else we would only accept a
+            // definition if it was the real thing???? Doesn't make sense.
+
+            if (incomplete_type_sp)
+            {
+                m_complete_class_cache[name] = incomplete_type_sp;
+                return incomplete_type_sp;
+            }
         }
     }
-    
     return TypeSP();
 }
 

Added: lldb/branches/windows/source/Target/ObjCLanguageRuntime.cpp.orig
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Target/ObjCLanguageRuntime.cpp.orig?rev=167218&view=auto
==============================================================================
--- lldb/branches/windows/source/Target/ObjCLanguageRuntime.cpp.orig (added)
+++ lldb/branches/windows/source/Target/ObjCLanguageRuntime.cpp.orig Thu Nov  1 02:04:04 2012
@@ -0,0 +1,406 @@
+//===-- ObjCLanguageRuntime.cpp ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/Type.h"
+
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/TypeList.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+ObjCLanguageRuntime::~ObjCLanguageRuntime()
+{
+}
+
+ObjCLanguageRuntime::ObjCLanguageRuntime (Process *process) :
+    LanguageRuntime (process),
+    m_has_new_literals_and_indexing (eLazyBoolCalculate),
+    m_isa_to_descriptor_cache(),
+    m_isa_to_descriptor_cache_is_up_to_date (false)
+{
+
+}
+
+void
+ObjCLanguageRuntime::AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t selector, lldb::addr_t impl_addr)
+{
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    if (log)
+    {
+        log->Printf ("Caching: class 0x%llx selector 0x%llx implementation 0x%llx.", class_addr, selector, impl_addr);
+    }
+    m_impl_cache.insert (std::pair<ClassAndSel,lldb::addr_t> (ClassAndSel(class_addr, selector), impl_addr));
+}
+
+lldb::addr_t
+ObjCLanguageRuntime::LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t selector)
+{
+    MsgImplMap::iterator pos, end = m_impl_cache.end();
+    pos = m_impl_cache.find (ClassAndSel(class_addr, selector));
+    if (pos != end)
+        return (*pos).second;
+    return LLDB_INVALID_ADDRESS;
+}
+
+void
+ObjCLanguageRuntime::AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp)
+{
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    if (log)
+    {
+        log->Printf ("Caching: class 0x%llx name: %s.", class_addr, name);
+    }
+    
+    TypeAndOrName class_type_or_name;
+    
+    if (type_sp)
+        class_type_or_name.SetTypeSP (type_sp);
+    else if (name && *name != '\0')
+        class_type_or_name.SetName (name);
+    else 
+        return;
+    m_class_name_cache.insert (std::pair<lldb::addr_t,TypeAndOrName> (class_addr, class_type_or_name));
+}
+
+void
+ObjCLanguageRuntime::AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_type_or_name)
+{
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    if (log)
+    {
+        log->Printf ("Caching: class 0x%llx name: %s.", class_addr, class_type_or_name.GetName().AsCString());
+    }
+    
+    m_class_name_cache.insert (std::pair<lldb::addr_t,TypeAndOrName> (class_addr, class_type_or_name));
+}
+
+TypeAndOrName
+ObjCLanguageRuntime::LookupInClassNameCache (lldb::addr_t class_addr)
+{
+    ClassNameMap::iterator pos, end = m_class_name_cache.end();
+    pos = m_class_name_cache.find (class_addr);
+    if (pos != end)
+        return (*pos).second;
+    return TypeAndOrName ();
+}
+
+lldb::TypeSP
+ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name)
+{
+    CompleteClassMap::iterator complete_class_iter = m_complete_class_cache.find(name);
+    
+    if (complete_class_iter != m_complete_class_cache.end())
+    {
+        TypeSP ret(complete_class_iter->second);
+        
+        if (!ret)
+            m_complete_class_cache.erase(name);
+        else
+            return TypeSP(complete_class_iter->second);
+    }
+    
+    ModuleList &modules = m_process->GetTarget().GetImages();
+    
+    SymbolContextList sc_list;
+    
+    modules.FindSymbolsWithNameAndType(name, eSymbolTypeObjCClass, sc_list);
+    
+    if (sc_list.GetSize() == 0)
+        return TypeSP();
+    
+    SymbolContext sc;
+    
+    sc_list.GetContextAtIndex(0, sc);
+    
+    ModuleSP module_sp(sc.module_sp);
+    
+    if (!module_sp)
+        return TypeSP();
+    
+    const SymbolContext null_sc;
+    const bool exact_match = true;
+    const uint32_t max_matches = UINT32_MAX;
+    TypeList types;
+    
+    module_sp->FindTypes (null_sc,
+                          name,
+                          exact_match,
+                          max_matches,
+                          types);
+    
+    if (types.GetSize() == 1)
+    {
+        TypeSP candidate_type = types.GetTypeAtIndex(0);
+        
+        if (ClangASTContext::IsObjCClassType(candidate_type->GetClangForwardType()))
+        {
+            m_complete_class_cache[name] = TypeWP(candidate_type);
+            return candidate_type;
+        }
+        else
+        {
+            return TypeSP();
+        }
+    }
+    
+    for (uint32_t ti = 0, te = types.GetSize();
+         ti < te;
+         ++ti)
+    {
+        TypeSP candidate_type = types.GetTypeAtIndex(ti);
+        
+        if (candidate_type->IsCompleteObjCClass() &&
+            ClangASTContext::IsObjCClassType(candidate_type->GetClangForwardType()))
+        {
+            m_complete_class_cache[name] = TypeWP(candidate_type);
+            return candidate_type;                                       
+        }
+    }
+    
+    return TypeSP();
+}
+
+size_t
+ObjCLanguageRuntime::GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name)
+{
+    return LLDB_INVALID_IVAR_OFFSET;
+}
+
+
+uint32_t
+ObjCLanguageRuntime::ParseMethodName (const char *name, 
+                                      ConstString *class_name,              // Class name (with category if any)
+                                      ConstString *selector_name,           // selector on its own
+                                      ConstString *name_sans_category,      // Full function prototype with no category
+                                      ConstString *class_name_sans_category)// Class name with no category (or empty if no category as answer will be in "class_name"
+{
+    if (class_name)
+        class_name->Clear();
+    if (selector_name)
+        selector_name->Clear();
+    if (name_sans_category)
+        name_sans_category->Clear();
+    if (class_name_sans_category)
+        class_name_sans_category->Clear();
+    
+    uint32_t result = 0;
+
+    if (IsPossibleObjCMethodName (name))
+    {
+        int name_len = strlen (name);
+        // Objective C methods must have at least:
+        //      "-[" or "+[" prefix
+        //      One character for a class name
+        //      One character for the space between the class name
+        //      One character for the method name
+        //      "]" suffix
+        if (name_len >= 6 && name[name_len - 1] == ']')
+        {
+            const char *selector_name_ptr = strchr (name, ' ');
+            if (selector_name_ptr)
+            {
+                if (class_name)
+                {
+                    class_name->SetCStringWithLength (name + 2, selector_name_ptr - name - 2);
+                    ++result;
+                }    
+                
+                // Skip the space
+                ++selector_name_ptr;
+                // Extract the objective C basename and add it to the
+                // accelerator tables
+                size_t selector_name_len = name_len - (selector_name_ptr - name) - 1;
+                if (selector_name)
+                {
+                    selector_name->SetCStringWithLength (selector_name_ptr, selector_name_len);                                
+                    ++result;
+                }
+                
+                // Also see if this is a "category" on our class.  If so strip off the category name,
+                // and add the class name without it to the basename table. 
+                
+                if (name_sans_category || class_name_sans_category)
+                {
+                    const char *open_paren = strchr (name, '(');
+                    if (open_paren)
+                    {
+                        if (class_name_sans_category)
+                        {
+                            class_name_sans_category->SetCStringWithLength (name + 2, open_paren - name - 2);
+                            ++result;
+                        }
+                        
+                        if (name_sans_category)
+                        {
+                            const char *close_paren = strchr (open_paren, ')');
+                            if (open_paren < close_paren)
+                            {
+                                std::string buffer (name, open_paren - name);
+                                buffer.append (close_paren + 1);
+                                name_sans_category->SetCString (buffer.c_str());
+                                ++result;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return result;
+}
+
+bool
+ObjCLanguageRuntime::ClassDescriptor::IsPointerValid (lldb::addr_t value,
+                                                      uint32_t ptr_size,
+                                                      bool allow_NULLs,
+                                                      bool allow_tagged,
+                                                      bool check_version_specific) const
+{
+    if (!value)
+        return allow_NULLs;
+    if ( (value % 2) == 1  && allow_tagged)
+        return true;
+    if ((value % ptr_size) == 0)
+        return (check_version_specific ? CheckPointer(value,ptr_size) : true);
+    else
+        return false;
+}
+
+ObjCLanguageRuntime::ObjCISA
+ObjCLanguageRuntime::GetISA(const ConstString &name)
+{
+    UpdateISAToDescriptorMap();
+    for (std::map<ObjCISA, ClassDescriptorSP>::iterator it = 
+        m_isa_to_descriptor_cache.begin(); it != m_isa_to_descriptor_cache.end(); ++it)
+        if (it->second && it->second->GetClassName() == name)
+            return it->first;
+    return 0;
+}
+
+ObjCLanguageRuntime::ObjCISA
+ObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa)
+{
+    ClassDescriptorSP objc_class_sp (GetClassDescriptor(isa));
+    if (objc_class_sp)
+    {
+        ClassDescriptorSP objc_super_class_sp (objc_class_sp->GetSuperclass());
+        if (objc_super_class_sp)
+            return objc_super_class_sp->GetISA();
+    }
+    return 0;
+}
+
+ConstString
+ObjCLanguageRuntime::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
+{
+    ClassDescriptorSP objc_class_sp (GetNonKVOClassDescriptor(isa));
+    if (objc_class_sp)
+        return objc_class_sp->GetClassName();
+    return ConstString();
+}
+
+ObjCLanguageRuntime::ClassDescriptorSP
+ObjCLanguageRuntime::GetClassDescriptor (const ConstString &class_name)
+{
+    UpdateISAToDescriptorMap();
+    for (const ISAToDescriptorMap::value_type &val : m_isa_to_descriptor_cache)
+        if (val.second && val.second->GetClassName() == class_name)
+            return val.second;
+    return ClassDescriptorSP();
+
+}
+
+ObjCLanguageRuntime::ClassDescriptorSP
+ObjCLanguageRuntime::GetClassDescriptor (ValueObject& valobj)
+{
+    ClassDescriptorSP objc_class_sp;
+    // if we get an invalid VO (which might still happen when playing around
+    // with pointers returned by the expression parser, don't consider this
+    // a valid ObjC object)
+    if (valobj.GetValue().GetContextType() != Value::eContextTypeInvalid)
+    {
+        addr_t isa_pointer = valobj.GetPointerValue();
+        if (isa_pointer != LLDB_INVALID_ADDRESS)
+        {
+            ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
+            
+            Process *process = exe_ctx.GetProcessPtr();
+            if (process)
+            {
+                Error error;
+                ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
+                if (isa != LLDB_INVALID_ADDRESS)
+                    objc_class_sp = GetClassDescriptor (isa);
+            }
+        }
+    }
+    return objc_class_sp;
+}
+
+ObjCLanguageRuntime::ClassDescriptorSP
+ObjCLanguageRuntime::GetNonKVOClassDescriptor (ValueObject& valobj)
+{
+    ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (GetClassDescriptor (valobj));
+    if (objc_class_sp)
+    {
+        if (!objc_class_sp->IsKVO())
+            return objc_class_sp;
+        
+        ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass());
+        if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid())
+            return non_kvo_objc_class_sp;
+    }
+    return ClassDescriptorSP();
+}
+
+
+ObjCLanguageRuntime::ClassDescriptorSP
+ObjCLanguageRuntime::GetClassDescriptor (ObjCISA isa)
+{
+    if (isa)
+    {
+        UpdateISAToDescriptorMap();
+        ObjCLanguageRuntime::ISAToDescriptorIterator pos = m_isa_to_descriptor_cache.find(isa);    
+        if (pos != m_isa_to_descriptor_cache.end())
+            return pos->second;
+    }
+    return ClassDescriptorSP();
+}
+
+ObjCLanguageRuntime::ClassDescriptorSP
+ObjCLanguageRuntime::GetNonKVOClassDescriptor (ObjCISA isa)
+{
+    if (isa)
+    {
+        ClassDescriptorSP objc_class_sp = GetClassDescriptor (isa);
+        if (objc_class_sp && objc_class_sp->IsValid())
+        {
+            if (!objc_class_sp->IsKVO())
+                return objc_class_sp;
+
+            ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass());
+            if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid())
+                return non_kvo_objc_class_sp;
+        }
+    }
+    return ClassDescriptorSP();
+}
+
+
+

Modified: lldb/branches/windows/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Target/Process.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Target/Process.cpp (original)
+++ lldb/branches/windows/source/Target/Process.cpp Thu Nov  1 02:04:04 2012
@@ -775,14 +775,14 @@
 { LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', no_argument,       NULL, 0, eArgTypeNone,          "Stop at the entry point of the program when launching a process."},
 { LLDB_OPT_SET_ALL, false, "disable-aslr",  'A', no_argument,       NULL, 0, eArgTypeNone,          "Disable address space layout randomization when launching a process."},
 { LLDB_OPT_SET_ALL, false, "plugin",        'p', required_argument, NULL, 0, eArgTypePlugin,        "Name of the process plugin you want to use."},
-{ LLDB_OPT_SET_ALL, false, "working-dir",   'w', required_argument, NULL, 0, eArgTypePath,          "Set the current working directory to <path> when running the inferior."},
+{ LLDB_OPT_SET_ALL, false, "working-dir",   'w', required_argument, NULL, 0, eArgTypeDirectoryName,          "Set the current working directory to <path> when running the inferior."},
 { LLDB_OPT_SET_ALL, false, "arch",          'a', required_argument, NULL, 0, eArgTypeArchitecture,  "Set the architecture for the process to launch when ambiguous."},
 { LLDB_OPT_SET_ALL, false, "environment",   'v', required_argument, NULL, 0, eArgTypeNone,          "Specify an environment variable name/value stirng (--environement NAME=VALUE). Can be specified multiple times for subsequent environment entries."},
-{ LLDB_OPT_SET_ALL, false, "shell",         'c', optional_argument, NULL, 0, eArgTypePath,          "Run the process in a shell (not supported on all platforms)."},
+{ LLDB_OPT_SET_ALL, false, "shell",         'c', optional_argument, NULL, 0, eArgTypeFilename,          "Run the process in a shell (not supported on all platforms)."},
 
-{ LLDB_OPT_SET_1  , false, "stdin",         'i', required_argument, NULL, 0, eArgTypePath,    "Redirect stdin for the process to <path>."},
-{ LLDB_OPT_SET_1  , false, "stdout",        'o', required_argument, NULL, 0, eArgTypePath,    "Redirect stdout for the process to <path>."},
-{ LLDB_OPT_SET_1  , false, "stderr",        'e', required_argument, NULL, 0, eArgTypePath,    "Redirect stderr for the process to <path>."},
+{ LLDB_OPT_SET_1  , false, "stdin",         'i', required_argument, NULL, 0, eArgTypeFilename,    "Redirect stdin for the process to <filename>."},
+{ LLDB_OPT_SET_1  , false, "stdout",        'o', required_argument, NULL, 0, eArgTypeFilename,    "Redirect stdout for the process to <filename>."},
+{ LLDB_OPT_SET_1  , false, "stderr",        'e', required_argument, NULL, 0, eArgTypeFilename,    "Redirect stderr for the process to <filename>."},
 
 { LLDB_OPT_SET_2  , false, "tty",           't', no_argument,       NULL, 0, eArgTypeNone,    "Start the process in a terminal (not supported on all platforms)."},
 
@@ -977,6 +977,10 @@
     SetEventName (eBroadcastBitSTDOUT, "stdout-available");
     SetEventName (eBroadcastBitSTDERR, "stderr-available");
     
+    m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlStop  , "control-stop"  );
+    m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlPause , "control-pause" );
+    m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlResume, "control-resume");
+
     listener.StartListeningForEvents (this,
                                       eBroadcastBitStateChanged |
                                       eBroadcastBitInterrupt |
@@ -1059,6 +1063,19 @@
     m_allocated_memory_cache.Clear();
     m_language_runtimes.clear();
     m_next_event_action_ap.reset();
+//#ifdef LLDB_CONFIGURATION_DEBUG
+//    StreamFile s(stdout, false);
+//    EventSP event_sp;
+//    while (m_private_state_listener.GetNextEvent(event_sp))
+//    {
+//        event_sp->Dump (&s);
+//        s.EOL();
+//    }
+//#endif
+    // We have to be very careful here as the m_private_state_listener might
+    // contain events that have ProcessSP values in them which can keep this
+    // process around forever. These events need to be cleared out.
+    m_private_state_listener.Clear();
     m_finalize_called = true;
 }
 
@@ -1554,7 +1571,10 @@
                 log->Printf("Process::SetPrivateState (%s) stop_id = %u", StateAsCString(new_state), m_mod_id.GetStopID());
         }
         // Use our target to get a shared pointer to ourselves...
-        m_private_state_broadcaster.BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (GetTarget().GetProcessSP(), new_state));
+        if (m_finalize_called && PrivateStateThreadIsValid() == false)
+            BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (shared_from_this(), new_state));
+        else
+            m_private_state_broadcaster.BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (shared_from_this(), new_state));
     }
     else
     {
@@ -1614,7 +1634,16 @@
                 expr.Printf("dlopen (\"%s\", 2)", path);
                 const char *prefix = "extern \"C\" void* dlopen (const char *path, int mode);\n";
                 lldb::ValueObjectSP result_valobj_sp;
-                ClangUserExpression::Evaluate (exe_ctx, eExecutionPolicyAlways, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny, unwind_on_error, expr.GetData(), prefix, result_valobj_sp);
+                ClangUserExpression::Evaluate (exe_ctx,
+                                               eExecutionPolicyAlways,
+                                               lldb::eLanguageTypeUnknown,
+                                               ClangUserExpression::eResultTypeAny,
+                                               unwind_on_error,
+                                               expr.GetData(),
+                                               prefix,
+                                               result_valobj_sp,
+                                               true,
+                                               ClangUserExpression::kDefaultTimeout);
                 error = result_valobj_sp->GetError();
                 if (error.Success())
                 {
@@ -1680,7 +1709,16 @@
                         expr.Printf("dlclose ((void *)0x%llx)", image_addr);
                         const char *prefix = "extern \"C\" int dlclose(void* handle);\n";
                         lldb::ValueObjectSP result_valobj_sp;
-                        ClangUserExpression::Evaluate (exe_ctx, eExecutionPolicyAlways, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny, unwind_on_error, expr.GetData(), prefix, result_valobj_sp);
+                        ClangUserExpression::Evaluate (exe_ctx,
+                                                       eExecutionPolicyAlways,
+                                                       lldb::eLanguageTypeUnknown,
+                                                       ClangUserExpression::eResultTypeAny,
+                                                       unwind_on_error,
+                                                       expr.GetData(),
+                                                       prefix,
+                                                       result_valobj_sp,
+                                                       true,
+                                                       ClangUserExpression::kDefaultTimeout);
                         if (result_valobj_sp->GetError().Success())
                         {
                             Scalar scalar;
@@ -3958,7 +3996,7 @@
 {
     Mutex::Locker locker (m_stdio_communication_mutex);
     m_stdout_data.append (s, len);
-    BroadcastEventIfUnique (eBroadcastBitSTDOUT, new ProcessEventData (GetTarget().GetProcessSP(), GetState()));
+    BroadcastEventIfUnique (eBroadcastBitSTDOUT, new ProcessEventData (shared_from_this(), GetState()));
 }
 
 void
@@ -3966,7 +4004,7 @@
 {
     Mutex::Locker locker (m_stdio_communication_mutex);
     m_stderr_data.append (s, len);
-    BroadcastEventIfUnique (eBroadcastBitSTDERR, new ProcessEventData (GetTarget().GetProcessSP(), GetState()));
+    BroadcastEventIfUnique (eBroadcastBitSTDERR, new ProcessEventData (shared_from_this(), GetState()));
 }
 
 //------------------------------------------------------------------

Modified: lldb/branches/windows/source/Target/StopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Target/StopInfo.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Target/StopInfo.cpp (original)
+++ lldb/branches/windows/source/Target/StopInfo.cpp Thu Nov  1 02:04:04 2012
@@ -246,7 +246,9 @@
                                                                               bp_loc_sp->GetConditionText(),
                                                                               NULL,
                                                                               result_value_sp,
-                                                                              error);
+                                                                              error,
+                                                                              true,
+                                                                              ClangUserExpression::kDefaultTimeout);
                         if (result_code == eExecutionCompleted)
                         {
                             if (result_value_sp)
@@ -550,75 +552,6 @@
                 }
             }
 
-            // Record the snapshot of our watchpoint.
-            VariableSP var_sp;
-            ValueObjectSP valobj_sp;        
-            StackFrame *frame = exe_ctx.GetFramePtr();
-            if (frame)
-            {
-                bool snapshot_taken = true;
-                if (!wp_sp->IsWatchVariable())
-                {
-                    // We are not watching a variable, just read from the process memory for the watched location.
-                    assert (process);
-                    Error error;
-                    uint64_t val = process->ReadUnsignedIntegerFromMemory(wp_sp->GetLoadAddress(),
-                                                                          wp_sp->GetByteSize(),
-                                                                          0,
-                                                                          error);
-                    if (log)
-                    {
-                        if (error.Success())
-                            log->Printf("Watchpoint snapshot val taken: 0x%llx\n", val);
-                        else
-                            log->Printf("Watchpoint snapshot val taking failed.\n");
-                    }                        
-                    wp_sp->SetNewSnapshotVal(val);
-                }
-                else if (!wp_sp->GetWatchSpec().empty())
-                {
-                    // Use our frame to evaluate the variable expression.
-                    Error error;
-                    uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
-                                                 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
-                    valobj_sp = frame->GetValueForVariableExpressionPath (wp_sp->GetWatchSpec().c_str(), 
-                                                                          eNoDynamicValues, 
-                                                                          expr_path_options,
-                                                                          var_sp,
-                                                                          error);
-                    if (valobj_sp)
-                    {
-                        // We're in business.
-                        StreamString ss;
-                        ValueObject::DumpValueObject(ss, valobj_sp.get());
-                        wp_sp->SetNewSnapshot(ss.GetString());
-                    }
-                    else
-                    {
-                        // The variable expression has become out of scope?
-                        // Let us forget about this stop info.
-                        if (log)
-                            log->Printf("Snapshot attempt failed.  Variable expression has become out of scope?");
-                        snapshot_taken = false;
-                        m_should_stop = false;
-                        wp_sp->IncrementFalseAlarmsAndReviseHitCount();
-                    }
-
-                    if (log && snapshot_taken)
-                        log->Printf("Watchpoint snapshot taken: '%s'\n", wp_sp->GetNewSnapshot().c_str());
-                }
-
-                // Now dump the snapshots we have taken.
-                if (snapshot_taken)
-                {
-                    Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
-                    StreamSP output_sp = debugger.GetAsyncOutputStream ();
-                    wp_sp->DumpSnapshots(output_sp.get());
-                    output_sp->EOL();
-                    output_sp->Flush();
-                }
-            }
-
             if (m_should_stop && wp_sp->GetConditionText() != NULL)
             {
                 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
@@ -636,7 +569,8 @@
                                                                       NULL,
                                                                       result_value_sp,
                                                                       error,
-                                                                      500000);
+                                                                      true,
+                                                                      ClangUserExpression::kDefaultTimeout);
                 if (result_code == eExecutionCompleted)
                 {
                     if (result_value_sp)
@@ -703,6 +637,18 @@
                     m_should_stop = false;
                 }
             }
+            // Finally, if we are going to stop, print out the new & old values:
+            if (m_should_stop)
+            {
+                wp_sp->CaptureWatchedValue(exe_ctx);
+                
+                Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
+                StreamSP output_sp = debugger.GetAsyncOutputStream ();
+                wp_sp->DumpSnapshots(output_sp.get());
+                output_sp->EOL();
+                output_sp->Flush();
+            }
+            
         }
         else
         {
@@ -713,6 +659,7 @@
         }
         if (log)
             log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
+        
     }
         
     virtual const char *

Modified: lldb/branches/windows/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Target/Target.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Target/Target.cpp (original)
+++ lldb/branches/windows/source/Target/Target.cpp Thu Nov  1 02:04:04 2012
@@ -523,12 +523,12 @@
 // See also Watchpoint::SetWatchpointType(uint32_t type) and
 // the OptionGroupWatchpoint::WatchType enum type.
 WatchpointSP
-Target::CreateWatchpoint(lldb::addr_t addr, size_t size, uint32_t type, Error &error)
+Target::CreateWatchpoint(lldb::addr_t addr, size_t size, const ClangASTType *type, uint32_t kind, Error &error)
 {
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
     if (log)
         log->Printf("Target::%s (addr = 0x%8.8llx size = %llu type = %u)\n",
-                    __FUNCTION__, addr, (uint64_t)size, type);
+                    __FUNCTION__, addr, (uint64_t)size, kind);
 
     WatchpointSP wp_sp;
     if (!ProcessIsValid())
@@ -559,7 +559,7 @@
             (matched_sp->WatchpointRead() ? LLDB_WATCH_TYPE_READ : 0) |
             (matched_sp->WatchpointWrite() ? LLDB_WATCH_TYPE_WRITE : 0);
         // Return the existing watchpoint if both size and type match.
-        if (size == old_size && type == old_type) {
+        if (size == old_size && kind == old_type) {
             wp_sp = matched_sp;
             wp_sp->SetEnabled(false);
         } else {
@@ -570,13 +570,12 @@
     }
 
     if (!wp_sp) {
-        Watchpoint *new_wp = new Watchpoint(addr, size);
+        Watchpoint *new_wp = new Watchpoint(*this, addr, size, type);
         if (!new_wp) {
             printf("Watchpoint ctor failed, out of memory?\n");
             return wp_sp;
         }
-        new_wp->SetWatchpointType(type);
-        new_wp->SetTarget(this);
+        new_wp->SetWatchpointType(kind);
         wp_sp.reset(new_wp);
         m_watchpoint_list.Add(wp_sp);
     }
@@ -1712,6 +1711,7 @@
             // we don't do anything with these for now
             break;
         case Value::eValueTypeScalar:
+        case Value::eValueTypeVector:
             clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
             clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
             break;
@@ -2167,7 +2167,6 @@
         "Always checking for inlined breakpoint locations can be expensive (memory and time), so we try to minimize the "
         "times we look for inlined locations. This setting allows you to control exactly which strategy is used when settings "
         "file and line breakpoints." },
-    { "disable-kext-loading"              , OptionValue::eTypeBoolean   , false, false                     , NULL, NULL, "Disable kext image loading in a Darwin kernel debug session" },
     { NULL                                 , OptionValue::eTypeInvalid   , false, 0                         , NULL, NULL, NULL }
 };
 enum
@@ -2191,8 +2190,7 @@
     ePropertyErrorPath,
     ePropertyDisableASLR,
     ePropertyDisableSTDIO,
-    ePropertyInlineStrategy,
-    ePropertyDisableKextLoading
+    ePropertyInlineStrategy
 };
 
 
@@ -2520,20 +2518,6 @@
     return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
 }
 
-bool
-TargetProperties::GetDisableKextLoading () const
-{
-    const uint32_t idx = ePropertyDisableKextLoading;
-    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
-}
-
-void
-TargetProperties::SetDisableKextLoading (bool b)
-{
-    const uint32_t idx = ePropertyDisableKextLoading;
-    m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
-}
-
 const TargetPropertiesSP &
 Target::GetGlobalProperties()
 {

Modified: lldb/branches/windows/source/Target/TargetList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Target/TargetList.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Target/TargetList.cpp (original)
+++ lldb/branches/windows/source/Target/TargetList.cpp Thu Nov  1 02:04:04 2012
@@ -160,8 +160,14 @@
         arch = specified_arch;
 
     FileSpec file (user_exe_path, false);
+    bool user_exe_path_is_bundle = false;
+    char resolved_bundle_exe_path[PATH_MAX];
+    resolved_bundle_exe_path[0] = '\0';
     if (file)
     {
+        if (file.GetFileType() == FileSpec::eFileTypeDirectory)
+            user_exe_path_is_bundle = true;
+
         if (file.IsRelativeToCurrentWorkingDirectory())
         {
             // Ignore paths that start with "./" and "../"
@@ -212,6 +218,8 @@
             }
             target_sp.reset(new Target(debugger, arch, platform_sp));
             target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
+            if (user_exe_path_is_bundle)
+                exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path));
         }
     }
     else
@@ -223,10 +231,21 @@
 
     if (target_sp)
     {
+        // Set argv0 with what the user typed, unless the user specified a
+        // directory. If the user specified a directory, then it is probably a
+        // bundle that was resolved and we need to use the resolved bundle path
         if (user_exe_path)
         {
             // Use exactly what the user typed as the first argument when we exec or posix_spawn
-            target_sp->SetArg0 (user_exe_path);
+            if (user_exe_path_is_bundle && resolved_bundle_exe_path[0])
+            {
+                target_sp->SetArg0 (resolved_bundle_exe_path);
+            }
+            else
+            {
+                // Just use what the user typed
+                target_sp->SetArg0 (user_exe_path);
+            }
         }
         if (file.GetDirectory())
         {

Modified: lldb/branches/windows/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Target/Thread.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Target/Thread.cpp (original)
+++ lldb/branches/windows/source/Target/Thread.cpp Thu Nov  1 02:04:04 2012
@@ -279,11 +279,16 @@
 void 
 Thread::DestroyThread ()
 {
+    m_destroy_called = true;
     m_plan_stack.clear();
     m_discarded_plan_stack.clear();
     m_completed_plan_stack.clear();
     m_actual_stop_info_sp.reset();
-    m_destroy_called = true;
+    m_reg_context_sp.reset();
+    m_unwinder_ap.reset();
+    Mutex::Locker locker(m_frame_mutex);
+    m_curr_frames_sp.reset();
+    m_prev_frames_sp.reset();
 }
 
 void

Modified: lldb/branches/windows/source/Target/ThreadPlanStepInRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Target/ThreadPlanStepInRange.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Target/ThreadPlanStepInRange.cpp (original)
+++ lldb/branches/windows/source/Target/ThreadPlanStepInRange.cpp Thu Nov  1 02:04:04 2012
@@ -95,14 +95,14 @@
     }
     else
     {
-        // Stepping through should be done stopping other threads in general, since we're setting a breakpoint and
-        // continuing...
+        // Stepping through should be done running other threads in general, since we're setting a breakpoint and
+        // continuing.  So only stop others if we are explicitly told to do so.
         
         bool stop_others;
-        if (m_stop_others != lldb::eAllThreads)
-            stop_others = true;
-        else
+        if (m_stop_others == lldb::eOnlyThisThread)
             stop_others = false;
+        else
+            stop_others = true;
             
         FrameComparison frame_order = CompareCurrentFrameToStartFrame();
         
@@ -291,10 +291,13 @@
     if (should_step_out)
     {
         // FIXME: Make sure the ThreadPlanForStepOut does the right thing with inlined functions.
+        // We really should have all plans take the tri-state for "stop others" so we can do the right
+        // thing.  For now let's be safe and always run others when we are likely to run arbitrary code.
+        const bool stop_others = false;
         return current_plan->GetThread().QueueThreadPlanForStepOut (false, 
                                                                     NULL, 
                                                                     true, 
-                                                                    current_plan->StopOthers(), 
+                                                                    stop_others,
                                                                     eVoteNo, 
                                                                     eVoteNoOpinion,
                                                                     0); // Frame index

Modified: lldb/branches/windows/source/Target/ThreadPlanStepInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Target/ThreadPlanStepInstruction.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Target/ThreadPlanStepInstruction.cpp (original)
+++ lldb/branches/windows/source/Target/ThreadPlanStepInstruction.cpp Thu Nov  1 02:04:04 2012
@@ -131,10 +131,14 @@
                     s.Address (return_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
                     log->Printf("%s.", s.GetData());
                 }
+                
+                // StepInstruction should probably have the tri-state RunMode, but for now it is safer to
+                // run others.
+                const bool stop_others = false;
                 m_thread.QueueThreadPlanForStepOut(false,
                                                    NULL,
                                                    true,
-                                                   m_stop_other_threads,
+                                                   stop_others,
                                                    eVoteNo,
                                                    eVoteNoOpinion,
                                                    0);

Modified: lldb/branches/windows/source/Target/ThreadPlanStepOverRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Target/ThreadPlanStepOverRange.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/source/Target/ThreadPlanStepOverRange.cpp (original)
+++ lldb/branches/windows/source/Target/ThreadPlanStepOverRange.cpp Thu Nov  1 02:04:04 2012
@@ -78,7 +78,7 @@
     
     // If we're out of the range but in the same frame or in our caller's frame
     // then we should stop.
-    // When stepping out we only step if we are forcing running one thread.
+    // When stepping out we only stop others if we are forcing running one thread.
     bool stop_others;
     if (m_stop_others == lldb::eOnlyThisThread)
         stop_others = true;

Modified: lldb/branches/windows/test/dotest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/dotest.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/dotest.py (original)
+++ lldb/branches/windows/test/dotest.py Thu Nov  1 02:04:04 2012
@@ -112,6 +112,12 @@
 # use this to track per-category failures
 failuresPerCategory = {}
 
+# The path to LLDB.framework is optional.
+lldbFrameworkPath = None
+
+# The path to lldb is optional
+lldbExecutablePath = None
+
 # The config file is optional.
 configFile = None
 
@@ -317,6 +323,8 @@
     global categoriesList
     global validCategories
     global useCategories
+    global lldbFrameworkPath
+    global lldbExecutablePath
     global configFile
     global archs
     global compilers
@@ -379,6 +387,8 @@
     # Configuration options
     group = parser.add_argument_group('Configuration options')
     group.add_argument('-c', metavar='config-file', help='Read a config file specified after this option')  # FIXME: additional doc.
+    group.add_argument('--framework', metavar='framework-path', help='The path to LLDB.framework')
+    group.add_argument('--executable', metavar='executable-path', help='The path to the lldb executable')
     group.add_argument('-e', metavar='benchmark-exe', help='Specify the full path of an executable used for benchmark purposes (see also: -x)')
     group.add_argument('-k', metavar='command', action='append', help="Specify a runhook, which is an lldb command to be executed by the debugger; The option can occur multiple times. The commands are executed one after the other to bring the debugger to a desired state, so that, for example, further benchmarking can be done")
     group.add_argument('-R', metavar='dir', help='Specify a directory to relocate the tests and their intermediate files to. BE WARNED THAT the directory, if exists, will be deleted before running this test driver. No cleanup of intermediate test files is performed in this case')
@@ -409,7 +419,10 @@
 
     platform_system = platform.system()
     platform_machine = platform.machine()
-    print args
+    
+    # only print the args if being verbose
+    if args.v:
+        print args
 
     if args.h:
         do_help = True
@@ -425,7 +438,9 @@
     if args.categoriesList:
         for category in args.categoriesList:
             if not(category in validCategories):
-                print "fatal error: category '" + category + "' is not a valid category - edit dotest.py or correct your invocation"
+                print "fatal error: category '" + category + "' is not a valid category"
+                print "if you have added a new category, please edit dotest.py, adding your new category to validCategories"
+                print "else, please specify one or more of the following: " + str(validCategories.keys())
                 sys.exit(1)
         categoriesList = set(args.categoriesList)
         useCategories = True
@@ -511,6 +526,12 @@
     if args.l:
         skip_long_running_test = False
 
+    if args.framework:
+        lldbFrameworkPath = args.framework
+
+    if args.executable:
+        lldbExecutablePath = args.executable
+
     if args.n:
         noHeaders = True
 
@@ -673,6 +694,8 @@
     global dumpSysPath
     global noHeaders
     global svn_info
+    global lldbFrameworkPath
+    global lldbExecutablePath
 
     # Get the directory containing the current script.
     if ("DOTEST_PROFILE" in os.environ or "DOTEST_PDB" in os.environ) and "DOTEST_SCRIPT_DIR" in os.environ:
@@ -722,56 +745,64 @@
     # Some of the tests can invoke the 'lldb' command directly.
     # We'll try to locate the appropriate executable right here.
 
-    # First, you can define an environment variable LLDB_EXEC specifying the
-    # full pathname of the lldb executable.
-    if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
-        lldbExec = os.environ["LLDB_EXEC"]
+    lldbExec = None
+    if lldbExecutablePath:
+        if is_exe(lldbExecutablePath):
+            lldbExec = lldbExecutablePath
+        else:
+            print lldbExecutablePath + " is not an executable"
+            sys.exit(-1)
     else:
-        lldbExec = None
-
-    executable = ['lldb']
-    dbgExec  = os.path.join(base, *(xcode3_build_dir + dbg + executable))
-    dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
-    dbcExec  = os.path.join(base, *(xcode3_build_dir + dbc + executable))
-    dbcExec2 = os.path.join(base, *(xcode4_build_dir + dbc + executable))
-    relExec  = os.path.join(base, *(xcode3_build_dir + rel + executable))
-    relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
-    baiExec  = os.path.join(base, *(xcode3_build_dir + bai + executable))
-    baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
-
-    # The 'lldb' executable built here in the source tree.
-    lldbHere = None
-    if is_exe(dbgExec):
-        lldbHere = dbgExec
-    elif is_exe(dbgExec2):
-        lldbHere = dbgExec2
-    elif is_exe(dbcExec):
-        lldbHere = dbcExec
-    elif is_exe(dbcExec2):
-        lldbHere = dbcExec2
-    elif is_exe(relExec):
-        lldbHere = relExec
-    elif is_exe(relExec2):
-        lldbHere = relExec2
-    elif is_exe(baiExec):
-        lldbHere = baiExec
-    elif is_exe(baiExec2):
-        lldbHere = baiExec2
-    elif lldbExec:
-        lldbHere = lldbExec
-
-    if lldbHere:
-        os.environ["LLDB_HERE"] = lldbHere
-        os.environ["LLDB_BUILD_DIR"] = os.path.split(lldbHere)[0]
-        if not noHeaders:
-            print "LLDB build dir:", os.environ["LLDB_BUILD_DIR"]
-            os.system('%s -v' % lldbHere)
-
-    # One last chance to locate the 'lldb' executable.
-    if not lldbExec:
-        lldbExec = which('lldb')
-        if lldbHere and not lldbExec:
-            lldbExec = lldbHere
+        # First, you can define an environment variable LLDB_EXEC specifying the
+        # full pathname of the lldb executable.
+        if "LLDB_EXEC" in os.environ and is_exe(os.environ["LLDB_EXEC"]):
+            lldbExec = os.environ["LLDB_EXEC"]
+        else:
+            lldbExec = None
+    
+        executable = ['lldb']
+        dbgExec  = os.path.join(base, *(xcode3_build_dir + dbg + executable))
+        dbgExec2 = os.path.join(base, *(xcode4_build_dir + dbg + executable))
+        dbcExec  = os.path.join(base, *(xcode3_build_dir + dbc + executable))
+        dbcExec2 = os.path.join(base, *(xcode4_build_dir + dbc + executable))
+        relExec  = os.path.join(base, *(xcode3_build_dir + rel + executable))
+        relExec2 = os.path.join(base, *(xcode4_build_dir + rel + executable))
+        baiExec  = os.path.join(base, *(xcode3_build_dir + bai + executable))
+        baiExec2 = os.path.join(base, *(xcode4_build_dir + bai + executable))
+    
+        # The 'lldb' executable built here in the source tree.
+        lldbHere = None
+        if is_exe(dbgExec):
+            lldbHere = dbgExec
+        elif is_exe(dbgExec2):
+            lldbHere = dbgExec2
+        elif is_exe(dbcExec):
+            lldbHere = dbcExec
+        elif is_exe(dbcExec2):
+            lldbHere = dbcExec2
+        elif is_exe(relExec):
+            lldbHere = relExec
+        elif is_exe(relExec2):
+            lldbHere = relExec2
+        elif is_exe(baiExec):
+            lldbHere = baiExec
+        elif is_exe(baiExec2):
+            lldbHere = baiExec2
+        elif lldbExec:
+            lldbHere = lldbExec
+    
+        if lldbHere:
+            os.environ["LLDB_HERE"] = lldbHere
+            os.environ["LLDB_BUILD_DIR"] = os.path.split(lldbHere)[0]
+            if not noHeaders:
+                print "LLDB build dir:", os.environ["LLDB_BUILD_DIR"]
+                os.system('%s -v' % lldbHere)
+    
+        # One last chance to locate the 'lldb' executable.
+        if not lldbExec:
+            lldbExec = which('lldb')
+            if lldbHere and not lldbExec:
+                lldbExec = lldbHere
 
 
     if not lldbExec:
@@ -791,41 +822,52 @@
 
     global ignore
 
-    # The '-i' option is used to skip looking for lldb.py in the build tree.
-    if ignore:
-        return
-
-    dbgPath  = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
-    dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
-    dbcPath  = os.path.join(base, *(xcode3_build_dir + dbc + python_resource_dir))
-    dbcPath2 = os.path.join(base, *(xcode4_build_dir + dbc + python_resource_dir))
-    relPath  = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
-    relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
-    baiPath  = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
-    baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
-
     lldbPath = None
-    if os.path.isfile(os.path.join(dbgPath, 'lldb/__init__.py')):
-        lldbPath = dbgPath
-    elif os.path.isfile(os.path.join(dbgPath2, 'lldb/__init__.py')):
-        lldbPath = dbgPath2
-    elif os.path.isfile(os.path.join(dbcPath, 'lldb/__init__.py')):
-        lldbPath = dbcPath
-    elif os.path.isfile(os.path.join(dbcPath2, 'lldb/__init__.py')):
-        lldbPath = dbcPath2
-    elif os.path.isfile(os.path.join(relPath, 'lldb/__init__.py')):
-        lldbPath = relPath
-    elif os.path.isfile(os.path.join(relPath2, 'lldb/__init__.py')):
-        lldbPath = relPath2
-    elif os.path.isfile(os.path.join(baiPath, 'lldb/__init__.py')):
-        lldbPath = baiPath
-    elif os.path.isfile(os.path.join(baiPath2, 'lldb/__init__.py')):
-        lldbPath = baiPath2
-
-    if not lldbPath:
-        print 'This script requires lldb.py to be in either ' + dbgPath + ',',
-        print relPath + ', or ' + baiPath
-        sys.exit(-1)
+    if lldbFrameworkPath:
+        candidatePath = os.path.join(lldbFrameworkPath, 'Resources', 'Python')
+        if os.path.isfile(os.path.join(candidatePath, 'lldb/__init__.py')):
+            lldbPath = candidatePath
+        if not lldbPath:
+            print 'Resources/Python/lldb/__init__.py was not found in ' + lldbFrameworkPath
+            sys.exit(-1)
+    else:
+        # The '-i' option is used to skip looking for lldb.py in the build tree.
+        if ignore:
+            return
+    
+        dbgPath  = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
+        dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
+        dbcPath  = os.path.join(base, *(xcode3_build_dir + dbc + python_resource_dir))
+        dbcPath2 = os.path.join(base, *(xcode4_build_dir + dbc + python_resource_dir))
+        relPath  = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
+        relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
+        baiPath  = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
+        baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
+    
+        if os.path.isfile(os.path.join(dbgPath, 'lldb/__init__.py')):
+            lldbPath = dbgPath
+        elif os.path.isfile(os.path.join(dbgPath2, 'lldb/__init__.py')):
+            lldbPath = dbgPath2
+        elif os.path.isfile(os.path.join(dbcPath, 'lldb/__init__.py')):
+            lldbPath = dbcPath
+        elif os.path.isfile(os.path.join(dbcPath2, 'lldb/__init__.py')):
+            lldbPath = dbcPath2
+        elif os.path.isfile(os.path.join(relPath, 'lldb/__init__.py')):
+            lldbPath = relPath
+        elif os.path.isfile(os.path.join(relPath2, 'lldb/__init__.py')):
+            lldbPath = relPath2
+        elif os.path.isfile(os.path.join(baiPath, 'lldb/__init__.py')):
+            lldbPath = baiPath
+        elif os.path.isfile(os.path.join(baiPath2, 'lldb/__init__.py')):
+            lldbPath = baiPath2
+    
+        if not lldbPath:
+            print 'This script requires lldb.py to be in either ' + dbgPath + ',',
+            print relPath + ', or ' + baiPath
+            sys.exit(-1)
+
+    # If tests need to find LLDB_FRAMEWORK, now they can do it
+    os.environ["LLDB_FRAMEWORK"] = os.path.dirname(os.path.dirname(lldbPath))
 
     # This is to locate the lldb.py module.  Insert it right after sys.path[0].
     sys.path[1:1] = [lldbPath]

Modified: lldb/branches/windows/test/functionalities/abbreviation/TestAbbreviations.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/functionalities/abbreviation/TestAbbreviations.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/functionalities/abbreviation/TestAbbreviations.py (original)
+++ lldb/branches/windows/test/functionalities/abbreviation/TestAbbreviations.py Thu Nov  1 02:04:04 2012
@@ -9,7 +9,7 @@
 import lldbutil
 
 class AbbreviationsTestCase(TestBase):
-    
+
     mydir = os.path.join("functionalities", "abbreviation")
 
     def test_nonrunning_command_abbreviations (self):
@@ -35,6 +35,11 @@
         self.expect("h",
                     startstr = "The following is a list of built-in, permanent debugger commands:")
 
+        # Execute cleanup function during test tear down
+        def cleanup():
+            self.runCmd("command alias t thread select")
+        self.addTearDownHook(cleanup)
+
         # Several matching commands: list them and error out.
         self.runCmd("command unalias t")
         self.expect("t",
@@ -136,7 +141,7 @@
                                  "thread #1:",
                                  "a.out",
                                  "sum\(a=1238, b=78392\)",
-                                 "at main.cpp\:25", 
+                                 "at main.cpp\:25",
                                  "stop reason = breakpoint 2.1" ])
 
         # ARCH, if not specified, defaults to x86_64.
@@ -147,7 +152,7 @@
                                    ' mov',
                                    ' addl ',
                                    'ret'],
-                        patterns = ['(leave|popq|popl)'])                               
+                        patterns = ['(leave|popq|popl)'])
 
         self.expect("i d l main.cpp",
                     patterns = ["Line table for .*main.cpp in `a.out"])

Modified: lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py (original)
+++ lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py Thu Nov  1 02:04:04 2012
@@ -141,6 +141,9 @@
                                '[2] = ', '3',
                                '[3] = ', '4'])            
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("numbers_list").MightHaveChildren(), "numbers_list.MightHaveChildren() says False for non empty!")
+
         self.runCmd("type format delete int")
 
         self.runCmd("c")
@@ -151,6 +154,9 @@
                                '[1]', 'is',
                                '[2]', 'smart'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("text_list").MightHaveChildren(), "text_list.MightHaveChildren() says False for non empty!")
+
         self.expect("p text_list",
                     substrs = ['list has 3 items',
                                '\"goofy\"',

Modified: lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py (original)
+++ lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py Thu Nov  1 02:04:04 2012
@@ -118,6 +118,9 @@
                     substrs = ['first =',
                                'second =']);
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("ii").MightHaveChildren(), "ii.MightHaveChildren() says False for non empty!")
+
         # check that the expression parser does not make use of
         # synthetic children instead of running code
         # TOT clang has a fix for this, which makes the expression command here succeed
@@ -180,6 +183,9 @@
                                'first = \"three\"',
                                'second = 3'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("si").MightHaveChildren(), "si.MightHaveChildren() says False for non empty!")
+
         # check access-by-index
         self.expect("frame variable si[0]",
                     substrs = ['first = ', 'one',
@@ -238,6 +244,9 @@
                                'second = \"!!!\"',
                                'first = 3'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("is").MightHaveChildren(), "is.MightHaveChildren() says False for non empty!")
+
         # check access-by-index
         self.expect("frame variable is[0]",
                     substrs = ['first = ',
@@ -291,6 +300,9 @@
                                'second = \"cat\"',
                                'first = \"gatto\"'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("ss").MightHaveChildren(), "ss.MightHaveChildren() says False for non empty!")
+
         # check access-by-index
         self.expect("frame variable ss[2]",
                     substrs = ['gatto', 'cat']);

Modified: lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py (original)
+++ lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py Thu Nov  1 02:04:04 2012
@@ -132,6 +132,9 @@
         self.expect("expression numbers_list[0]", matching=False, error=True,
                     substrs = ['0x12345678'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("numbers_list").MightHaveChildren(), "numbers_list.MightHaveChildren() says False for non empty!")
+
         self.runCmd("n")
             
         self.expect("frame variable numbers_list",
@@ -181,6 +184,9 @@
         self.expect("expression text_list[0]", matching=False, error=True,
                     substrs = ['goofy'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("text_list").MightHaveChildren(), "text_list.MightHaveChildren() says False for non empty!")
+
 if __name__ == '__main__':
     import atexit
     lldb.SBDebugger.Initialize()

Modified: lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py (original)
+++ lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py Thu Nov  1 02:04:04 2012
@@ -118,6 +118,9 @@
         self.expect("frame variable ii[8]", matching=True,
                     substrs = ['1234567'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("ii").MightHaveChildren(), "ii.MightHaveChildren() says False for non empty!")
+
         # check that the expression parser does not make use of
         # synthetic children instead of running code
         # TOT clang has a fix for this, which makes the expression command here succeed
@@ -189,7 +192,10 @@
         self.expect("frame variable si[0]",
                     substrs = ['first = ', 'four',
                                'second = 4']);
-        
+
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("si").MightHaveChildren(), "si.MightHaveChildren() says False for non empty!")
+
         # check that the expression parser does not make use of
         # synthetic children instead of running code
         # TOT clang has a fix for this, which makes the expression command here succeed
@@ -247,7 +253,10 @@
         self.expect("frame variable is[0]",
                     substrs = ['first = ',
                                'second =']);
-        
+
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("is").MightHaveChildren(), "is.MightHaveChildren() says False for non empty!")
+
         # check that the expression parser does not make use of
         # synthetic children instead of running code
         # TOT clang has a fix for this, which makes the expression command here succeed
@@ -304,6 +313,9 @@
         # check access-by-index
         self.expect("frame variable ss[3]",
                     substrs = ['gatto', 'cat']);
+
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("ss").MightHaveChildren(), "ss.MightHaveChildren() says False for non empty!")
         
         # check that the expression parser does not make use of
         # synthetic children instead of running code

Modified: lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py (original)
+++ lldb/branches/windows/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py Thu Nov  1 02:04:04 2012
@@ -143,6 +143,9 @@
         self.expect("expression numbers[6]", matching=False, error=True,
             substrs = ['1234567'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("numbers").MightHaveChildren(), "numbers.MightHaveChildren() says False for non empty!")
+
         # clear out the vector and see that we do the right thing once again
         self.runCmd("n")
 
@@ -204,6 +207,9 @@
         self.expect("expression strings[0]", matching=False, error=True,
                     substrs = ['goofy'])
 
+        # check that MightHaveChildren() gets it right
+        self.assertTrue(self.frame().FindVariable("strings").MightHaveChildren(), "strings.MightHaveChildren() says False for non empty!")
+
         self.runCmd("n")
 
         self.expect("frame variable strings",

Modified: lldb/branches/windows/test/functionalities/data-formatter/rdar-11086338/TestRdar11086338.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/functionalities/data-formatter/rdar-11086338/TestRdar11086338.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/functionalities/data-formatter/rdar-11086338/TestRdar11086338.py (original)
+++ lldb/branches/windows/test/functionalities/data-formatter/rdar-11086338/TestRdar11086338.py Thu Nov  1 02:04:04 2012
@@ -72,6 +72,9 @@
         self.expect('frame variable other_arr --ptr-depth 2 -d no-run-target',
                     substrs = ['@"4 objects"','@"6 objects" {','@"hello"','@"world"','@"this"','@"is"','@"me"','@"http://www.apple.com'])
 
+        self.assertTrue(self.frame().FindVariable("arr").MightHaveChildren(), "arr says it does not have children!")
+        self.assertTrue(self.frame().FindVariable("other_arr").MightHaveChildren(), "arr says it does not have children!")
+
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/branches/windows/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/functionalities/data-formatter/rdar-11988289/TestRdar%2011988289.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py (original)
+++ lldb/branches/windows/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py Thu Nov  1 02:04:04 2012
@@ -74,6 +74,9 @@
         self.expect('frame variable mutable --ptr-depth 3 -d no-run-target',
         substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"puartist"','3 key/value pairs {','@"bar"','@"2 objects"','(int)1','@"two"'])
 
+        self.assertTrue(self.frame().FindVariable("dictionary").MightHaveChildren(), "dictionary says it does not have children!")
+        self.assertTrue(self.frame().FindVariable("mutable").MightHaveChildren(), "mutable says it does not have children!")
+
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/branches/windows/test/functionalities/register/TestRegisters.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/functionalities/register/TestRegisters.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/functionalities/register/TestRegisters.py (original)
+++ lldb/branches/windows/test/functionalities/register/TestRegisters.py Thu Nov  1 02:04:04 2012
@@ -50,7 +50,8 @@
 
         # Test some register-related commands.
 
-        self.runCmd("register read -a")
+        self.expect("register read -a", MISSING_EXPECTED_REGISTERS,
+            substrs = ['registers were unavailable'], matching = False)
         self.runCmd("register read xmm0")
 
         # rdar://problem/10611315

Modified: lldb/branches/windows/test/functionalities/watchpoint/variable_out_of_scope/TestWatchedVarHitWhenInScope.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/functionalities/watchpoint/variable_out_of_scope/TestWatchedVarHitWhenInScope.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/functionalities/watchpoint/variable_out_of_scope/TestWatchedVarHitWhenInScope.py (original)
+++ lldb/branches/windows/test/functionalities/watchpoint/variable_out_of_scope/TestWatchedVarHitWhenInScope.py Thu Nov  1 02:04:04 2012
@@ -12,6 +12,15 @@
 
     mydir = os.path.join("functionalities", "watchpoint", "variable_out_of_scope")
 
+    #
+    # This test depends on not tracking watchpoint expression hits if we have
+    # left the watchpoint scope.  We will provide such an ability at some point
+    # but the way this was done was incorrect, and it is unclear that for the
+    # most part that's not what folks mostly want, so we have to provide a 
+    # clearer API to express this.
+    #
+
+    @unittest2.expectedFailure
     @dsym_test
     def test_watched_var_should_only_hit_when_in_scope_with_dsym(self):
         """Test that a variable watchpoint should only hit when in scope."""
@@ -19,6 +28,7 @@
         self.setTearDownCleanup(dictionary=self.d)
         self.watched_var()
 
+    @unittest2.expectedFailure
     @dwarf_test
     def test_watched_var_should_only_hit_when_in_scope_with_dwarf(self):
         """Test that a variable watchpoint should only hit when in scope."""

Modified: lldb/branches/windows/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py (original)
+++ lldb/branches/windows/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py Thu Nov  1 02:04:04 2012
@@ -97,8 +97,8 @@
 
         # Check that the watchpoint snapshoting mechanism is working.
         self.expect("watchpoint list -v",
-            substrs = ['old value:', 'global = 0',
-                       'new value:', 'global = 1'])
+            substrs = ['old value:', ' = 0',
+                       'new value:', ' = 1'])
 
         # The watchpoint command "forced" our global variable 'cookie' to become 777.
         self.expect("frame variable -g cookie",

Modified: lldb/branches/windows/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py (original)
+++ lldb/branches/windows/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py Thu Nov  1 02:04:04 2012
@@ -85,8 +85,8 @@
 
         # Check that the watchpoint snapshoting mechanism is working.
         self.expect("watchpoint list -v",
-            substrs = ['old value:', 'global = 0',
-                       'new value:', 'global = 1'])
+            substrs = ['old value:', ' = 0',
+                       'new value:', ' = 1'])
 
         # The watchpoint command "forced" our global variable 'cookie' to become 777.
         self.expect("frame variable -g cookie",

Modified: lldb/branches/windows/test/lang/c/struct_types/TestStructTypes.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/lang/c/struct_types/TestStructTypes.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/lang/c/struct_types/TestStructTypes.py (original)
+++ lldb/branches/windows/test/lang/c/struct_types/TestStructTypes.py Thu Nov  1 02:04:04 2012
@@ -55,6 +55,11 @@
         self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
             substrs = [' resolved, hit count = 1'])
 
+        # The padding should be an array of size 0
+        self.expect("image lookup -t point_tag",
+            DATA_TYPES_DISPLAYED_CORRECTLY,
+            substrs = ['padding[0]'])
+
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/branches/windows/test/lang/c/struct_types/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/lang/c/struct_types/main.c?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/lang/c/struct_types/main.c (original)
+++ lldb/branches/windows/test/lang/c/struct_types/main.c Thu Nov  1 02:04:04 2012
@@ -10,15 +10,15 @@
 {
     struct point_tag {
         int x;
-        char padding[0];
         int y;
+        char padding[0];
     }; // Set break point at this line.
 
     struct rect_tag {
         struct point_tag bottom_left;
         struct point_tag top_right;
     };
-    struct point_tag pt = { 2, {}, 3 }; // This is the first executable statement.
-    struct rect_tag rect = {{1, {}, 2}, {3, {}, 4}};
+    struct point_tag pt = { 2, 3, {} }; // This is the first executable statement.
+    struct rect_tag rect = {{1, 2, {}}, {3, 4, {}}};
     return 0;
 }

Modified: lldb/branches/windows/test/lldbtest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/test/lldbtest.py?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/test/lldbtest.py (original)
+++ lldb/branches/windows/test/lldbtest.py Thu Nov  1 02:04:04 2012
@@ -32,6 +32,7 @@
 """
 
 import os, sys, traceback
+import os.path
 import re
 from subprocess import *
 import StringIO
@@ -90,6 +91,8 @@
 
 BREAKPOINT_HIT_THRICE = "Breakpoint resolved with hit cout = 3"
 
+MISSING_EXPECTED_REGISTERS = "At least one expected register is unavailable."
+
 OBJECT_PRINTED_CORRECTLY = "Object printed correctly"
 
 SOURCE_DISPLAYED_CORRECTLY = "Source code displayed correctly"
@@ -414,6 +417,7 @@
     accomplish things.
     
     """
+
     # The concrete subclass should override this attribute.
     mydir = None
 
@@ -434,6 +438,7 @@
         # Fail fast if 'mydir' attribute is not overridden.
         if not cls.mydir or len(cls.mydir) == 0:
             raise Exception("Subclasses must override the 'mydir' attribute.")
+
         # Save old working directory.
         cls.oldcwd = os.getcwd()
 
@@ -1021,6 +1026,27 @@
         if lldb.pre_flight:
             lldb.pre_flight(self)
 
+    # utility methods that tests can use to access the current objects
+    def target(self):
+        if not self.dbg:
+            raise Exception('Invalid debugger instance')
+        return self.dbg.GetSelectedTarget()
+
+    def process(self):
+        if not self.dbg:
+            raise Exception('Invalid debugger instance')
+        return self.dbg.GetSelectedTarget().GetProcess()
+
+    def thread(self):
+        if not self.dbg:
+            raise Exception('Invalid debugger instance')
+        return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread()
+
+    def frame(self):
+        if not self.dbg:
+            raise Exception('Invalid debugger instance')
+        return self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
+
     def tearDown(self):
         #import traceback
         #traceback.print_stack()
@@ -1184,7 +1210,10 @@
                                  "Command '" + str + "' is expected to fail!")
         else:
             # No execution required, just compare str against the golden input.
-            output = str
+            if isinstance(str,lldb.SBCommandReturnObject):
+                output = str.GetOutput()
+            else:
+                output = str
             with recording(self, trace) as sbuf:
                 print >> sbuf, "looking at:", output
 

Modified: lldb/branches/windows/tools/debugserver/debugserver.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/debugserver.xcodeproj/project.pbxproj?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/debugserver.xcodeproj/project.pbxproj (original)
+++ lldb/branches/windows/tools/debugserver/debugserver.xcodeproj/project.pbxproj Thu Nov  1 02:04:04 2012
@@ -49,6 +49,8 @@
 		260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBThreadResumeActions.cpp; sourceTree = "<group>"; };
 		260E7332114BFFE600D1DFB3 /* DNBThreadResumeActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBThreadResumeActions.h; sourceTree = "<group>"; };
 		260FC7320E5B290400043FC9 /* debugnub-exports */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "debugnub-exports"; sourceTree = SOURCE_ROOT; };
+		26203D1C1641EFB200A662F7 /* com.apple.debugserver.applist.internal.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.applist.internal.plist; sourceTree = "<group>"; };
+		26203D1D1641EFB200A662F7 /* com.apple.debugserver.internal.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.internal.plist; sourceTree = "<group>"; };
 		26242C390DDBD33C0054A4CC /* debugserver-entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "debugserver-entitlements.plist"; sourceTree = "<group>"; };
 		264D5D571293835600ED4C01 /* DNBArch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArch.cpp; sourceTree = "<group>"; };
 		26593A060D4931CC001C9FE3 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
@@ -182,6 +184,8 @@
 		26A028FE114AB6A60029C479 /* Resources */ = {
 			isa = PBXGroup;
 			children = (
+				26203D1C1641EFB200A662F7 /* com.apple.debugserver.applist.internal.plist */,
+				26203D1D1641EFB200A662F7 /* com.apple.debugserver.internal.plist */,
 				260FC7320E5B290400043FC9 /* debugnub-exports */,
 				26242C390DDBD33C0054A4CC /* debugserver-entitlements.plist */,
 				26A4BAED0D498B7D00A9BEAB /* com.apple.debugserver.plist */,

Modified: lldb/branches/windows/tools/debugserver/source/DNB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/DNB.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/DNB.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/DNB.cpp Thu Nov  1 02:04:04 2012
@@ -23,6 +23,7 @@
 #include <sys/sysctl.h>
 #include <map>
 #include <vector>
+#include <libproc.h>
 
 #include "MacOSX/MachProcess.h"
 #include "MacOSX/MachTask.h"
@@ -31,6 +32,8 @@
 #include "DNBDataRef.h"
 #include "DNBThreadResumeActions.h"
 #include "DNBTimer.h"
+#include "CFBundle.h"
+
 
 typedef STD_SHARED_PTR(MachProcess) MachProcessSP;
 typedef std::map<nub_process_t, MachProcessSP> ProcessMap;
@@ -427,7 +430,6 @@
     return proc_infos.size();
 }
 
-
 static size_t
 GetAllInfosMatchingName(const char *full_process_name, std::vector<struct kinfo_proc>& matching_proc_infos)
 {
@@ -458,24 +460,27 @@
 
                 // Check for process by name. We only check the first MAXCOMLEN
                 // chars as that is all that kp_proc.p_comm holds.
+                
                 if (::strncasecmp(process_name, proc_infos[i].kp_proc.p_comm, MAXCOMLEN) == 0)
                 {
                     if (process_name_len > MAXCOMLEN)
                     {
                         // We found a matching process name whose first MAXCOMLEN
                         // characters match, but there is more to the name than
-                        // this. We need to get the full process name. 
+                        // this. We need to get the full process name.  Use proc_pidpath, which will get
+                        // us the full path to the executed process.
 
-                        int proc_args_mib[3] = { CTL_KERN, KERN_PROCARGS2, proc_infos[i].kp_proc.p_pid };
+                        char proc_path_buf[PATH_MAX];
                         
-                        // Get PATH_MAX for argv[0] plus 4 bytes for the argc
-                        char arg_data[PATH_MAX+4];
-                        size_t arg_data_size = sizeof(arg_data);
-                         // Skip the 4 byte argc integer value to get to argv[0]
-                        const char *argv0 = arg_data + 4;
-                        if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0)
+                        int return_val = proc_pidpath (proc_infos[i].kp_proc.p_pid, proc_path_buf, PATH_MAX);
+                        if (return_val > 0)
                         {
-                            const char *argv_basename = strrchr(argv0, '/');
+                            // Okay, now search backwards from that to see if there is a
+                            // slash in the name.  Note, even though we got all the args we don't care
+                            // because the list data is just a bunch of concatenated null terminated strings
+                            // so strrchr will start from the end of argv0.
+                            
+                            const char *argv_basename = strrchr(proc_path_buf, '/');
                             if (argv_basename)
                             {
                                 // Skip the '/'
@@ -484,7 +489,7 @@
                             else
                             {
                                 // We didn't find a directory delimiter in the process argv[0], just use what was in there
-                                argv_basename = argv0;
+                                argv_basename = proc_path_buf;
                             }
 
                             if (argv_basename)
@@ -2097,6 +2102,21 @@
 
     if (result.empty())
         result = path;
+    
+    struct stat path_stat;
+    if (::stat(path, &path_stat) == 0)
+    {
+        if ((path_stat.st_mode & S_IFMT) == S_IFDIR)
+        {
+            CFBundle bundle (path);
+            CFReleaser<CFURLRef> url(bundle.CopyExecutableURL ());
+            if (url.get())
+            {
+                if (::CFURLGetFileSystemRepresentation (url.get(), true, (UInt8*)resolved_path, resolved_path_size))
+                    return true;
+            }
+        }
+    }
 
     if (realpath(path, max_path))
     {

Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/CFBundle.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/CFBundle.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/CFBundle.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/CFBundle.cpp Thu Nov  1 02:04:04 2012
@@ -85,3 +85,13 @@
         return ::CFBundleGetIdentifier (bundle);
     return NULL;
 }
+
+
+CFURLRef
+CFBundle::CopyExecutableURL () const
+{
+    CFBundleRef bundle = get();
+    if (bundle != NULL)
+        return CFBundleCopyExecutableURL(bundle);
+    return NULL;
+}

Modified: lldb/branches/windows/tools/debugserver/source/MacOSX/CFBundle.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/MacOSX/CFBundle.h?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/MacOSX/CFBundle.h (original)
+++ lldb/branches/windows/tools/debugserver/source/MacOSX/CFBundle.h Thu Nov  1 02:04:04 2012
@@ -25,11 +25,17 @@
     CFBundle(const char *path = NULL);
     CFBundle(const CFBundle& rhs);
     CFBundle& operator=(const CFBundle& rhs);
-    virtual ~CFBundle();
+    virtual
+    ~CFBundle();
+    bool
+    SetPath (const char *path);
 
-        bool SetPath (const char *path);
-        CFStringRef GetIdentifier () const;
+    CFStringRef
+    GetIdentifier () const;
 
+    CFURLRef
+    CopyExecutableURL () const;
+    
 protected:
         CFReleaser<CFURLRef> m_bundle_url;
 };

Modified: lldb/branches/windows/tools/debugserver/source/debugserver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/debugserver/source/debugserver.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/tools/debugserver/source/debugserver.cpp (original)
+++ lldb/branches/windows/tools/debugserver/source/debugserver.cpp Thu Nov  1 02:04:04 2012
@@ -787,6 +787,8 @@
 int
 main (int argc, char *argv[])
 {
+    const char *argv_sub_zero = argv[0]; // save a copy of argv[0] for error reporting post-launch
+
     g_isatty = ::isatty (STDIN_FILENO);
 
     //  ::printf ("uid=%u euid=%u gid=%u egid=%u\n",
@@ -1426,7 +1428,7 @@
                     else
                     {
                         const char *error_str = remote->Context().LaunchStatus().AsString();
-                        RNBLogSTDERR ("error: failed to launch process %s: %s\n", argv[0], error_str ? error_str : "unknown error.");
+                        RNBLogSTDERR ("error: failed to launch process %s: %s\n", argv_sub_zero, error_str ? error_str : "unknown error.");
                     }
                 }
                 break;

Modified: lldb/branches/windows/tools/driver/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/driver/CMakeLists.txt?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/tools/driver/CMakeLists.txt (original)
+++ lldb/branches/windows/tools/driver/CMakeLists.txt Thu Nov  1 02:04:04 2012
@@ -87,6 +87,7 @@
   selectiondag
   bitreader
   mc
+  mcjit
   core
   mcdisassembler
   )

Added: lldb/branches/windows/tools/driver/Driver.cpp.orig
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/driver/Driver.cpp.orig?rev=167218&view=auto
==============================================================================
--- lldb/branches/windows/tools/driver/Driver.cpp.orig (added)
+++ lldb/branches/windows/tools/driver/Driver.cpp.orig Thu Nov  1 02:04:04 2012
@@ -0,0 +1,672 @@
+//===-- Driver.cpp ----------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Driver.h"
+
+#ifdef _WIN32
+#include "lldb/lldb-windows.h"
+#include "lldb/lldb-private-log.h"
+#include "lldb/Core/StreamCallback.h"
+#include "lldb/Core/Log.h"
+#endif
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <fcntl.h>
+
+#include "IOChannel.h"
+#include "lldb/API/SBBreakpoint.h"
+#include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBCommandReturnObject.h"
+#include "lldb/API/SBCommunication.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBHostOS.h"
+#include "lldb/API/SBListener.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/API/SBTarget.h"
+#include "lldb/API/SBThread.h"
+#include "lldb/API/SBProcess.h"
+
+using namespace lldb;
+
+static void reset_stdin_termios ();
+
+Driver::Driver () :
+    SBBroadcaster ("Driver"),
+    m_debugger (NULL),
+    m_editline_pty (),
+    m_editline_slave_fh (NULL),
+    m_editline_reader (),
+    m_io_channel_ap (),
+    m_option_data (),
+    m_waiting_for_command (false)
+{
+}
+
+Driver::~Driver ()
+{
+}
+
+const char *
+Driver::GetFilename() const
+{
+    if (m_option_data.m_args.empty())
+        return NULL;
+    return m_option_data.m_args.front().c_str();
+}
+
+const char *
+Driver::GetCrashLogFilename() const
+{
+    if (m_option_data.m_crash_log.empty())
+        return NULL;
+    return m_option_data.m_crash_log.c_str();
+}
+
+lldb::ScriptLanguage
+Driver::GetScriptLanguage() const
+{
+    return m_option_data.m_script_lang;
+}
+
+size_t
+Driver::GetNumSourceCommandFiles () const
+{
+    return m_option_data.m_source_command_files.size();
+}
+
+const char *
+Driver::GetSourceCommandFileAtIndex (uint32_t idx) const
+{
+    if (idx < m_option_data.m_source_command_files.size())
+        return m_option_data.m_source_command_files[idx].c_str();
+    return NULL;
+}
+
+bool
+Driver::GetDebugMode() const
+{
+    return m_option_data.m_debug_mode;
+}
+
+size_t
+Driver::GetProcessSTDOUT ()
+{
+    //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
+    char stdio_buffer[1024];
+    size_t len;
+    size_t total_bytes = 0;
+    while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
+    {
+        m_io_channel_ap->OutWrite (stdio_buffer, len, ASYNC);
+        total_bytes += len;
+    }
+    return total_bytes;
+}
+
+size_t
+Driver::GetProcessSTDERR ()
+{
+    //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
+    char stdio_buffer[1024];
+    size_t len;
+    size_t total_bytes = 0;
+    while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
+    {
+        m_io_channel_ap->ErrWrite (stdio_buffer, len, ASYNC);
+        total_bytes += len;
+    }
+    return total_bytes;
+}
+
+void
+Driver::UpdateSelectedThread ()
+{
+    using namespace lldb;
+    SBProcess process(m_debugger.GetSelectedTarget().GetProcess());
+    if (!process.IsValid())
+        return;
+    
+    SBThread curr_thread (process.GetSelectedThread());
+    SBThread thread;
+    StopReason curr_thread_stop_reason = eStopReasonInvalid;
+    curr_thread_stop_reason = curr_thread.GetStopReason();
+
+    if (!curr_thread.IsValid() ||
+        curr_thread_stop_reason == eStopReasonInvalid ||
+        curr_thread_stop_reason == eStopReasonNone)
+    {
+        // Prefer a thread that has just completed its plan over another thread as current thread.
+        SBThread plan_thread;
+        SBThread other_thread;
+       const size_t num_threads = process.GetNumThreads();
+        size_t i;
+        for (i = 0; i < num_threads; ++i)
+        {
+            thread = process.GetThreadAtIndex(i);
+            StopReason thread_stop_reason = thread.GetStopReason();
+            switch (thread_stop_reason)
+			{
+            default:
+            case eStopReasonInvalid:
+            case eStopReasonNone:
+                break;
+
+            case eStopReasonTrace:
+            case eStopReasonBreakpoint:
+            case eStopReasonWatchpoint:
+            case eStopReasonSignal:
+            case eStopReasonException:
+                if (!other_thread.IsValid())
+                    other_thread = thread;
+                break;
+            case eStopReasonPlanComplete:
+                if (!plan_thread.IsValid())
+                    plan_thread = thread;
+                break;
+            }
+        }
+        if (plan_thread.IsValid())
+            process.SetSelectedThread (plan_thread);
+        else if (other_thread.IsValid())
+            process.SetSelectedThread (other_thread);
+        else
+		{
+			if (curr_thread.IsValid())
+				thread = curr_thread;
+			else
+				thread = process.GetThreadAtIndex(0);
+
+<<<<<<< .working
+			if (thread.IsValid())
+				process.SetSelectedThread (thread);
+=======
+void
+Driver::HandleThreadEvent (const SBEvent &event)
+{
+    // At present the only thread event we handle is the Frame Changed event, and all we do for that is just
+    // reprint the thread status for that thread.
+    using namespace lldb;
+    const uint32_t event_type = event.GetType();
+    if (event_type == SBThread::eBroadcastBitStackChanged)
+    {
+        SBThread thread = SBThread::GetThreadFromEvent (event);
+        if (thread.IsValid())
+        {
+            SBStream out_stream;
+            thread.GetStatus(out_stream);
+            m_io_channel_ap->OutWrite (out_stream.GetData (), out_stream.GetSize (), ASYNC);
+        }
+    }
+}
+
+//  This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).
+
+bool
+Driver::HandleIOEvent (const SBEvent &event)
+{
+    bool quit = false;
+
+    const uint32_t event_type = event.GetType();
+
+    if (event_type & IOChannel::eBroadcastBitHasUserInput)
+    {
+        // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for
+        // handling.
+
+        const char *command_string = SBEvent::GetCStringFromEvent(event);
+        if (command_string == NULL)
+            command_string = "";
+        SBCommandReturnObject result;
+        
+        // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd
+        // output orderings and problems with the prompt.
+        m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true);
+
+        if (result.GetOutputSize() > 0)
+            m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), NO_ASYNC);
+            
+        if (result.GetErrorSize() > 0)
+            m_io_channel_ap->OutWrite (result.GetError(), result.GetErrorSize(), NO_ASYNC);
+
+        // We are done getting and running our command, we can now clear the
+        // m_waiting_for_command so we can get another one.
+        m_waiting_for_command = false;
+
+        // If our editline input reader is active, it means another input reader
+        // got pushed onto the input reader and caused us to become deactivated.
+        // When the input reader above us gets popped, we will get re-activated
+        // and our prompt will refresh in our callback
+        if (m_editline_reader.IsActive())
+        {
+            ReadyForCommand ();
+>>>>>>> .merge-right.r165938
+        }
+    }
+}
+
+void LogOutput(const char * msg, void *baton)
+{
+    puts(msg);
+}
+
+void Driver::Initialize()
+{
+    m_debugger = SBDebugger::Create(false, LogOutput, 0);
+    // We want to be able to handle CTRL+D in the terminal to have it terminate
+    // certain input
+    m_debugger.SetCloseInputOnEOF (false);
+    InitializePseudoTerminal();
+ 
+
+    m_debugger.SetErrorFileHandle (stderr, false);
+    m_debugger.SetOutputFileHandle (stdout, false);
+    m_debugger.SetInputFileHandle (stdin, true);
+ 
+    m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
+
+    InitializeEditLineIO();	
+
+	
+    SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
+    m_interpreter = &sb_interpreter;
+
+    SBListener listener(m_debugger.GetListener());
+    listener.StartListeningForEventClass(m_debugger, 
+                                         SBTarget::GetBroadcasterClassName(), 
+                                         SBTarget::eBroadcastBitBreakpointChanged);
+    if (!listener.IsValid())
+        return;
+
+    listener.StartListeningForEvents (*m_io_channel_ap,
+                                        IOChannel::eBroadcastBitHasUserInput |
+                                        IOChannel::eBroadcastBitUserInterrupt |
+                                        IOChannel::eBroadcastBitThreadShouldExit |
+                                        IOChannel::eBroadcastBitThreadDidStart |
+                                        IOChannel::eBroadcastBitThreadDidExit);
+
+    if (!m_io_channel_ap->Start ())
+        return;
+    
+	iochannel_thread_exited = false;
+	
+    listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
+                                        SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
+                                        SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
+                                        SBCommandInterpreter::eBroadcastBitAsynchronousErrorData);
+
+    // Before we handle any options from the command line, we parse the
+    // .lldbinit file in the user's home directory.
+    SBCommandReturnObject result;
+    sb_interpreter.SourceInitFileInHomeDirectory(result);
+
+    if (GetDebugMode())
+    {
+        result.PutError (m_debugger.GetErrorFileHandle());
+        result.PutOutput (m_debugger.GetOutputFileHandle());
+    }
+	HandleCommandLine(result);
+
+    // Now that all option parsing is done, we try and parse the .lldbinit
+    // file in the current working directory
+    sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
+    if (GetDebugMode())	
+    {
+        result.PutError(m_debugger.GetErrorFileHandle());
+        result.PutOutput(m_debugger.GetOutputFileHandle());
+    }
+	SBEvent event;
+    // Make sure the IO channel is started up before we try to tell it we
+    // are ready for input
+    listener.WaitForEventForBroadcasterWithType (UINT32_MAX, 
+                                                    *m_io_channel_ap,
+                                                    IOChannel::eBroadcastBitThreadDidStart, 
+                                                    event);
+    
+    // If we were asked to attach, then do that here:
+    // I'm going to use the command string rather than directly
+    // calling the API's because then I don't have to recode the
+    // event handling here.
+    if (!m_option_data.m_process_name.empty()
+        || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
+    {
+        AttachToProcess();
+    }
+    
+    ReadyForCommand ();
+}
+
+<<<<<<< .working
+void
+Driver::MainLoop ()
+{
+    SBEvent event;
+    while (!GetIsDone())
+=======
+    SBListener listener(m_debugger.GetListener());
+    if (listener.IsValid())
+>>>>>>> .merge-right.r165938
+    {
+<<<<<<< .working
+        m_listener->WaitForEvent (UINT32_MAX, event);
+        if (event.IsValid())
+		{
+            ProcessEvent(event);
+        }
+    }
+	
+	
+    DestroyPseudoTerminal();
+    CloseIOChannelFile ();
+ 
+    if (!iochannel_thread_exited)
+    {
+	        event.Clear();
+        m_listener->GetNextEventForBroadcasterWithType (*m_io_channel_ap,
+                                                        IOChannel::eBroadcastBitThreadDidExit,
+                                                        event);
+        if (!event.IsValid())
+=======
+
+        listener.StartListeningForEventClass(m_debugger, 
+                                         SBTarget::GetBroadcasterClassName(), 
+                                         SBTarget::eBroadcastBitBreakpointChanged);
+        listener.StartListeningForEventClass(m_debugger, 
+                                         SBThread::GetBroadcasterClassName(),
+                                         SBThread::eBroadcastBitStackChanged);
+        listener.StartListeningForEvents (*m_io_channel_ap,
+                                          IOChannel::eBroadcastBitHasUserInput |
+                                          IOChannel::eBroadcastBitUserInterrupt |
+                                          IOChannel::eBroadcastBitThreadShouldExit |
+                                          IOChannel::eBroadcastBitThreadDidStart |
+                                          IOChannel::eBroadcastBitThreadDidExit);
+
+        if (m_io_channel_ap->Start ())
+>>>>>>> .merge-right.r165938
+        {
+<<<<<<< .working
+            // Send end EOF to the driver file descriptor
+            m_io_channel_ap->Stop();
+=======
+            bool iochannel_thread_exited = false;
+
+            listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
+                                              SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
+                                              SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
+                                              SBCommandInterpreter::eBroadcastBitAsynchronousErrorData);
+
+            // Before we handle any options from the command line, we parse the
+            // .lldbinit file in the user's home directory.
+            SBCommandReturnObject result;
+            sb_interpreter.SourceInitFileInHomeDirectory(result);
+            if (GetDebugMode())
+            {
+                result.PutError (m_debugger.GetErrorFileHandle());
+                result.PutOutput (m_debugger.GetOutputFileHandle());
+            }
+
+            // Now we handle options we got from the command line
+            char command_string[PATH_MAX * 2];
+            const size_t num_source_command_files = GetNumSourceCommandFiles();
+            if (num_source_command_files > 0)
+            {
+                for (size_t i=0; i < num_source_command_files; ++i)
+                {
+                    const char *command_file = GetSourceCommandFileAtIndex(i);
+                    ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file);
+                    m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false);
+                    if (GetDebugMode())
+                    {
+                        result.PutError (m_debugger.GetErrorFileHandle());
+                        result.PutOutput (m_debugger.GetOutputFileHandle());
+                    }
+                }
+            }
+
+            // Was there a core file specified?
+            std::string core_file_spec("");
+            if (!m_option_data.m_core_file.empty())
+                core_file_spec.append("--core ").append(m_option_data.m_core_file);
+
+            const size_t num_args = m_option_data.m_args.size();
+            if (num_args > 0)
+            {
+                char arch_name[64];
+                if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
+                    ::snprintf (command_string, 
+                                sizeof (command_string), 
+                                "target create --arch=%s %s \"%s\"", 
+                                arch_name,
+                                core_file_spec.c_str(),
+                                m_option_data.m_args[0].c_str());
+                else
+                    ::snprintf (command_string, 
+                                sizeof(command_string), 
+                                "target create %s \"%s\"", 
+                                core_file_spec.c_str(),
+                                m_option_data.m_args[0].c_str());
+
+                m_debugger.HandleCommand (command_string);
+                
+                if (num_args > 1)
+                {
+                    m_debugger.HandleCommand ("settings clear target.run-args");
+                    char arg_cstr[1024];
+                    for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
+                    {
+                        ::snprintf (arg_cstr, 
+                                    sizeof(arg_cstr), 
+                                    "settings append target.run-args \"%s\"", 
+                                    m_option_data.m_args[arg_idx].c_str());
+                        m_debugger.HandleCommand (arg_cstr);
+                    }
+                }
+            }
+            else if (!core_file_spec.empty())
+            {
+                ::snprintf (command_string, 
+                            sizeof(command_string), 
+                            "target create %s", 
+                            core_file_spec.c_str());
+                m_debugger.HandleCommand (command_string);;
+            }
+
+            // Now that all option parsing is done, we try and parse the .lldbinit
+            // file in the current working directory
+            sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
+            if (GetDebugMode())
+            {
+                result.PutError(m_debugger.GetErrorFileHandle());
+                result.PutOutput(m_debugger.GetOutputFileHandle());
+            }
+
+            SBEvent event;
+
+            // Make sure the IO channel is started up before we try to tell it we
+            // are ready for input
+            listener.WaitForEventForBroadcasterWithType (UINT32_MAX, 
+                                                         *m_io_channel_ap,
+                                                         IOChannel::eBroadcastBitThreadDidStart, 
+                                                         event);
+            // If we were asked to attach, then do that here:
+            // I'm going to use the command string rather than directly
+            // calling the API's because then I don't have to recode the
+            // event handling here.
+            if (!m_option_data.m_process_name.empty()
+                || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
+            {
+                std::string command_str("process attach ");
+                if (m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
+                {
+                    command_str.append("-p ");
+                    char pid_buffer[32];
+                    ::snprintf (pid_buffer, sizeof(pid_buffer), "%llu", m_option_data.m_process_pid);
+                    command_str.append(pid_buffer);
+                }
+                else 
+                {
+                    command_str.append("-n \"");
+                    command_str.append(m_option_data.m_process_name);
+                    command_str.push_back('\"');
+                    if (m_option_data.m_wait_for)
+                        command_str.append(" -w");
+                }
+                
+                if (m_debugger.GetOutputFileHandle())
+                    ::fprintf (m_debugger.GetOutputFileHandle(), 
+                               "Attaching to process with:\n    %s\n", 
+                               command_str.c_str());
+                                               
+                // Force the attach to be synchronous:
+                bool orig_async = m_debugger.GetAsync();
+                m_debugger.SetAsync(true);
+                m_debugger.HandleCommand(command_str.c_str());
+                m_debugger.SetAsync(orig_async);                
+            }
+                        
+            ReadyForCommand ();
+
+            while (!GetIsDone())
+            {
+                listener.WaitForEvent (UINT32_MAX, event);
+                if (event.IsValid())
+                {
+                    if (event.GetBroadcaster().IsValid())
+                    {
+                        uint32_t event_type = event.GetType();
+                        if (event.BroadcasterMatchesRef (*m_io_channel_ap))
+                        {
+                            if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
+                                (event_type & IOChannel::eBroadcastBitThreadDidExit))
+                            {
+                                SetIsDone();
+                                if (event_type & IOChannel::eBroadcastBitThreadDidExit)
+                                    iochannel_thread_exited = true;
+                            }
+                            else
+                            {
+                                if (HandleIOEvent (event))
+                                    SetIsDone();
+                            }
+                        }
+                        else if (SBProcess::EventIsProcessEvent (event))
+                        {
+                            HandleProcessEvent (event);
+                        }
+                        else if (SBBreakpoint::EventIsBreakpointEvent (event))
+                        {
+                            HandleBreakpointEvent (event);
+                        }
+                        else if (SBThread::EventIsThreadEvent (event))
+                        {
+                            HandleThreadEvent (event);
+                        }
+                        else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
+                        {
+                            // TODO: deprecate the eBroadcastBitQuitCommandReceived event
+                            // now that we have SBCommandInterpreter::SetCommandOverrideCallback()
+                            // that can take over a command
+                            if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
+                            {
+                                SetIsDone();
+                            }
+                            else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData)
+                            {
+                                const char *data = SBEvent::GetCStringFromEvent (event);
+                                m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC);
+                            }
+                            else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData)
+                            {
+                                const char *data = SBEvent::GetCStringFromEvent (event);
+                                m_io_channel_ap->OutWrite (data, strlen(data), ASYNC);
+                            }
+                        }
+                    }
+                }
+            }
+
+            editline_output_pty.CloseMasterFileDescriptor();
+            master_out_comm.Disconnect();
+            out_comm_2.Disconnect();
+            reset_stdin_termios();
+            fclose (stdin);
+
+            CloseIOChannelFile ();
+
+            if (!iochannel_thread_exited)
+            {
+                event.Clear();
+                listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap,
+                                                             IOChannel::eBroadcastBitThreadDidExit,
+                                                             event);
+                if (!event.IsValid())
+                {
+                    // Send end EOF to the driver file descriptor
+                    m_io_channel_ap->Stop();
+                }
+            }
+
+            SBDebugger::Destroy (m_debugger);
+>>>>>>> .merge-right.r165938
+        }
+    }
+	SBDebugger::Destroy (m_debugger);
+}
+
+
+void
+Driver::ReadyForCommand ()
+{
+    if (m_waiting_for_command == false)
+    {
+        m_waiting_for_command = true;
+        BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true);
+    }
+}
+
+// defined in DriverPosix.cpp
+void SetupPosixSignals();
+
+int
+main (int argc, char const *argv[], const char *envp[])
+{
+#if 1 // Enable for debug logging
+    lldb::StreamSP logStream(new lldb_private::StreamCallback(LogOutput, 0));
+    const char* logCategories[] = { 0 };
+    lldb::LogSP log = lldb_private::EnableLog(logStream, 0, logCategories, 0);
+    log->GetMask().Reset(LIBLLDB_LOG_ALL);
+#endif
+    SBDebugger::Initialize();
+    
+    SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
+
+	SetupPosixSignals();
+    // Create a scope for driver so that the driver object will destroy itself
+    // before SBDebugger::Terminate() is called.
+    {
+        Driver driver;
+
+        bool exit = false;
+        SBError error = driver.ParseArgs (argc, argv, stdout, exit);
+        if (error.Fail())
+        {
+            const char *error_cstr = error.GetCString ();
+            if (error_cstr)
+                ::fprintf (stderr, "error: %s\n", error_cstr);
+        }
+        else if (!exit)
+        {
+            driver.Initialize();
+        }
+    }
+
+    SBDebugger::Terminate();
+    return 0;
+}

Modified: lldb/branches/windows/tools/driver/DriverOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/tools/driver/DriverOptions.cpp?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/tools/driver/DriverOptions.cpp (original)
+++ lldb/branches/windows/tools/driver/DriverOptions.cpp Thu Nov  1 02:04:04 2012
@@ -35,32 +35,34 @@
 
 static OptionDefinition g_options[] =
 {
-    { LLDB_OPT_SET_1,    true , "help"           , 'h', no_argument      , 0,  eArgTypeNone,         
+    { LLDB_OPT_SET_1,    true , "help"           , 'h', no_argument      , 0,  eArgTypeNone,
         "Prints out the usage information for the LLDB debugger." },
-    { LLDB_OPT_SET_2,    true , "version"        , 'v', no_argument      , 0,  eArgTypeNone,         
+    { LLDB_OPT_SET_2,    true , "version"        , 'v', no_argument      , 0,  eArgTypeNone,
         "Prints out the current version number of the LLDB debugger." },
-    { LLDB_OPT_SET_3,    true , "arch"           , 'a', required_argument, 0,  eArgTypeArchitecture, 
+    { LLDB_OPT_SET_3,    true , "arch"           , 'a', required_argument, 0,  eArgTypeArchitecture,
         "Tells the debugger to use the specified architecture when starting and running the program.  <architecture> must "
         "be one of the architectures for which the program was compiled." },
-    { LLDB_OPT_SET_3,    true , "file"           , 'f', required_argument, 0,  eArgTypeFilename,     
+    { LLDB_OPT_SET_3,    true , "file"           , 'f', required_argument, 0,  eArgTypeFilename,
         "Tells the debugger to use the file <filename> as the program to be debugged." },
-    { LLDB_OPT_SET_4,    true , "attach-name"    , 'n', required_argument, 0,  eArgTypeProcessName,  
+    { LLDB_OPT_SET_3,    false, "core"           , 'c', required_argument, 0,  eArgTypeFilename,
+        "Tells the debugger to use the fullpath to <path> as the core file." },
+    { LLDB_OPT_SET_4,    true , "attach-name"    , 'n', required_argument, 0,  eArgTypeProcessName,
         "Tells the debugger to attach to a process with the given name." },
-    { LLDB_OPT_SET_4,    true , "wait-for"       , 'w', no_argument      , 0,  eArgTypeNone,         
+    { LLDB_OPT_SET_4,    true , "wait-for"       , 'w', no_argument      , 0,  eArgTypeNone,
         "Tells the debugger to wait for a process with the given pid or name to launch before attaching." },
-    { LLDB_OPT_SET_5,    true , "attach-pid"     , 'p', required_argument, 0,  eArgTypePid,          
+    { LLDB_OPT_SET_5,    true , "attach-pid"     , 'p', required_argument, 0,  eArgTypePid,
         "Tells the debugger to attach to a process with the given pid." },
-    { LLDB_3_TO_5,       false, "script-language", 'l', required_argument, 0,  eArgTypeScriptLang,   
+    { LLDB_3_TO_5,       false, "script-language", 'l', required_argument, 0,  eArgTypeScriptLang,
         "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default.  "
         "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl.  Currently only the Python "
         "extensions have been implemented." },
-    { LLDB_3_TO_5,       false, "debug"          , 'd', no_argument      , 0,  eArgTypeNone,         
+    { LLDB_3_TO_5,       false, "debug"          , 'd', no_argument      , 0,  eArgTypeNone,
         "Tells the debugger to print out extra information for debugging itself." },
-    { LLDB_3_TO_5,       false, "source"         , 's', required_argument, 0,  eArgTypeFilename,     
+    { LLDB_3_TO_5,       false, "source"         , 's', required_argument, 0,  eArgTypeFilename,
         "Tells the debugger to read in and execute the file <file>, which should contain lldb commands." },
-    { LLDB_3_TO_5,       false, "editor"         , 'e', no_argument      , 0,  eArgTypeNone,         
+    { LLDB_3_TO_5,       false, "editor"         , 'e', no_argument      , 0,  eArgTypeNone,
         "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
-    { LLDB_3_TO_5,       false, "no-lldbinit"    , 'x', no_argument      , 0,  eArgTypeNone,         
+    { LLDB_3_TO_5,       false, "no-lldbinit"    , 'x', no_argument      , 0,  eArgTypeNone,
         "Do not automatically parse any '.lldbinit' files." },
     { 0,                 false, NULL             , 0  , 0                , 0,  eArgTypeNone,         NULL }
 };

Modified: lldb/branches/windows/www/lldb-gdb.html
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/www/lldb-gdb.html?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/www/lldb-gdb.html (original)
+++ lldb/branches/windows/www/lldb-gdb.html Thu Nov  1 02:04:04 2012
@@ -585,6 +585,25 @@
                         </td>
                     </tr>
 
+                    <tr><td class="header" colspan="2">Creating and assigning a value to a convenience variable.</td></tr>
+                    <tr>
+                        <td class="content">
+                            <b>(gdb)</b> set $foo = 5<br>
+                            <b>(gdb)</b> set variable $foo = 5<br>
+                              or using the print command <br>
+                            <b>(gdb)</b> print $foo = 5<br>
+                              or using the call command <br>
+                            <b>(gdb)</b> call $foo = 5<br>
+                              and if you want to specify the type of the variable:
+                            <b>(gdb)</b> set $foo = (unsigned int) 5<br>
+
+                        </td>
+                        <td class="content">
+                          In lldb you evaluate a variable declaration expression as you would write it in C:<br>
+                            <b>(lldb)</b> expr unsigned int $foo = 5<br>
+                        </td>
+                    </tr>
+
                     <tr><td class="header" colspan="2">Printing the ObjC "description" of an object.</td></tr>
                     <tr>
                         <td class="content">
@@ -649,6 +668,18 @@
                         </td>
                     </tr>
 
+                    <tr><td class="header" colspan="2">Backtrace the first five frames of the current thread.</td></tr>
+                    <tr>
+                        <td class="content">
+                            <b>(gdb)</b> bt 5
+                        </td>
+                        <td class="content">
+                            <b>(lldb)</b> thread backtrace -c 5<br>
+                            <b>(lldb)</b> bt 5 (<i>lldb-169 and later</i>)<br>
+                            <b>(lldb)</b> bt -c 5 (<i>lldb-168 and earlier</i>)
+                        </td>
+                    </tr>
+
                     <tr><td class="header" colspan="2">Select a different stack frame by index for the current thread.</td></tr>
                     <tr>
                         <td class="content">
@@ -946,7 +977,7 @@
                         </td>
                     </tr>
 
-                    <tr><td class="header" colspan="2">Lookup information for a raw address in the executable or any shared libraries.</td></tr>
+                    <tr><td class="header" colspan="2">Look up information for a raw address in the executable or any shared libraries.</td></tr>
                     <tr>
                         <td class="content">
                             <b>(gdb)</b> info symbol 0x1ec4<br>
@@ -957,7 +988,7 @@
                         </td>
                     </tr>
 
-                    <tr><td class="header" colspan="2">Lookup functions matching a regular expression in a binary.</td></tr>
+                    <tr><td class="header" colspan="2">Look up functions matching a regular expression in a binary.</td></tr>
                     <tr>
                         <td class="content">
                             <b>(gdb)</b> info function <FUNC_REGEX><br>
@@ -971,7 +1002,7 @@
                         </td>
                     </tr>
 
-                    <tr><td class="header" colspan="2">Lookup information for an address in <b>a.out</a> only.</td></tr>
+                    <tr><td class="header" colspan="2">Look up information for an address in <b>a.out</a> only.</td></tr>
                     <tr>
                         <td class="content">
                         </td>
@@ -981,10 +1012,10 @@
                         </td>
                     </tr>
 
-                    <tr><td class="header" colspan="2">Lookup information for for a type <code>Point</code> by name.</td></tr>
+                    <tr><td class="header" colspan="2">Look up information for for a type <code>Point</code> by name.</td></tr>
                     <tr>
                         <td class="content">
-                            <b>(lldb)</b> ptype Point<br>
+                            <b>(gdb)</b> ptype Point<br>
                         </td>
                         <td class="content">
                             <b>(lldb)</b> image lookup --type Point<br>
@@ -1052,6 +1083,26 @@
                         </td>
                     </tr>
 
+                    <tr><td class="header" colspan="2">Remap source file pathnames for the debug session.  If your source files are no longer located in the same location as when the program was built --- maybe the program was built on a different computer --- you need to tell the debugger how to find the sources at their local file path instead of the build system's file path.</td></tr>
+                    <tr>
+                        <td class="content">
+                            <b>(gdb)</b> set pathname-substitutions /buildbot/path /my/path<br>
+                        </td>
+                        <td class="content">
+                            <b>(lldb)</b> settings set target.source-map /buildbot/path /my/path<br>
+                        </td>
+                    </tr>
+
+                    <tr><td class="header" colspan="2">Supply a catchall directory to search for source files in.</td></tr>
+                    <tr>
+                        <td class="content">
+                            <b>(gdb)</b> directory /my/path<br>
+                        </td>
+                        <td class="content">
+                            (<i>No equivalent command yet.)<br>
+                        </td>
+                    </tr>
+
                     </table>
                     <p>
                 </div>

Modified: lldb/branches/windows/www/python-reference.html
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/www/python-reference.html?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/www/python-reference.html (original)
+++ lldb/branches/windows/www/python-reference.html Thu Nov  1 02:04:04 2012
@@ -213,9 +213,9 @@
                     scripts to breakpoints provides a way to create complex breakpoint
                     conditions and also allows for smart logging and data gathering.</p>
                 <p>When your process hits a breakpoint to which you have attached some python code, the code is executed as the
-                   body of a function which takes two arguments:</p>
+                   body of a function which takes three arguments:</p>
                     <p>
-<code><pre><tt>def breakpoint_function_wrapper(<b>frame</b>, <b>bp_loc</b>):
+<code><pre><tt>def breakpoint_function_wrapper(<b>frame</b>, <b>bp_loc</b>, <b>dict</b>):
   <font color=green># Your code goes here</font>
 </tt></pre></code>
                     <p><table class="stats" width="620" cellspacing="0">
@@ -251,6 +251,17 @@
                             are represented by <b>lldb.SBBreakpointLocation</b> objects.
                         </td>
                     </tr>
+                    <tr>
+                        <td class="content">
+                            <b>dict</b>
+                        </td>
+                        <td class="content">
+                            <b>dict</b>
+                        </td>
+                        <td class="content">
+                            The python session dictionary as a standard python dictionary object.
+                        </td>
+                    </tr>
                     </table>
              <p>An example will show how simple it is to write some python code and attach it to a breakpoint. 
                 The following example will allow you to track the order in which the functions in a given shared library 

Modified: lldb/branches/windows/www/sidebar.incl
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/www/sidebar.incl?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/www/sidebar.incl (original)
+++ lldb/branches/windows/www/sidebar.incl Thu Nov  1 02:04:04 2012
@@ -14,16 +14,13 @@
     <div class="urbangreymenu">
       <h1 class="headerbar">Use and Extension</h1>
       <ul>
-        <li><a href="architecture.html">Architecture</a></li>
-        <li><a href="customization.html">Customization</a></li>
-        <li><a href="docs.html">Documentation</a></li>
-        <li><a href="faq.html">FAQ</a></li>
+        <li><a href="tutorial.html">Tutorial</a></li>
+        <li><a href="lldb-gdb.html">GDB and LLDB command examples</a></li>
         <li><a href="formats.html">Frame and Thread Formatting</a></li>
-        <li><a href="lldb-gdb.html">LLDB and GDB</a></li>
+        <li><a href="varformats.html">Variable Formatting</a></li>
         <li><a href="python-reference.html">Python Reference</a></li>
         <li><a href="scripting.html">Python Example</a></li>
-        <li><a href="tutorial.html">Tutorial</a></li>
-        <li><a href="varformats.html">Variable Formatting</a></li>
+        <li><a href="architecture.html">Architecture</a></li>
       </ul>
     </div>
   </div>
@@ -48,4 +45,4 @@
     </ul>
     </div>
   </div>
-</div>
\ No newline at end of file
+</div>

Modified: lldb/branches/windows/www/tutorial.html
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/www/tutorial.html?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/www/tutorial.html (original)
+++ lldb/branches/windows/www/tutorial.html Thu Nov  1 02:04:04 2012
@@ -347,7 +347,7 @@
                     to see all the commands for watchpoint manipulations.  For instance, we might do the following to watch
                     a variable called 'global' for write operation, but only stop if the condition '(global==5)' is true:</p>
 
-                   <pre><tt>(lldb) watch set var -w write global
+                   <pre><tt>(lldb) watch set var global
 Watchpoint created: Watchpoint 1: addr = 0x100001018 size = 4 state = enabled type = w
     declare @ '/Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp:12'
 (lldb) watch modify -c '(global==5)'

Modified: lldb/branches/windows/www/varformats.html
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/www/varformats.html?rev=167218&r1=167217&r2=167218&view=diff
==============================================================================
--- lldb/branches/windows/www/varformats.html (original)
+++ lldb/branches/windows/www/varformats.html Thu Nov  1 02:04:04 2012
@@ -1039,8 +1039,12 @@
 			        <i>this call should return a new LLDB SBValue object representing the child at the index given as argument</i> <br/>
 			    <font color=blue>def</font> update(self): <br/>
 			        <i>this call should be used to update the internal state of this Python object whenever the state of the variables in LLDB changes.</i><sup>[1]</sup><br/>
+			    <font color=blue>def</font> has_children(self): <br/>
+			        <i>this call should return True if this object might have children, and False if this object can be guaranteed not to have children.</i><sup>[2]</sup><br/>
 		</code>
 <sup>[1]</sup> This method is optional. Also, it may optionally choose to return a value (starting with LLDB SVN rev153061/LLDB-134). If it returns a value, and that value is <font color=blue><code>True</code></font>, LLDB will be allowed to cache the children and the children count it previously obtained, and will not return to the provider class to ask. If nothing, <font color=blue><code>None</code></font>, or anything other than <font color=blue><code>True</code></font> is returned, LLDB will discard the cached information and ask. Regardless, whenever necessary LLDB will call <code>update</code>.
+<br/>
+<sup>[2]</sup> This method is optional, and LLDB will honor it starting with SVN rev166495. While implementing it in terms of <code>num_children</code> is acceptable, implementors are encouraged to look for optimized coding alternatives whenever reasonable. For an example, see the <code>std::list</code> providers shipping with LLDB.
 		<p>For examples of how synthetic children are created, you are encouraged to look at <a href="http://llvm.org/svn/llvm-project/lldb/trunk/examples/synthetic/">examples/synthetic</a> in the LLDB trunk.
 			You may especially want to begin looking at <a href="http://llvm.org/svn/llvm-project/lldb/trunk/examples/synthetic/bitfield">this example</a> to get
 			a feel for this feature, as it is a very easy and well commented example.</p>





More information about the lldb-commits mailing list