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/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,