Pulled in a new version of LLVM/Clang to solve a variety
of problems with Objective-C object completion.  To go
along with the LLVM/Clang-side fixes, we have a variety
of Objective-C improvements.

Fixes include:

- It is now possible to run expressions when stopped in
  an Objective-C class method and have "self" act just
  like "self" would act in the class method itself (i.e.,
  [self classMethod] works without casting the return
  type if debug info is present).  To accomplish this,
  the expression masquerades as a class method added by
  a category.

- Objective-C objects can now provide methods and
  properties and methods to Clang on demand (i.e., the
  ASTImporter sets hasExternalVisibleDecls on Objective-C
  interface objects).

- Objective-C built-in types, which had long been a bone
  of contention (should we be using "id"?  "id*"?), are
  now fetched correctly using accessor functions on
  ClangASTContext.  We inhibit searches for them in the
  debug information.

There are also a variety of logging fixes, and I made two
changes to the test suite:

- Enabled a test case for Objective-C properties in the
  current translation unit.

- Added a test case for calling Objective-C class methods
  when stopped in a class method.


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@144607 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ASTDumper.cpp b/source/Expression/ASTDumper.cpp
index 1c819b1..a82a892 100644
--- a/source/Expression/ASTDumper.cpp
+++ b/source/Expression/ASTDumper.cpp
@@ -63,7 +63,7 @@
     decl_ctx->setHasExternalVisibleStorage(has_external_visible_storage);
 }
 
-ASTDumper::ASTDumper (clang::Type *type)
+ASTDumper::ASTDumper (const clang::Type *type)
 {
     m_dump = clang::QualType(type, 0).getAsString();
 }
diff --git a/source/Expression/ClangASTSource.cpp b/source/Expression/ClangASTSource.cpp
index c62db70..a2597ba 100644
--- a/source/Expression/ClangASTSource.cpp
+++ b/source/Expression/ClangASTSource.cpp
@@ -311,6 +311,10 @@
                                      current_id);
         }
     }
+    else if (const ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(context.m_decl_context))
+    {
+        FindObjCPropertyDecls(context);
+    }
     else if (!isa<TranslationUnitDecl>(context.m_decl_context))
     {
         // we shouldn't be getting FindExternalVisibleDecls calls for these
@@ -568,6 +572,63 @@
     }
 }
 
+void
+ClangASTSource::FindObjCPropertyDecls (NameSearchContext &context)
+{
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+    static unsigned int invocation_id = 0;
+    unsigned int current_id = invocation_id++;
+    
+    const ObjCInterfaceDecl *iface_decl = cast<ObjCInterfaceDecl>(context.m_decl_context);
+    Decl *orig_decl;
+    ASTContext *orig_ast_ctx;
+    
+    m_ast_importer->ResolveDeclOrigin(iface_decl, &orig_decl, &orig_ast_ctx);
+    
+    if (!orig_decl)
+        return;
+    
+    ObjCInterfaceDecl *orig_iface_decl = dyn_cast<ObjCInterfaceDecl>(orig_decl);
+    
+    if (!orig_iface_decl)
+        return;
+    
+    if (!ClangASTContext::GetCompleteDecl(orig_ast_ctx, orig_iface_decl))
+        return;
+    
+    std::string property_name_str = context.m_decl_name.getAsString();
+    StringRef property_name(property_name_str.c_str());
+    ObjCPropertyDecl *property_decl = orig_iface_decl->FindPropertyDeclaration(&orig_ast_ctx->Idents.get(property_name));
+    
+    if (log)
+        log->Printf("ClangASTSource::FindObjCPropertyDecls[%d] for property '%s.%s'",
+                    current_id, 
+                    iface_decl->getNameAsString().c_str(), 
+                    property_name_str.c_str());
+    
+    if (!property_decl)
+        return;
+    
+    Decl *copied_decl = m_ast_importer->CopyDecl(orig_ast_ctx, property_decl);
+    
+    if (!copied_decl)
+        return;
+    
+    ObjCPropertyDecl *copied_property_decl = dyn_cast<ObjCPropertyDecl>(copied_decl);
+    
+    if (!copied_property_decl)
+        return;
+    
+    if (log)
+    {
+        ASTDumper dumper((Decl*)copied_property_decl);
+        log->Printf("  CAS::FOPD[%d] found %s", current_id, dumper.GetCString());
+    }
+ 
+    context.AddNamedDecl(copied_property_decl);
+}
+
 void 
 ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map,
                                       const ConstString &name,
diff --git a/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp
index 6e62c29..4299220 100644
--- a/source/Expression/ClangExpressionDeclMap.cpp
+++ b/source/Expression/ClangExpressionDeclMap.cpp
@@ -1105,13 +1105,13 @@
 
     if (frame == NULL || process == NULL || target == NULL)
     {
-        err.SetErrorString("Couldn't load 'this' because the context is incomplete");
+        err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
         return false;
     }
     
     if (!m_struct_vars->m_object_pointer_type.GetOpaqueQualType())
     {
-        err.SetErrorString("Couldn't load 'this' because its type is unknown");
+        err.SetErrorStringWithFormat("Couldn't load '%s' because its type is unknown", object_name.AsCString());
         return false;
     }
     
@@ -1121,7 +1121,7 @@
     
     if (!object_ptr_var)
     {
-        err.SetErrorStringWithFormat("Couldn't find '%s' with appropriate type in scope", object_name.GetCString());
+        err.SetErrorStringWithFormat("Couldn't find '%s' with appropriate type in scope", object_name.AsCString());
         return false;
     }
     
@@ -2224,12 +2224,7 @@
                                      current_id);
         }
     }
-    else if (!isa<TranslationUnitDecl>(context.m_decl_context))
-    {
-        // we shouldn't be getting FindExternalVisibleDecls calls for these
-        return;
-    }
-    else
+    else if (isa<TranslationUnitDecl>(context.m_decl_context))
     {
         ClangNamespaceDecl namespace_decl;
         
@@ -2342,12 +2337,47 @@
             
             if (!frame)
                 return;
+         
+            SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction);
+            
+            if (!sym_ctx.function)
+                return;
+            
+            clang::DeclContext *decl_context;
+            
+            if (sym_ctx.block && sym_ctx.block->GetInlinedFunctionInfo())
+                decl_context = sym_ctx.block->GetClangDeclContextForInlinedFunction();
+            else
+                decl_context = sym_ctx.function->GetClangDeclContext();
+            
+            if (!decl_context)
+                return;
+            
+            clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context);
+            
+            if (!method_decl)
+                return;
+
+            ObjCInterfaceDecl* self_interface = method_decl->getClassInterface();
+            
+            if (!self_interface)
+                return;
+            
+            const clang::Type *interface_type = self_interface->getTypeForDecl();
+                    
+            TypeFromUser class_user_type(QualType(interface_type, 0).getAsOpaquePtr(),
+                                         &method_decl->getASTContext());
+            
+            if (log)
+            {
+                ASTDumper ast_dumper(interface_type);
+                log->Printf("  FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
+            }
+                
+            AddOneType(context, class_user_type, current_id, false);
             
             VariableList *vars = frame->GetVariableList(false);
             
-            if (!vars)
-                return;
-            
             lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
             
             if (!self_var || 
@@ -2364,25 +2394,6 @@
                                         self_type->GetClangAST());
             
             m_struct_vars->m_object_pointer_type = self_user_type;
-            
-            void *pointer_target_type = NULL;
-            
-            if (!ClangASTContext::IsPointerType(self_user_type.GetOpaqueQualType(),
-                                                &pointer_target_type)
-                || pointer_target_type == NULL)
-                return;
-            
-            TypeFromUser class_user_type(pointer_target_type,
-                                         self_type->GetClangAST());
-            
-            if (log)
-            {
-                ASTDumper ast_dumper(pointer_target_type);
-                log->Printf("  FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
-            }
-            
-            AddOneType(context, class_user_type, current_id, false);
-            
             return;
         }
         
diff --git a/source/Expression/ClangUserExpression.cpp b/source/Expression/ClangUserExpression.cpp
index 25eb8c4..4ae34a3 100644
--- a/source/Expression/ClangUserExpression.cpp
+++ b/source/Expression/ClangUserExpression.cpp
@@ -56,6 +56,7 @@
     m_objectivec (false),
     m_needs_object_ptr (false),
     m_const_object (false),
+    m_static_method(false),
     m_target (NULL),
     m_evaluated_statically (false),
     m_const_result ()
@@ -167,7 +168,7 @@
     }
     else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context))
     {        
-        if (m_allow_objc && method_decl->isInstanceMethod())
+        if (m_allow_objc)
         {
             VariableList *vars = frame->GetVariableList(false);
             
@@ -193,6 +194,9 @@
             
             m_objectivec = true;
             m_needs_object_ptr = true;
+            
+            if (!method_decl->isInstanceMethod())
+                m_static_method = true;
         }
     }
 }
@@ -274,7 +278,7 @@
     else
         lang_type = lldb::eLanguageTypeC;
     
-    if (!source_code->GetText(m_transformed_text, lang_type, m_const_object))
+    if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method))
     {
         error_stream.PutCString ("error: couldn't construct expression body");
         return false;
diff --git a/source/Expression/ExpressionSourceCode.cpp b/source/Expression/ExpressionSourceCode.cpp
index 4b749b5..b1719b3 100644
--- a/source/Expression/ExpressionSourceCode.cpp
+++ b/source/Expression/ExpressionSourceCode.cpp
@@ -13,7 +13,7 @@
 
 using namespace lldb_private;
 
-bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object) const
+bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object, bool static_method) const
 {
     if (m_wrap)
     {
@@ -59,21 +59,42 @@
                                m_body.c_str());
             break;
         case lldb::eLanguageTypeObjC:
-            wrap_stream.Printf("%s                                                      \n"
-                                "typedef unsigned short unichar;                        \n"
-                                "@interface $__lldb_objc_class ($__lldb_category)       \n"
-                                "-(void)%s:(void *)$__lldb_arg;                         \n"
-                                "@end                                                   \n"
-                                "@implementation $__lldb_objc_class ($__lldb_category)  \n"
-                                "-(void)%s:(void *)$__lldb_arg                          \n"
-                                "{                                                      \n"
-                                "    %s;                                                \n"
-                                "}                                                      \n"
-                                "@end                                                   \n",
-                                m_prefix.c_str(),
-                                m_name.c_str(),
-                                m_name.c_str(),
-                                m_body.c_str());
+            if (static_method)
+            {
+                wrap_stream.Printf("%s                                                      \n"
+                                    "typedef unsigned short unichar;                        \n"
+                                    "@interface $__lldb_objc_class ($__lldb_category)       \n"
+                                    "+(void)%s:(void *)$__lldb_arg;                         \n"
+                                    "@end                                                   \n"
+                                    "@implementation $__lldb_objc_class ($__lldb_category)  \n"
+                                    "+(void)%s:(void *)$__lldb_arg                          \n"
+                                    "{                                                      \n"
+                                    "    %s;                                                \n"
+                                    "}                                                      \n"
+                                    "@end                                                   \n",
+                                    m_prefix.c_str(),
+                                    m_name.c_str(),
+                                    m_name.c_str(),
+                                    m_body.c_str());
+            }
+            else
+            {
+                wrap_stream.Printf("%s                                                      \n"
+                                   "typedef unsigned short unichar;                        \n"
+                                   "@interface $__lldb_objc_class ($__lldb_category)       \n"
+                                   "-(void)%s:(void *)$__lldb_arg;                         \n"
+                                   "@end                                                   \n"
+                                   "@implementation $__lldb_objc_class ($__lldb_category)  \n"
+                                   "-(void)%s:(void *)$__lldb_arg                          \n"
+                                   "{                                                      \n"
+                                   "    %s;                                                \n"
+                                   "}                                                      \n"
+                                   "@end                                                   \n",
+                                   m_prefix.c_str(),
+                                   m_name.c_str(),
+                                   m_name.c_str(),
+                                   m_body.c_str());
+            }
             break;
         }
         
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index d7e1ddf..fe19fea 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -931,19 +931,19 @@
 clang_type_t
 ClangASTContext::GetBuiltInType_objc_id()
 {
-    return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinIdTy).getAsOpaquePtr();
+    return getASTContext()->getObjCIdType().getAsOpaquePtr();
 }
 
 clang_type_t
 ClangASTContext::GetBuiltInType_objc_Class()
 {
-    return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinClassTy).getAsOpaquePtr();
+    return getASTContext()->getObjCClassType().getAsOpaquePtr();
 }
 
 clang_type_t
 ClangASTContext::GetBuiltInType_objc_selector()
 {
-    return getASTContext()->getPointerType(getASTContext()->ObjCBuiltinSelTy).getAsOpaquePtr();
+    return getASTContext()->getObjCSelType().getAsOpaquePtr();
 }
 
 clang_type_t
@@ -4694,7 +4694,7 @@
         {
             ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
             
-            class_interface_decl->setForwardDecl(false);
+            class_interface_decl->completedForwardDecl();
         }
         
         const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr());
diff --git a/source/Symbol/ClangASTImporter.cpp b/source/Symbol/ClangASTImporter.cpp
index ef0dcfe..92c2325 100644
--- a/source/Symbol/ClangASTImporter.cpp
+++ b/source/Symbol/ClangASTImporter.cpp
@@ -186,14 +186,26 @@
         to_namespace_decl->setHasExternalVisibleStorage();
     }
     
-    if (isa<ObjCInterfaceDecl>(from))
+    if (ObjCInterfaceDecl *from_interface_decl = dyn_cast<ObjCInterfaceDecl>(from))
     {
         ObjCInterfaceDecl *to_interface_decl = dyn_cast<ObjCInterfaceDecl>(to);
         
+        to_interface_decl->setHasExternalLexicalStorage();
         to_interface_decl->setHasExternalVisibleStorage();
         
-        if (!to_interface_decl->isForwardDecl())
-            to_interface_decl->setExternallyCompleted();
+        if (to_interface_decl->isForwardDecl())
+            to_interface_decl->completedForwardDecl();
+        
+        to_interface_decl->setExternallyCompleted();
+        
+        if (log)
+            log->Printf("    [ClangASTImporter] Imported %p, a %s named %s%s%s%s",
+                        to,
+                        ((clang::Decl*)from_interface_decl)->getDeclKindName(),
+                        from_interface_decl->getName().str().c_str(),
+                        (to_interface_decl->hasExternalLexicalStorage() ? " Lexical" : ""),
+                        (to_interface_decl->hasExternalVisibleStorage() ? " Visible" : ""),
+                        (to_interface_decl->isForwardDecl() ? " Forward" : ""));
     }
     
     return clang::ASTImporter::Imported(from, to);