Added support for looking up the complete type for
Objective-C classes.  This allows LLDB to find
ivars declared in class extensions in modules other
than where the debugger is currently stopped (we
already supported this when the debugger was
stopped in the same module as the definition).

This involved the following main changes:

- The ObjCLanguageRuntime now knows how to hunt
  for the authoritative version of an Objective-C
  type.  It looks for the symbol indicating a
  definition, and then gets the type from the
  module containing that symbol.

- ValueObjects now report their type with a
  potential override, and the override is set if
  the type of the ValueObject is an Objective-C
  class or pointer type that is defined somewhere
  other than the original reported type.  This
  means that "frame variable" will always use the
  complete type if one is available.

- The ClangASTSource now looks for the complete
  type when looking for ivars.  This means that
  "expr" will always use the complete type if one
  is available.

- I added a testcase that verifies that both
  "frame variable" and "expr" work.


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@151214 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/ObjCLanguageRuntime.cpp b/source/Target/ObjCLanguageRuntime.cpp
index 00d3aa4..0076ff0 100644
--- a/source/Target/ObjCLanguageRuntime.cpp
+++ b/source/Target/ObjCLanguageRuntime.cpp
@@ -14,6 +14,7 @@
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/Type.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -94,6 +95,84 @@
     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 ClangNamespaceDecl *null_namespace_decl = NULL;
+    const bool append = false;
+    const uint32_t max_matches = UINT32_MAX;
+    TypeList types;
+    
+    module_sp->FindTypes(null_sc, 
+                         name,
+                         null_namespace_decl,
+                         append, 
+                         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)
 {