summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2012-09-11 21:44:01 +0000
committerSean Callanan <scallanan@apple.com>2012-09-11 21:44:01 +0000
commitbc47dfcba2644d7dbc466afa7fa2c1778e4fa4cf (patch)
treee540e225d35adca9b310077b8692e5271cc3492a
parent822ab6b2e4a76bbd9abb790d67b0ec030beb79ed (diff)
downloadbcm5719-llvm-bc47dfcba2644d7dbc466afa7fa2c1778e4fa4cf.tar.gz
bcm5719-llvm-bc47dfcba2644d7dbc466afa7fa2c1778e4fa4cf.zip
This patch is part of ongoing work to extract type
information from the Objective-C runtime. This patch takes the old AppleObjCSymbolVendor and replaces it with an AppleObjCTypeVendor, which is much more lightweight. Specifically, the SymbolVendor needs to pretend that there is a backing symbol file for the Types it vends, whereas a TypeVendor only vends bare ClangASTTypes. These ClangASTTypes only need to exist in an ASTContext. The ClangASTSource now falls back to the runtime's TypeVendor (if one exists) if the debug information doesn't find a complete type for a particular Objective-C interface. The runtime's TypeVendor maintains an ASTContext full of types it knows about, and re-uses the ISA-based type query information used by the ValueObjects. Currently, the runtime's TypeVendor doesn't provide useful answers because we haven't yet implemented a way to iterate across all ISAs contained in the target process's runtime. That's the next step. llvm-svn: 163651
-rw-r--r--lldb/include/lldb/Symbol/TypeVendor.h56
-rw-r--r--lldb/include/lldb/Target/LanguageRuntime.h6
-rw-r--r--lldb/include/lldb/Target/ObjCLanguageRuntime.h8
-rw-r--r--lldb/source/Expression/ClangASTSource.cpp395
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp13
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h8
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp83
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp198
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h (renamed from lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h)26
-rw-r--r--lldb/source/Target/ObjCLanguageRuntime.cpp10
10 files changed, 560 insertions, 243 deletions
diff --git a/lldb/include/lldb/Symbol/TypeVendor.h b/lldb/include/lldb/Symbol/TypeVendor.h
new file mode 100644
index 00000000000..4ae82fd9522
--- /dev/null
+++ b/lldb/include/lldb/Symbol/TypeVendor.h
@@ -0,0 +1,56 @@
+//===-- TypeVendor.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_TypeVendor_h_
+#define liblldb_TypeVendor_h_
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+// The type vendor class is intended as a generic interface to search
+// for Clang types that are not necessarily backed by a specific symbol
+// file.
+//----------------------------------------------------------------------
+class TypeVendor
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ TypeVendor()
+ {
+ }
+
+ virtual
+ ~TypeVendor()
+ {
+ }
+
+ virtual uint32_t
+ FindTypes (const ConstString &name,
+ bool append,
+ uint32_t max_matches,
+ std::vector <ClangASTType> &types) = 0;
+
+protected:
+ //------------------------------------------------------------------
+ // Classes that inherit from TypeVendor can see and modify these
+ //------------------------------------------------------------------
+
+private:
+ //------------------------------------------------------------------
+ // For TypeVendor only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (TypeVendor);
+};
+
+
+} // namespace lldb_private
+
+#endif
diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h
index 4ca9f7419d2..5a4dc7ae7f6 100644
--- a/lldb/include/lldb/Target/LanguageRuntime.h
+++ b/lldb/include/lldb/Target/LanguageRuntime.h
@@ -83,6 +83,12 @@ public:
static const char *
GetNameForLanguageType (lldb::LanguageType language);
+
+ Process *
+ GetProcess()
+ {
+ return m_process;
+ }
protected:
//------------------------------------------------------------------
diff --git a/lldb/include/lldb/Target/ObjCLanguageRuntime.h b/lldb/include/lldb/Target/ObjCLanguageRuntime.h
index 24891ed15c5..64aded76adf 100644
--- a/lldb/include/lldb/Target/ObjCLanguageRuntime.h
+++ b/lldb/include/lldb/Target/ObjCLanguageRuntime.h
@@ -19,6 +19,7 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/TypeVendor.h"
#include "lldb/Target/LanguageRuntime.h"
namespace lldb_private {
@@ -222,14 +223,17 @@ public:
virtual ObjCISA
GetISA(ValueObject& valobj) = 0;
+ virtual ObjCISA
+ GetISA(const ConstString &name);
+
virtual ConstString
GetActualTypeName(ObjCISA isa);
virtual ObjCISA
GetParentClass(ObjCISA isa);
- virtual SymbolVendor *
- GetSymbolVendor()
+ virtual TypeVendor *
+ GetTypeVendor()
{
return NULL;
}
diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp
index f94eb9c8e6c..80a9ea3dd6a 100644
--- a/lldb/source/Expression/ClangASTSource.cpp
+++ b/lldb/source/Expression/ClangASTSource.cpp
@@ -622,9 +622,11 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
name.GetCString(),
(name_string ? name_string : "<anonymous>"));
}
-
+
+ clang::ASTContext *type_ast = type_sp->GetClangAST();
+ lldb::clang_type_t full_type = type_sp->GetClangFullType();
- void *copied_type = GuardedCopyType(m_ast_context, type_sp->GetClangAST(), type_sp->GetClangFullType());
+ void *copied_type = GuardedCopyType(m_ast_context, type_ast, full_type);
if (!copied_type)
{
@@ -641,6 +643,87 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context,
} while(0);
}
+static void
+FindObjCMethodDeclsWithOrigin (unsigned int current_id,
+ NameSearchContext &context,
+ ObjCInterfaceDecl *original_interface_decl,
+ clang::ASTContext *ast_context,
+ ClangASTImporter *ast_importer,
+ const char *log_info)
+{
+ const DeclarationName &decl_name(context.m_decl_name);
+ clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
+
+ Selector original_selector;
+
+ if (decl_name.isObjCZeroArgSelector())
+ {
+ IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
+ original_selector = original_ctx->Selectors.getSelector(0, &ident);
+ }
+ else if (decl_name.isObjCOneArgSelector())
+ {
+ const std::string &decl_name_string = decl_name.getAsString();
+ std::string decl_name_string_without_colon(decl_name_string.c_str(), decl_name_string.length() - 1);
+ IdentifierInfo *ident = &original_ctx->Idents.get(decl_name_string_without_colon.c_str());
+ original_selector = original_ctx->Selectors.getSelector(1, &ident);
+ }
+ else
+ {
+ SmallVector<IdentifierInfo *, 4> idents;
+
+ clang::Selector sel = decl_name.getObjCSelector();
+
+ int num_args = sel.getNumArgs();
+
+ for (unsigned i = 0;
+ i != num_args;
+ ++i)
+ {
+ idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
+ }
+
+ original_selector = original_ctx->Selectors.getSelector(num_args, idents.data());
+ }
+
+ DeclarationName original_decl_name(original_selector);
+
+ ObjCInterfaceDecl::lookup_result result = original_interface_decl->lookup(original_decl_name);
+
+ if (result.first == result.second)
+ return;
+
+ if (!*result.first)
+ return;
+
+ ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(*result.first);
+
+ if (!result_method)
+ return;
+
+ Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method);
+
+ if (!copied_decl)
+ return;
+
+ ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
+
+ if (!copied_method_decl)
+ return;
+
+ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ {
+ ASTDumper dumper((Decl*)copied_method_decl);
+ log->Printf(" CAS::FOMD[%d] found (%s) %s", current_id, log_info, dumper.GetCString());
+ }
+
+ context.AddNamedDecl(copied_method_decl);
+
+ return;
+}
+
void
ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
{
@@ -669,72 +752,12 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
ObjCInterfaceDecl *original_interface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl);
- Selector original_selector;
-
- if (decl_name.isObjCZeroArgSelector())
- {
- IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
- original_selector = original_ctx->Selectors.getSelector(0, &ident);
- }
- else if (decl_name.isObjCOneArgSelector())
- {
- const std::string &decl_name_string = decl_name.getAsString();
- std::string decl_name_string_without_colon(decl_name_string.c_str(), decl_name_string.length() - 1);
- IdentifierInfo *ident = &original_ctx->Idents.get(decl_name_string_without_colon.c_str());
- original_selector = original_ctx->Selectors.getSelector(1, &ident);
- }
- else
- {
- SmallVector<IdentifierInfo *, 4> idents;
-
- clang::Selector sel = decl_name.getObjCSelector();
-
- int num_args = sel.getNumArgs();
-
- for (unsigned i = 0;
- i != num_args;
- ++i)
- {
- idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
- }
-
- original_selector = original_ctx->Selectors.getSelector(num_args, idents.data());
- }
-
- DeclarationName original_decl_name(original_selector);
-
- ObjCInterfaceDecl::lookup_result result = original_interface_decl->lookup(original_decl_name);
-
- if (result.first == result.second)
- break;
-
- if (!*result.first)
- break;
-
- ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(*result.first);
-
- if (!result_method)
- break;
-
- Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &result_method->getASTContext(), result_method);
-
- if (!copied_decl)
- continue;
-
- ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
-
- if (!copied_method_decl)
- continue;
-
- if (log)
- {
- ASTDumper dumper((Decl*)copied_method_decl);
- log->Printf(" CAS::FOMD[%d] found (in debug info) %s", current_id, dumper.GetCString());
- }
-
- context.AddNamedDecl(copied_method_decl);
-
- return;
+ FindObjCMethodDeclsWithOrigin(current_id,
+ context,
+ original_interface_decl,
+ m_ast_context,
+ m_ast_importer,
+ "in debug info");
} while (0);
StreamString ss;
@@ -845,53 +868,105 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context)
}
while (0);
- for (uint32_t i = 0, e = sc_list.GetSize();
- i != e;
- ++i)
+ if (sc_list.GetSize())
{
- SymbolContext sc;
-
- if (!sc_list.GetContextAtIndex(i, sc))
- continue;
-
- if (!sc.function)
- continue;
-
- DeclContext *function_ctx = sc.function->GetClangDeclContext();
-
- if (!function_ctx)
- continue;
-
- ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(function_ctx);
-
- if (!method_decl)
- continue;
-
- ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface();
-
- if (!found_interface_decl)
- continue;
+ // We found a good function symbol. Use that.
- if (found_interface_decl->getName() == interface_decl->getName())
+ for (uint32_t i = 0, e = sc_list.GetSize();
+ i != e;
+ ++i)
{
- Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
+ SymbolContext sc;
- if (!copied_decl)
+ if (!sc_list.GetContextAtIndex(i, sc))
continue;
- ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
+ if (!sc.function)
+ continue;
- if (!copied_method_decl)
+ DeclContext *function_ctx = sc.function->GetClangDeclContext();
+
+ if (!function_ctx)
continue;
- if (log)
+ ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(function_ctx);
+
+ if (!method_decl)
+ continue;
+
+ ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface();
+
+ if (!found_interface_decl)
+ continue;
+
+ if (found_interface_decl->getName() == interface_decl->getName())
{
- ASTDumper dumper((Decl*)copied_method_decl);
- log->Printf(" CAS::FOMD[%d] found (in debug info) %s", current_id, dumper.GetCString());
+ Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl);
+
+ if (!copied_decl)
+ continue;
+
+ ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
+
+ if (!copied_method_decl)
+ continue;
+
+ if (log)
+ {
+ ASTDumper dumper((Decl*)copied_method_decl);
+ log->Printf(" CAS::FOMD[%d] found (in debug info) %s", current_id, dumper.GetCString());
+ }
+
+ context.AddNamedDecl(copied_method_decl);
}
+ }
+ }
+ else
+ {
+ do
+ {
+ // We need to look at the runtime.
+
+ lldb::ProcessSP process(m_target->GetProcessSP());
+
+ if (!process)
+ break;
+
+ ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+
+ TypeVendor *type_vendor = language_runtime->GetTypeVendor();
+
+ if (!type_vendor)
+ break;
+
+ ConstString interface_name(interface_decl->getNameAsString().c_str());
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector <ClangASTType> types;
+
+ if (!type_vendor->FindTypes(interface_name,
+ append,
+ max_matches,
+ types))
+ break;
- context.AddNamedDecl(copied_method_decl);
+ const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr();
+
+ const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type);
+
+ if (!runtime_interface_type)
+ break;
+
+ ObjCInterfaceDecl *runtime_interface_decl = runtime_interface_type->getDecl();
+
+ FindObjCMethodDeclsWithOrigin(current_id,
+ context,
+ runtime_interface_decl,
+ m_ast_context,
+ m_ast_importer,
+ "in runtime");
}
+ while(0);
}
}
@@ -1055,41 +1130,89 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
if (!language_runtime)
return;
- lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
-
- if (!complete_type_sp)
- return;
-
- TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType(), complete_type_sp->GetClangAST());
- lldb::clang_type_t complete_opaque_type = complete_type.GetOpaqueQualType();
-
- if (!complete_opaque_type)
- return;
-
- const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
- const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type);
-
- if (!complete_interface_type)
- return;
-
- DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_type->getDecl());
-
- if (complete_iface_decl.decl == origin_iface_decl.decl)
- return; // already checked this one
-
- if (log)
- log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
- current_id,
- complete_iface_decl.decl,
- &complete_iface_decl->getASTContext());
-
+ do
+ {
+ // First see if any other debug information has this property/ivar.
+
+ lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
+
+ if (!complete_type_sp)
+ break;
+
+ TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType(), complete_type_sp->GetClangAST());
+ lldb::clang_type_t complete_opaque_type = complete_type.GetOpaqueQualType();
+
+ if (!complete_opaque_type)
+ break;
+
+ const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
+ const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type);
+
+ if (!complete_interface_type)
+ break;
+
+ DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_type->getDecl());
+
+ if (complete_iface_decl.decl == origin_iface_decl.decl)
+ break; // already checked this one
+
+ if (log)
+ log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id,
+ complete_iface_decl.decl,
+ &complete_iface_decl->getASTContext());
+
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
+ context,
+ *m_ast_context,
+ m_ast_importer,
+ complete_iface_decl))
+ return;
+ }
+ while(0);
- if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
- context,
- *m_ast_context,
- m_ast_importer,
- complete_iface_decl))
- return;
+ do
+ {
+ // Now check the runtime.
+
+ TypeVendor *type_vendor = language_runtime->GetTypeVendor();
+
+ if (!type_vendor)
+ break;
+
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector <ClangASTType> types;
+
+ if (!type_vendor->FindTypes(class_name,
+ append,
+ max_matches,
+ types))
+ break;
+
+ const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr();
+
+ const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type);
+
+ if (!runtime_interface_type)
+ break;
+
+ DeclFromUser<const ObjCInterfaceDecl> runtime_iface_decl(runtime_interface_type->getDecl());
+
+ if (log)
+ log->Printf("CAS::FOPD[%d] trying runtime (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+ current_id,
+ runtime_iface_decl.decl,
+ &runtime_iface_decl->getASTContext());
+
+ if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id,
+ context,
+ *m_ast_context,
+ m_ast_importer,
+ runtime_iface_decl))
+ return;
+ }
+ while(0);
}
typedef llvm::DenseMap <const FieldDecl *, uint64_t> FieldOffsetMap;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 7945270e18a..e2deca56eef 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -32,6 +32,7 @@
#include "lldb/Expression/ClangUtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -39,7 +40,7 @@
#include "lldb/Target/Thread.h"
#include "AppleObjCRuntimeV2.h"
-#include "AppleObjCSymbolVendor.h"
+#include "AppleObjCTypeVendor.h"
#include "AppleObjCTrampolineHandler.h"
#include <vector>
@@ -700,13 +701,13 @@ AppleObjCRuntimeV2::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
return descriptor->GetClassName();
}
-SymbolVendor *
-AppleObjCRuntimeV2::GetSymbolVendor()
+TypeVendor *
+AppleObjCRuntimeV2::GetTypeVendor()
{
- if (!m_symbol_vendor_ap.get())
- m_symbol_vendor_ap.reset(new AppleObjCSymbolVendor(m_process));
+ if (!m_type_vendor_ap.get())
+ m_type_vendor_ap.reset(new AppleObjCTypeVendor(*this));
- return m_symbol_vendor_ap.get();
+ return m_type_vendor_ap.get();
}
AppleObjCRuntimeV2::ClassDescriptorV2::ClassDescriptorV2 (ValueObject &isa_pointer)
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index ff94b81dfac..90179cafbf4 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -244,7 +244,7 @@ public:
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA = 1;
virtual ObjCLanguageRuntime::ObjCISA
- GetISA(ValueObject& valobj);
+ GetISA(ValueObject& valobj);
virtual ConstString
GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa);
@@ -255,8 +255,8 @@ public:
virtual ClassDescriptorSP
GetClassDescriptor (ObjCISA isa);
- virtual SymbolVendor *
- GetSymbolVendor();
+ virtual TypeVendor *
+ GetTypeVendor();
protected:
virtual lldb::BreakpointResolverSP
@@ -278,7 +278,7 @@ private:
lldb::addr_t m_get_class_name_args;
Mutex m_get_class_name_args_mutex;
- std::auto_ptr<SymbolVendor> m_symbol_vendor_ap;
+ std::auto_ptr<TypeVendor> m_type_vendor_ap;
static const char *g_find_class_name_function_name;
static const char *g_find_class_name_function_body;
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp
deleted file mode 100644
index fba909b8701..00000000000
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-//===-- AppleObjCSymbolVendor.cpp -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AppleObjCSymbolVendor.h"
-
-#include "lldb/Core/Log.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-
-#include "clang/AST/ASTContext.h"
-
-using namespace lldb_private;
-
-AppleObjCSymbolVendor::AppleObjCSymbolVendor(Process *process) :
- SymbolVendor(lldb::ModuleSP()),
- m_process(process->shared_from_this()),
- m_ast_ctx(process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str())
-{
-}
-
-uint32_t
-AppleObjCSymbolVendor::FindTypes (const SymbolContext& sc,
- const ConstString &name,
- const ClangNamespaceDecl *namespace_decl,
- bool append,
- uint32_t max_matches,
- TypeList& types)
-{
- lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS)); // FIXME - a more appropriate log channel?
-
- if (log)
- log->Printf("ObjC SymbolVendor asked for '%s'",
- name.AsCString());
-
- if (!append)
- types.Clear();
-
- uint32_t ret = 0;
-
- ModuleList &target_modules = m_process->GetTarget().GetImages();
- Mutex::Locker modules_locker(target_modules.GetMutex());
-
- for (size_t image_index = 0, end_index = target_modules.GetSize();
- image_index < end_index;
- ++image_index)
- {
- Module *image = target_modules.GetModulePointerAtIndexUnlocked(image_index);
-
- if (!image)
- continue;
-
- SymbolVendor *symbol_vendor = image->GetSymbolVendor();
-
- if (!symbol_vendor)
- continue;
-
- SymbolFile *symbol_file = image->GetSymbolVendor()->GetSymbolFile();
-
- // Don't use a symbol file if it actually has types. We are specifically
- // looking for something in runtime information, not from debug information,
- // as the data in debug information will get parsed by the debug info
- // symbol files. So we veto any symbol file that has actual variable
- // type parsing abilities.
- if (symbol_file == NULL || (symbol_file->GetAbilities() & SymbolFile::VariableTypes))
- continue;
-
- const bool inferior_append = true;
-
- ret += symbol_file->FindTypes (sc, name, namespace_decl, inferior_append, max_matches - ret, types);
-
- if (ret >= max_matches)
- break;
- }
-
- return ret;
-}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
new file mode 100644
index 00000000000..e14e2e6f508
--- /dev/null
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
@@ -0,0 +1,198 @@
+//===-- AppleObjCSymbolVendor.cpp -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AppleObjCTypeVendor.h"
+
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Expression/ASTDumper.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+
+using namespace lldb_private;
+
+class lldb_private::AppleObjCExternalASTSource : public ClangExternalASTSourceCommon
+{
+public:
+ AppleObjCExternalASTSource (AppleObjCTypeVendor &type_vendor) :
+ m_type_vendor(type_vendor)
+ {
+ }
+
+ clang::DeclContextLookupResult
+ FindExternalVisibleDeclsByName (const clang::DeclContext *DC,
+ clang::DeclarationName Name)
+ {
+ return clang::DeclContextLookupResult();
+ }
+
+ clang::ExternalLoadResult
+ FindExternalLexicalDecls (const clang::DeclContext *DC,
+ bool (*isKindWeWant)(clang::Decl::Kind),
+ llvm::SmallVectorImpl<clang::Decl*> &Decls)
+ {
+ return clang::ELR_Success;
+ }
+
+ void
+ CompleteType (clang::TagDecl *Tag)
+ {
+ return;
+ }
+
+ void
+ CompleteType (clang::ObjCInterfaceDecl *Class)
+ {
+ return;
+ }
+
+ bool
+ layoutRecordType(const clang::RecordDecl *Record,
+ uint64_t &Size,
+ uint64_t &Alignment,
+ llvm::DenseMap <const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets,
+ llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &VirtualBaseOffsets)
+ {
+ return false;
+ }
+
+ void StartTranslationUnit (clang::ASTConsumer *Consumer)
+ {
+ clang::TranslationUnitDecl *translation_unit_decl = m_type_vendor.m_ast_ctx.getASTContext()->getTranslationUnitDecl();
+ translation_unit_decl->setHasExternalVisibleStorage();
+ translation_unit_decl->setHasExternalLexicalStorage();
+ }
+private:
+ AppleObjCTypeVendor &m_type_vendor;
+};
+
+AppleObjCTypeVendor::AppleObjCTypeVendor(ObjCLanguageRuntime &runtime) :
+ TypeVendor(),
+ m_runtime(runtime),
+ m_ast_ctx(runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple().getTriple().c_str())
+{
+ m_external_source = new AppleObjCExternalASTSource (*this);
+ llvm::OwningPtr<clang::ExternalASTSource> external_source_owning_ptr (m_external_source);
+ m_ast_ctx.getASTContext()->setExternalSource(external_source_owning_ptr);
+}
+
+uint32_t
+AppleObjCTypeVendor::FindTypes (const ConstString &name,
+ bool append,
+ uint32_t max_matches,
+ std::vector <ClangASTType> &types)
+{
+ static unsigned int invocation_id = 0;
+ unsigned int current_id = invocation_id++;
+
+ lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
+
+ if (log)
+ log->Printf("AppleObjCTypeVendor::FindTypes [%u] ('%s', %s, %u, )",
+ current_id,
+ (const char*)name.AsCString(),
+ append ? "true" : "false",
+ max_matches);
+
+ if (!append)
+ types.clear();
+
+ uint32_t ret = 0;
+
+ do
+ {
+ // See if the type is already in our ASTContext.
+
+ clang::ASTContext *ast_ctx = m_ast_ctx.getASTContext();
+
+ clang::IdentifierInfo &identifier_info = ast_ctx->Idents.get(name.GetStringRef());
+ clang::DeclarationName decl_name = ast_ctx->DeclarationNames.getIdentifier(&identifier_info);
+
+ clang::DeclContext::lookup_const_result lookup_result = ast_ctx->getTranslationUnitDecl()->lookup(decl_name);
+
+ if (lookup_result.first != lookup_result.second)
+ {
+ if (const clang::ObjCInterfaceDecl *result_iface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(*lookup_result.first))
+ {
+ clang::QualType result_iface_type = ast_ctx->getObjCInterfaceType(result_iface_decl);
+
+ if (log)
+ {
+ ASTDumper dumper(result_iface_type);
+ log->Printf("AOCTV::FT [%u] Found %s (isa 0x%llx) in the ASTContext",
+ current_id,
+ dumper.GetCString(),
+ m_external_source->GetMetadata((uintptr_t)result_iface_decl));
+ }
+
+ types.push_back(ClangASTType(ast_ctx, result_iface_type.getAsOpaquePtr()));
+ ret++;
+ break;
+ }
+ else
+ {
+ if (log)
+ log->Printf("AOCTV::FT [%u] There's something in the ASTContext, but it's not something we know about",
+ current_id);
+ break;
+ }
+ }
+ else if(log)
+ {
+ log->Printf("AOCTV::FT [%u] Couldn't find %s in the ASTContext",
+ current_id,
+ name.AsCString());
+ }
+
+ // It's not. If it exists, we have to put it into our ASTContext.
+
+ // TODO Actually do this. But we have to search the class list first. Until then we'll just give up.
+ break;
+
+ ObjCLanguageRuntime::ObjCISA isa = m_runtime.GetISA(name);
+
+ if (!isa)
+ {
+ if (log)
+ log->Printf("AOCTV::FT [%u] Couldn't find the isa",
+ current_id);
+
+ break;
+ }
+
+ clang::ObjCInterfaceDecl *new_iface_decl = clang::ObjCInterfaceDecl::Create(*ast_ctx,
+ ast_ctx->getTranslationUnitDecl(),
+ clang::SourceLocation(),
+ &identifier_info,
+ NULL);
+
+ m_external_source->SetMetadata((uintptr_t)new_iface_decl, (uint64_t)isa);
+
+ new_iface_decl->setHasExternalVisibleStorage();
+
+ clang::QualType new_iface_type = ast_ctx->getObjCInterfaceType(new_iface_decl);
+
+ if (log)
+ {
+ ASTDumper dumper(new_iface_type);
+ log->Printf("AOCTV::FT [%u] Created %s (isa 0x%llx)",
+ current_id,
+ dumper.GetCString(),
+ (uint64_t)isa);
+ }
+ } while (0);
+
+ return ret;
+}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h
index b426de5cf76..e06011662a9 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h
@@ -16,30 +16,32 @@
#include <map>
// Other libraries and framework includes
+
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/SymbolVendor.h"
-#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/TypeVendor.h"
namespace lldb_private {
+
+class AppleObjCExternalASTSource;
-class AppleObjCSymbolVendor : public SymbolVendor
+class AppleObjCTypeVendor : public TypeVendor
{
public:
- AppleObjCSymbolVendor(Process* process);
+ AppleObjCTypeVendor(ObjCLanguageRuntime &runtime);
virtual uint32_t
- FindTypes (const SymbolContext& sc,
- const ConstString &name,
- const ClangNamespaceDecl *namespace_decl,
- bool append,
- uint32_t max_matches,
- TypeList& types);
+ FindTypes (const ConstString &name,
+ bool append,
+ uint32_t max_matches,
+ std::vector <ClangASTType> &types);
+ friend class AppleObjCExternalASTSource;
private:
- lldb::ProcessSP m_process;
- ClangASTContext m_ast_ctx;
+ ObjCLanguageRuntime &m_runtime;
+ ClangASTContext m_ast_ctx;
+ AppleObjCExternalASTSource *m_external_source;
};
} // namespace lldb_private
diff --git a/lldb/source/Target/ObjCLanguageRuntime.cpp b/lldb/source/Target/ObjCLanguageRuntime.cpp
index a404ce40c2d..df00c353c4a 100644
--- a/lldb/source/Target/ObjCLanguageRuntime.cpp
+++ b/lldb/source/Target/ObjCLanguageRuntime.cpp
@@ -281,6 +281,16 @@ ObjCLanguageRuntime::ClassDescriptor::IsPointerValid (lldb::addr_t value,
}
ObjCLanguageRuntime::ObjCISA
+ObjCLanguageRuntime::GetISA(const ConstString &name)
+{
+ for (const ISAToDescriptorMap::value_type &val : m_isa_to_descriptor_cache)
+ if (val.second && val.second->GetClassName() == name)
+ return val.first;
+
+ return 0;
+}
+
+ObjCLanguageRuntime::ObjCISA
ObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa)
{
if (!IsValidISA(isa))
OpenPOWER on IntegriCloud