diff options
13 files changed, 170 insertions, 78 deletions
diff --git a/lldb/include/lldb/Symbol/TypeVendor.h b/lldb/include/lldb/Symbol/TypeVendor.h index 4ae82fd9522..559b21eeb95 100644 --- a/lldb/include/lldb/Symbol/TypeVendor.h +++ b/lldb/include/lldb/Symbol/TypeVendor.h @@ -10,6 +10,8 @@ #ifndef liblldb_TypeVendor_h_ #define liblldb_TypeVendor_h_ +#include "lldb/Core/ClangForward.h" + namespace lldb_private { //---------------------------------------------------------------------- @@ -37,6 +39,9 @@ public: bool append, uint32_t max_matches, std::vector <ClangASTType> &types) = 0; + + virtual clang::ASTContext * + GetClangASTContext () = 0; protected: //------------------------------------------------------------------ diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index 0ce361cb54d..c6c4f72d5b6 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -2085,6 +2085,29 @@ SBTarget::FindFirstType (const char* typename_cstr) return SBType(type_sp); } } + + // Didn't find the type in the symbols; try the Objective-C runtime + // if one is installed + + ProcessSP process_sp(target_sp->GetProcessSP()); + + if (process_sp) + { + ObjCLanguageRuntime *objc_language_runtime = process_sp->GetObjCLanguageRuntime(); + + if (objc_language_runtime) + { + TypeVendor *objc_type_vendor = objc_language_runtime->GetTypeVendor(); + + if (objc_type_vendor) + { + std::vector <ClangASTType> types; + + if (objc_type_vendor->FindTypes(const_typename, true, 1, types) > 0) + return SBType(types[0]); + } + } + } // No matches, search for basic typename matches ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); @@ -2136,7 +2159,35 @@ SBTarget::FindTypes (const char* typename_cstr) sb_type_list.Append(SBType(type_sp)); } } - else + + // Try the Objective-C runtime if one is installed + + ProcessSP process_sp(target_sp->GetProcessSP()); + + if (process_sp) + { + ObjCLanguageRuntime *objc_language_runtime = process_sp->GetObjCLanguageRuntime(); + + if (objc_language_runtime) + { + TypeVendor *objc_type_vendor = objc_language_runtime->GetTypeVendor(); + + if (objc_type_vendor) + { + std::vector <ClangASTType> types; + + if (objc_type_vendor->FindTypes(const_typename, true, UINT32_MAX, types)) + { + for (ClangASTType &type : types) + { + sb_type_list.Append(SBType(type)); + } + } + } + } + } + + if (sb_type_list.GetSize() == 0) { // No matches, search for basic typename matches ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp index 2bce5090dca..8d8fa6e2e5a 100644 --- a/lldb/source/Expression/ClangASTSource.cpp +++ b/lldb/source/Expression/ClangASTSource.cpp @@ -681,7 +681,7 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, if (!copied_type) { if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export the type for a constant integer result", + log->Printf(" CAS::FEVD[%u] - Couldn't export a type", current_id); break; @@ -689,6 +689,63 @@ ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, context.AddTypeDecl(copied_type); } + else + { + do + { + // Couldn't find any types elsewhere. Try the Objective-C runtime if one exists. + + lldb::ProcessSP process(m_target->GetProcessSP()); + + if (!process) + break; + + ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); + + if (!language_runtime) + break; + + 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(name, + append, + max_matches, + types)) + break; + + if (log) + { + log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\" in the runtime", + current_id, + name.GetCString()); + } + + const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr(); + + clang::QualType runtime_qual_type(runtime_clang_type, 0); + + void *copied_type = GuardedCopyType(m_ast_context, type_vendor->GetClangASTContext(), runtime_qual_type.getAsOpaquePtr()); + + if (!copied_type) + { + if (log) + log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the runtime", + current_id); + + break; + } + + context.AddTypeDecl(copied_type); + } + while(0); + } } while(0); } @@ -1076,6 +1133,9 @@ ClangASTSource::FindObjCMethodDecls (NameSearchContext &context) ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); + if (!language_runtime) + break; + TypeVendor *type_vendor = language_runtime->GetTypeVendor(); if (!type_vendor) diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp index f81b75ec154..545a8cae624 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -9,6 +9,7 @@ #include "AppleObjCRuntimeV1.h" #include "AppleObjCTrampolineHandler.h" +#include "AppleObjCTypeVendor.h" #include "llvm/Support/MachO.h" #include "clang/AST/Type.h" @@ -294,6 +295,15 @@ AppleObjCRuntimeV1::ClassDescriptorV1::GetSuperclass () return ObjCLanguageRuntime::ClassDescriptorSP(new AppleObjCRuntimeV1::ClassDescriptorV1(m_parent_isa,process_sp)); } +bool +AppleObjCRuntimeV1::ClassDescriptorV1::Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func, + std::function <bool (const char *, const char *)> const &instance_method_func, + std::function <bool (const char *, const char *)> const &class_method_func, + std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func) +{ + return false; +} + lldb::addr_t AppleObjCRuntimeV1::GetISAHashTablePointer () { @@ -454,3 +464,11 @@ AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded() } } +TypeVendor * +AppleObjCRuntimeV1::GetTypeVendor() +{ + if (!m_type_vendor_ap.get()) + m_type_vendor_ap.reset(new AppleObjCTypeVendor(*this)); + + return m_type_vendor_ap.get(); +} diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h index faaf5788628..0de135d1874 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h @@ -64,6 +64,12 @@ public: return m_isa; } + virtual bool + Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func, + std::function <bool (const char *, const char *)> const &instance_method_func, + std::function <bool (const char *, const char *)> const &class_method_func, + std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func); + virtual ~ClassDescriptorV1 () {} @@ -125,6 +131,9 @@ public: virtual void UpdateISAToDescriptorMapIfNeeded(); + + virtual TypeVendor * + GetTypeVendor(); protected: virtual lldb::BreakpointResolverSP @@ -173,6 +182,7 @@ protected: HashTableSignature m_hash_signature; lldb::addr_t m_isa_hash_table_ptr; + std::auto_ptr<TypeVendor> m_type_vendor_ap; private: AppleObjCRuntimeV1(Process *process); }; diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp index 4e573302aa9..19c99632baa 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp @@ -126,6 +126,8 @@ public: ASTDumper dumper((clang::Decl*)interface_decl); dumper.ToLog(log, " [CT] "); } + + m_type_vendor.FinishDecl(interface_decl); if (log) { @@ -197,6 +199,7 @@ AppleObjCTypeVendor::GetDeclForISA(ObjCLanguageRuntime::ObjCISA isa) m_external_source->SetMetadata((uintptr_t)new_iface_decl, meta_data); new_iface_decl->setHasExternalVisibleStorage(); + new_iface_decl->setHasExternalLexicalStorage(); ast_ctx->getTranslationUnitDecl()->addDecl(new_iface_decl); @@ -508,6 +511,7 @@ AppleObjCTypeVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) interface_decl->startDefinition(); interface_decl->setHasExternalVisibleStorage(false); + interface_decl->setHasExternalLexicalStorage(false); ObjCLanguageRuntime::ClassDescriptorSP descriptor = m_runtime.GetClassDescriptor(objc_isa); diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h index bb1dc30832d..5a24f397ac2 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h @@ -38,6 +38,12 @@ public: uint32_t max_matches, std::vector <ClangASTType> &types); + virtual clang::ASTContext * + GetClangASTContext () + { + return m_ast_ctx.getASTContext(); + } + friend class AppleObjCExternalASTSource; private: clang::ObjCInterfaceDecl *GetDeclForISA(ObjCLanguageRuntime::ObjCISA isa); diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index 5c74dd7686b..87e40daec6f 100644 --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -381,66 +381,8 @@ SymbolFileSymtab::FindTypes (const lldb_private::SymbolContext& sc, uint32_t max_matches, lldb_private::TypeList& types) { - if (!append) - types.Clear(); - - if (!m_objc_class_name_to_index.IsEmpty()) - { - TypeMap::iterator iter = m_objc_class_types.find(name); - - if (iter != m_objc_class_types.end()) - { - types.Insert(iter->second); - return 1; - } - - const Symtab::NameToIndexMap::Entry *match = m_objc_class_name_to_index.FindFirstValueForName(name.GetCString()); - - if (match == NULL) - return 0; - - const bool isForwardDecl = false; - const bool isInternal = true; - - ClangASTContext &ast = GetClangASTContext(); - - ClangASTMetadata metadata; - metadata.SetUserID(0xffaaffaaffaaffaall); - lldb::clang_type_t objc_object_type = ast.CreateObjCClass (name.AsCString(), - ast.GetTranslationUnitDecl(), - isForwardDecl, - isInternal, - &metadata); - - Declaration decl; - - lldb::TypeSP type(new Type (match->value, - this, - name, - 0, // byte_size - don't change this from 0, we currently use that to identify these "synthetic" ObjC class types. - NULL, // SymbolContextScope* - 0, // encoding_uid - Type::eEncodingInvalid, - decl, - objc_object_type, - Type::eResolveStateFull)); - - m_objc_class_types[name] = type; - - types.Insert(type); - - return 1; - } - return 0; } -// -//uint32_t -//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) -//{ -// return 0; -//} - //------------------------------------------------------------------ // PluginInterface protocol diff --git a/lldb/source/Target/ObjCLanguageRuntime.cpp b/lldb/source/Target/ObjCLanguageRuntime.cpp index 2b37cb06c22..fa80e0951e9 100644 --- a/lldb/source/Target/ObjCLanguageRuntime.cpp +++ b/lldb/source/Target/ObjCLanguageRuntime.cpp @@ -105,9 +105,7 @@ ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name) types); if (num_types) - { - TypeSP incomplete_type_sp; - + { uint32_t i; for (i = 0; i < num_types; ++i) { @@ -120,8 +118,6 @@ ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name) m_complete_class_cache[name] = type_sp; return type_sp; } - else if (!incomplete_type_sp) - incomplete_type_sp = type_sp; } } } diff --git a/lldb/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py b/lldb/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py index ed389618867..0a85da7b529 100644 --- a/lldb/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py +++ b/lldb/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py @@ -59,23 +59,23 @@ class DataFormatterRdar11988289TestCase(TestBase): # Now check that we are displaying Cocoa classes correctly self.expect('frame variable dictionary', substrs = ['3 key/value pairs']) - self.expect('frame variable mutable', + self.expect('frame variable mutabledict', substrs = ['4 key/value pairs']) self.expect('frame variable dictionary --ptr-depth 1', substrs = ['3 key/value pairs','[0] = {','key = 0x','value = 0x','[1] = {','[2] = {']) - self.expect('frame variable mutable --ptr-depth 1', + self.expect('frame variable mutabledict --ptr-depth 1', substrs = ['4 key/value pairs','[0] = {','key = 0x','value = 0x','[1] = {','[2] = {','[3] = {']) self.expect('frame variable dictionary --ptr-depth 1 --dynamic-type no-run-target', substrs = ['3 key/value pairs','@"bar"','@"2 objects"','@"baz"','2 key/value pairs']) - self.expect('frame variable mutable --ptr-depth 1 --dynamic-type no-run-target', + self.expect('frame variable mutabledict --ptr-depth 1 --dynamic-type no-run-target', substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"puartist"','3 key/value pairs']) - self.expect('frame variable mutable --ptr-depth 2 --dynamic-type no-run-target', + self.expect('frame variable mutabledict --ptr-depth 2 --dynamic-type no-run-target', substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"puartist"','3 key/value pairs {','@"bar"','@"2 objects"']) - self.expect('frame variable mutable --ptr-depth 3 --dynamic-type no-run-target', + self.expect('frame variable mutabledict --ptr-depth 3 --dynamic-type no-run-target', substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"puartist"','3 key/value pairs {','@"bar"','@"2 objects"','(int)1','@"two"']) self.assertTrue(self.frame().FindVariable("dictionary").MightHaveChildren(), "dictionary says it does not have children!") - self.assertTrue(self.frame().FindVariable("mutable").MightHaveChildren(), "mutable says it does not have children!") + self.assertTrue(self.frame().FindVariable("mutabledict").MightHaveChildren(), "mutable says it does not have children!") if __name__ == '__main__': diff --git a/lldb/test/functionalities/data-formatter/rdar-11988289/main.m b/lldb/test/functionalities/data-formatter/rdar-11988289/main.m index c1ab2e4018a..62eed942d29 100644 --- a/lldb/test/functionalities/data-formatter/rdar-11988289/main.m +++ b/lldb/test/functionalities/data-formatter/rdar-11988289/main.m @@ -18,11 +18,11 @@ int main (int argc, const char * argv[]) NSArray* keys = @[@"foo",@"bar",@"baz"]; NSArray* values = @[@"hello",@[@"X",@"Y"],@{@1 : @"one",@2 : @"two"}]; NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys]; - NSMutableDictionary* mutable = [NSMutableDictionary dictionaryWithCapacity:5]; - [mutable setObject:@"123" forKey:@23]; - [mutable setObject:[NSURL URLWithString:@"http://www.apple.com"] forKey:@"foobar"]; - [mutable setObject:@[@"a",@12] forKey:@57]; - [mutable setObject:dictionary forKey:@"puartist"]; + NSMutableDictionary* mutabledict = [NSMutableDictionary dictionaryWithCapacity:5]; + [mutabledict setObject:@"123" forKey:@23]; + [mutabledict setObject:[NSURL URLWithString:@"http://www.apple.com"] forKey:@"foobar"]; + [mutabledict setObject:@[@"a",@12] forKey:@57]; + [mutabledict setObject:dictionary forKey:@"puartist"]; [pool drain];// Set break point at this line. return 0; diff --git a/lldb/test/lang/objc/foundation/TestObjCMethods2.py b/lldb/test/lang/objc/foundation/TestObjCMethods2.py index 861d9fcab35..7b899aa433c 100644 --- a/lldb/test/lang/objc/foundation/TestObjCMethods2.py +++ b/lldb/test/lang/objc/foundation/TestObjCMethods2.py @@ -230,7 +230,7 @@ class FoundationTestCase2(TestBase): self.runCmd("run", RUN_SUCCEEDED) - self.expect("p [NSError errorWithDomain:@\"Hello\" code:35 userInfo:nil]", + self.expect("p [NSError thisMethodIsntImplemented:0]", error = True, patterns = ["no known method", "cast the message send to the method's return type"]) self.runCmd("process continue") diff --git a/lldb/test/python_api/type/TestTypeList.py b/lldb/test/python_api/type/TestTypeList.py index 05643e675cc..d0e4dd6c449 100644 --- a/lldb/test/python_api/type/TestTypeList.py +++ b/lldb/test/python_api/type/TestTypeList.py @@ -66,7 +66,7 @@ class TypeAndTypeListTestCase(TestBase): type_list = target.FindTypes('Task') if self.TraceOn(): print "Size of type_list from target.FindTypes('Task') query: %d" % type_list.GetSize() - self.assertTrue(len(type_list) == 1) + self.assertTrue(len(type_list) >= 1) # a second Task make be scared up by the Objective-C runtime for type in type_list: self.assertTrue(type) self.DebugSBType(type) |

