summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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