19b8ff51183563d68818795caef3174d4fc2c2c1dGreg Clayton//===-- ObjCLanguageRuntime.cpp ---------------------------------*- C++ -*-===// 2642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// 3642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// The LLVM Compiler Infrastructure 4642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// 5642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// This file is distributed under the University of Illinois Open Source 6642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// License. See LICENSE.TXT for details. 7642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// 8642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//===----------------------------------------------------------------------===// 9324067bc91877dbbd6ec3a8663914fa3dbb7e3c9Jim Ingham#include "clang/AST/Type.h" 10642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham 11b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Core/Log.h" 12ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#include "lldb/Core/MappedHash.h" 1349ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Core/Module.h" 14642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include "lldb/Core/PluginManager.h" 15f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton#include "lldb/Core/Timer.h" 16324067bc91877dbbd6ec3a8663914fa3dbb7e3c9Jim Ingham#include "lldb/Core/ValueObject.h" 17324067bc91877dbbd6ec3a8663914fa3dbb7e3c9Jim Ingham#include "lldb/Symbol/ClangASTContext.h" 18ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham#include "lldb/Symbol/Type.h" 1949ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Symbol/TypeList.h" 20b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Target/ObjCLanguageRuntime.h" 21931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan#include "lldb/Target/Target.h" 22642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham 23f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton#include "llvm/ADT/StringRef.h" 24f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton 25642036f22366d47ea8e6f8498bedb92b88f7f79fJim Inghamusing namespace lldb; 26642036f22366d47ea8e6f8498bedb92b88f7f79fJim Inghamusing namespace lldb_private; 27642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham 28642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//---------------------------------------------------------------------- 29642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// Destructor 30642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//---------------------------------------------------------------------- 31642036f22366d47ea8e6f8498bedb92b88f7f79fJim InghamObjCLanguageRuntime::~ObjCLanguageRuntime() 32642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham{ 33642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham} 34642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham 35642036f22366d47ea8e6f8498bedb92b88f7f79fJim InghamObjCLanguageRuntime::ObjCLanguageRuntime (Process *process) : 366e12c7a5a851f661677b16c544aac2f93fb6e86dSean Callanan LanguageRuntime (process), 376fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan m_has_new_literals_and_indexing (eLazyBoolCalculate), 38ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton m_isa_to_descriptor(), 39ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton m_isa_to_descriptor_stop_id (UINT32_MAX) 40642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham{ 41642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham 42b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham} 43b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham 44ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonbool 45ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg ClaytonObjCLanguageRuntime::AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name) 46ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{ 47ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton if (isa != 0) 48ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton { 49ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton m_isa_to_descriptor[isa] = descriptor_sp; 50ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton // class_name is assumed to be valid 51ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton m_hash_to_isa_map.insert(std::make_pair(MappedHash::HashStringUsingDJB(class_name), isa)); 52ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton return true; 53ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton } 54ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton return false; 55ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton} 56ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton 57b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Inghamvoid 58b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim InghamObjCLanguageRuntime::AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t selector, lldb::addr_t impl_addr) 59b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham{ 60952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 61b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham if (log) 62b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham { 635f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf ("Caching: class 0x%" PRIx64 " selector 0x%" PRIx64 " implementation 0x%" PRIx64 ".", class_addr, selector, impl_addr); 64b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham } 65b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham m_impl_cache.insert (std::pair<ClassAndSel,lldb::addr_t> (ClassAndSel(class_addr, selector), impl_addr)); 66b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham} 67b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham 68b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Inghamlldb::addr_t 69b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim InghamObjCLanguageRuntime::LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t selector) 70b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham{ 71b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham MsgImplMap::iterator pos, end = m_impl_cache.end(); 72b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham pos = m_impl_cache.find (ClassAndSel(class_addr, selector)); 73b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham if (pos != end) 74b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham return (*pos).second; 75b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham return LLDB_INVALID_ADDRESS; 76b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham} 77ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham 7858513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham 79931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callananlldb::TypeSP 80931acecd4e3af534028936431dc0f75a9fd6eb02Sean CallananObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name) 81931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan{ 82931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan CompleteClassMap::iterator complete_class_iter = m_complete_class_cache.find(name); 83931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan 84931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan if (complete_class_iter != m_complete_class_cache.end()) 85931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan { 86ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton // Check the weak pointer to make sure the type hasn't been unloaded 87ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton TypeSP complete_type_sp (complete_class_iter->second.lock()); 88931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan 89ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton if (complete_type_sp) 90ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton return complete_type_sp; 91931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan else 92ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton m_complete_class_cache.erase(name); 93931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan } 94931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan 9512fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata if (m_negative_complete_class_cache.count(name) > 0) 9612fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata return TypeSP(); 9712fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata 98146d9522c95c0c8c5409539813b55e08b99196eeEnrico Granata const ModuleList &modules = m_process->GetTarget().GetImages(); 99ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton 100931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan SymbolContextList sc_list; 101ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton const size_t matching_symbols = modules.FindSymbolsWithNameAndType (name, 102ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton eSymbolTypeObjCClass, 103ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton sc_list); 104931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan 105ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton if (matching_symbols) 106931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan { 107ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton SymbolContext sc; 108931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan 109ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton sc_list.GetContextAtIndex(0, sc); 110ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton 111ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton ModuleSP module_sp(sc.module_sp); 112ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton 113ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton if (!module_sp) 114931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan return TypeSP(); 115931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan 116ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton const SymbolContext null_sc; 117ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton const bool exact_match = true; 118ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton const uint32_t max_matches = UINT32_MAX; 119ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton TypeList types; 120ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton 121ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton const uint32_t num_types = module_sp->FindTypes (null_sc, 122ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton name, 123ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton exact_match, 124ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton max_matches, 125ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton types); 126ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton 127ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton if (num_types) 128282c22c6a6b6e54324b0d474b90d918bbfd3a10eSean Callanan { 129ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton uint32_t i; 130ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton for (i = 0; i < num_types; ++i) 131ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton { 132ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton TypeSP type_sp (types.GetTypeAtIndex(i)); 133ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton 13452f792329be5db8e38961350589e97e8f2823acdGreg Clayton if (type_sp->GetClangForwardType().IsObjCObjectOrInterfaceType()) 135ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton { 136ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton if (type_sp->IsCompleteObjCClass()) 137ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton { 138ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton m_complete_class_cache[name] = type_sp; 139ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton return type_sp; 140ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton } 141ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton } 142ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton } 143931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan } 144931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan } 14512fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata m_negative_complete_class_cache.insert(name); 146931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan return TypeSP(); 147931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan} 148931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan 14958513667f6765aa8db13cdc4abd500340c1cac80Jim Inghamsize_t 15058513667f6765aa8db13cdc4abd500340c1cac80Jim InghamObjCLanguageRuntime::GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name) 15158513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham{ 15258513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham return LLDB_INVALID_IVAR_OFFSET; 15358513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham} 15458513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham 155f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonvoid 156f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::Clear() 157f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{ 158f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_full.Clear(); 159f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_class.Clear(); 160f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_category.Clear(); 161f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_selector.Clear(); 162f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_type = eTypeUnspecified; 163f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_category_is_valid = false; 164f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton} 165f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton 166f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//bool 167f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//ObjCLanguageRuntime::MethodName::SetName (const char *name, bool strict) 168f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//{ 169f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// Clear(); 170f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// if (name && name[0]) 171f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// { 172f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// // If "strict" is true. then the method must be specified with a 173f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// // '+' or '-' at the beginning. If "strict" is false, then the '+' 174f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// // or '-' can be omitted 175f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// bool valid_prefix = false; 176f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// 177f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// if (name[0] == '+' || name[0] == '-') 178f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// { 179f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// valid_prefix = name[1] == '['; 180f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// } 181f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// else if (!strict) 182f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// { 183f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// // "strict" is false, the name just needs to start with '[' 184f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// valid_prefix = name[0] == '['; 185f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// } 186f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// 187f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// if (valid_prefix) 188f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// { 189f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// static RegularExpression g_regex("^([-+]?)\\[([A-Za-z_][A-Za-z_0-9]*)(\\([A-Za-z_][A-Za-z_0-9]*\\))? ([A-Za-z_][A-Za-z_0-9:]*)\\]$"); 190f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// llvm::StringRef matches[4]; 191f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// // Since we are using a global regular expression, we must use the threadsafe version of execute 192f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// if (g_regex.ExecuteThreadSafe(name, matches, 4)) 193f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// { 194f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// m_full.SetCString(name); 195f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// if (matches[0].empty()) 196f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// m_type = eTypeUnspecified; 197f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// else if (matches[0][0] == '+') 198f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// m_type = eTypeClassMethod; 199f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// else 200f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// m_type = eTypeInstanceMethod; 201f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// m_class.SetString(matches[1]); 202f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// m_selector.SetString(matches[3]); 203f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// if (!matches[2].empty()) 204f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// m_category.SetString(matches[2]); 205f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// } 206f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// } 207f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// } 208f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton// return IsValid(strict); 209f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//} 2103ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham 211f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonbool 212f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::SetName (const char *name, bool strict) 2133ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham{ 214f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton Clear(); 215f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (name && name[0]) 216f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 217f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // If "strict" is true. then the method must be specified with a 218f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // '+' or '-' at the beginning. If "strict" is false, then the '+' 219f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // or '-' can be omitted 220f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton bool valid_prefix = false; 221f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton 222f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (name[0] == '+' || name[0] == '-') 223f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 224f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton valid_prefix = name[1] == '['; 225f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (name[0] == '+') 226f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_type = eTypeClassMethod; 227f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton else 228f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_type = eTypeInstanceMethod; 229f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 230f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton else if (!strict) 231f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 232f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // "strict" is false, the name just needs to start with '[' 233f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton valid_prefix = name[0] == '['; 234f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 235f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton 236f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (valid_prefix) 237f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 238f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton int name_len = strlen (name); 239f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // Objective C methods must have at least: 240f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // "-[" or "+[" prefix 241f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // One character for a class name 242f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // One character for the space between the class name 243f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // One character for the method name 244f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // "]" suffix 245f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (name_len >= (5 + (strict ? 1 : 0)) && name[name_len - 1] == ']') 246f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 247f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_full.SetCStringWithLength(name, name_len); 248f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 249f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 250f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 251f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton return IsValid(strict); 252f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton} 253662e56733faaeee932eba120d756257682f1bf04Greg Clayton 254f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonconst ConstString & 255f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::GetClassName () 256f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{ 257f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (!m_class) 2583ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham { 259f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (IsValid(false)) 2603ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham { 261f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *full = m_full.GetCString(); 262f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *class_start = (full[0] == '[' ? full + 1 : full + 2); 263f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *paren_pos = strchr (class_start, '('); 264f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (paren_pos) 2653ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham { 266f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_class.SetCStringWithLength (class_start, paren_pos - class_start); 267f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 268f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton else 269f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 270f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // No '(' was found in the full name, we can definitively say 271f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // that our category was valid (and empty). 272f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_category_is_valid = true; 273f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *space_pos = strchr (full, ' '); 274f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (space_pos) 2753ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham { 276f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_class.SetCStringWithLength (class_start, space_pos - class_start); 277f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (!m_class_category) 2783ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham { 279f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // No category in name, so we can also fill in the m_class_category 280f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_class_category = m_class; 2813ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham } 2823ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham } 2833ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham } 2843ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham } 2853ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham } 286f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton return m_class; 287f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton} 288f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton 289f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonconst ConstString & 290f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::GetClassNameWithCategory () 291f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{ 292f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (!m_class_category) 293f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 294f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (IsValid(false)) 295f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 296f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *full = m_full.GetCString(); 297f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *class_start = (full[0] == '[' ? full + 1 : full + 2); 298f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *space_pos = strchr (full, ' '); 299f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (space_pos) 300f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 301f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_class_category.SetCStringWithLength (class_start, space_pos - class_start); 302f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // If m_class hasn't been filled in and the class with category doesn't 303f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // contain a '(', then we can also fill in the m_class 304f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (!m_class && strchr (m_class_category.GetCString(), '(') == NULL) 305f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 306f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_class = m_class_category; 307f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // No '(' was found in the full name, we can definitively say 308f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // that our category was valid (and empty). 309f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_category_is_valid = true; 310f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton 311f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 312f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 313f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 314f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 315f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton return m_class_category; 316f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton} 317f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton 318f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonconst ConstString & 319f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::GetSelector () 320f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{ 321f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (!m_selector) 322f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 323f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (IsValid(false)) 324f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 325f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *full = m_full.GetCString(); 326f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *space_pos = strchr (full, ' '); 327f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (space_pos) 328f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 329f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton ++space_pos; // skip the space 330f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_selector.SetCStringWithLength (space_pos, m_full.GetLength() - (space_pos - full) - 1); 331f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 332f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 333f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 334f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton return m_selector; 335f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton} 336f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton 337f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonconst ConstString & 338f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::GetCategory () 339f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{ 340f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (!m_category_is_valid && !m_category) 341f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 342f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (IsValid(false)) 343f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 344f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_category_is_valid = true; 345f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *full = m_full.GetCString(); 346f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *class_start = (full[0] == '[' ? full + 1 : full + 2); 347f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *open_paren_pos = strchr (class_start, '('); 348f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (open_paren_pos) 349f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 350f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton ++open_paren_pos; // Skip the open paren 351f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const char *close_paren_pos = strchr (open_paren_pos, ')'); 352f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (close_paren_pos) 353f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton m_category.SetCStringWithLength (open_paren_pos, close_paren_pos - open_paren_pos); 354f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 355f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 356f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 357f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton return m_category; 358f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton} 359f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton 360f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonConstString 361f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::GetFullNameWithoutCategory (bool empty_if_no_category) 362f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{ 363f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (IsValid(false)) 364f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 365f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (HasCategory()) 366f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 367f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton StreamString strm; 368f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (m_type == eTypeClassMethod) 369f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton strm.PutChar('+'); 370f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton else if (m_type == eTypeInstanceMethod) 371f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton strm.PutChar('-'); 372f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton strm.Printf("[%s %s]", GetClassName().GetCString(), GetSelector().GetCString()); 373f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton return ConstString(strm.GetString().c_str()); 374f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 375f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton 376f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (!empty_if_no_category) 377f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 378f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton // Just return the full name since it doesn't have a category 379f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton return GetFullName(); 380f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 381f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 382f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton return ConstString(); 383f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton} 384f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton 385f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonsize_t 386f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::GetFullNames (std::vector<ConstString> &names, bool append) 387f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{ 388f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (!append) 389f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton names.clear(); 390f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (IsValid(false)) 391f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 392f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton StreamString strm; 393f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const bool is_class_method = m_type == eTypeClassMethod; 394f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const bool is_instance_method = m_type == eTypeInstanceMethod; 395f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const ConstString &category = GetCategory(); 396f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (is_class_method || is_instance_method) 397f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 398f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton names.push_back (m_full); 399f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (category) 400f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 401f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton strm.Printf("%c[%s %s]", 402f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton is_class_method ? '+' : '-', 403f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton GetClassName().GetCString(), 404f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton GetSelector().GetCString()); 405f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton names.push_back(ConstString(strm.GetString().c_str())); 406f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 407f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 408f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton else 409f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 410f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const ConstString &class_name = GetClassName(); 411f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton const ConstString &selector = GetSelector(); 412f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton strm.Printf("+[%s %s]", class_name.GetCString(), selector.GetCString()); 413f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton names.push_back(ConstString(strm.GetString().c_str())); 414f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton strm.Clear(); 415f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString()); 416f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton names.push_back(ConstString(strm.GetString().c_str())); 417f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton strm.Clear(); 418f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton if (category) 419f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton { 420f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton strm.Printf("+[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString()); 421f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton names.push_back(ConstString(strm.GetString().c_str())); 422f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton strm.Clear(); 423f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton strm.Printf("-[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString()); 424f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton names.push_back(ConstString(strm.GetString().c_str())); 425f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 426f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 427f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton } 428f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton return names.size(); 4293ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham} 430ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata 431f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton 432ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granatabool 433ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico GranataObjCLanguageRuntime::ClassDescriptor::IsPointerValid (lldb::addr_t value, 434ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata uint32_t ptr_size, 435ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata bool allow_NULLs, 436ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata bool allow_tagged, 437be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton bool check_version_specific) const 438ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata{ 439ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata if (!value) 440ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata return allow_NULLs; 441ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata if ( (value % 2) == 1 && allow_tagged) 442ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata return true; 443ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata if ((value % ptr_size) == 0) 444ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata return (check_version_specific ? CheckPointer(value,ptr_size) : true); 445ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata else 446ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata return false; 447ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata} 448ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata 449ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico GranataObjCLanguageRuntime::ObjCISA 450c718b9652bb1a7aea5d133123fcc8bc87277002cSean CallananObjCLanguageRuntime::GetISA(const ConstString &name) 451c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan{ 452ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton ISAToDescriptorIterator pos = GetDescriptorIterator (name); 453ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton if (pos != m_isa_to_descriptor.end()) 454ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton return pos->first; 455c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan return 0; 456c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan} 457c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan 458ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg ClaytonObjCLanguageRuntime::ISAToDescriptorIterator 459ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg ClaytonObjCLanguageRuntime::GetDescriptorIterator (const ConstString &name) 460ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{ 461ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton ISAToDescriptorIterator end = m_isa_to_descriptor.end(); 462ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton 463ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton if (name) 464ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton { 465ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton UpdateISAToDescriptorMap(); 466ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton if (m_hash_to_isa_map.empty()) 467ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton { 468ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton // No name hashes were provided, we need to just linearly power through the 469ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton // names and find a match 470ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton for (ISAToDescriptorIterator pos = m_isa_to_descriptor.begin(); pos != end; ++pos) 471ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton { 472ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton if (pos->second->GetClassName() == name) 473ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton return pos; 474ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton } 475ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton } 476ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton else 477ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton { 478ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton // Name hashes were provided, so use them to efficiently lookup name to isa/descriptor 479ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton const uint32_t name_hash = MappedHash::HashStringUsingDJB (name.GetCString()); 480ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton std::pair <HashToISAIterator, HashToISAIterator> range = m_hash_to_isa_map.equal_range(name_hash); 481ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton for (HashToISAIterator range_pos = range.first; range_pos != range.second; ++range_pos) 482ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton { 483ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton ISAToDescriptorIterator pos = m_isa_to_descriptor.find (range_pos->second); 484ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton if (pos != m_isa_to_descriptor.end()) 485ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton { 486ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton if (pos->second->GetClassName() == name) 487ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton return pos; 488ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton } 489ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton } 490ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton } 491ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton } 492ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton return end; 493ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton} 494ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton 495ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton 496c718b9652bb1a7aea5d133123fcc8bc87277002cSean CallananObjCLanguageRuntime::ObjCISA 497ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico GranataObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa) 498ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata{ 499d387b462eecb908af265ecc7006781b4532073adGreg Clayton ClassDescriptorSP objc_class_sp (GetClassDescriptorFromISA(isa)); 500be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton if (objc_class_sp) 501ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata { 502be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton ClassDescriptorSP objc_super_class_sp (objc_class_sp->GetSuperclass()); 503be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton if (objc_super_class_sp) 504be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton return objc_super_class_sp->GetISA(); 505ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata } 506be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton return 0; 507ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata} 508ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata 509ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico GranataConstString 510ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico GranataObjCLanguageRuntime::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa) 511ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata{ 512be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton ClassDescriptorSP objc_class_sp (GetNonKVOClassDescriptor(isa)); 513be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton if (objc_class_sp) 514be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton return objc_class_sp->GetClassName(); 515be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton return ConstString(); 516be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton} 517be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton 518be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg ClaytonObjCLanguageRuntime::ClassDescriptorSP 519d387b462eecb908af265ecc7006781b4532073adGreg ClaytonObjCLanguageRuntime::GetClassDescriptorFromClassName (const ConstString &class_name) 520be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton{ 521ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton ISAToDescriptorIterator pos = GetDescriptorIterator (class_name); 522ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton if (pos != m_isa_to_descriptor.end()) 523ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton return pos->second; 524be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton return ClassDescriptorSP(); 525a510437e795477e5f629263d3d191d982c991733Greg Clayton 526be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton} 527be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton 528be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg ClaytonObjCLanguageRuntime::ClassDescriptorSP 529a510437e795477e5f629263d3d191d982c991733Greg ClaytonObjCLanguageRuntime::GetClassDescriptor (ValueObject& valobj) 530be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton{ 531be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton ClassDescriptorSP objc_class_sp; 532a510437e795477e5f629263d3d191d982c991733Greg Clayton // if we get an invalid VO (which might still happen when playing around 533a510437e795477e5f629263d3d191d982c991733Greg Clayton // with pointers returned by the expression parser, don't consider this 534a510437e795477e5f629263d3d191d982c991733Greg Clayton // a valid ObjC object) 53552f792329be5db8e38961350589e97e8f2823acdGreg Clayton if (valobj.GetClangType().IsValid()) 536be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton { 537a510437e795477e5f629263d3d191d982c991733Greg Clayton addr_t isa_pointer = valobj.GetPointerValue(); 538a510437e795477e5f629263d3d191d982c991733Greg Clayton if (isa_pointer != LLDB_INVALID_ADDRESS) 539a510437e795477e5f629263d3d191d982c991733Greg Clayton { 540a510437e795477e5f629263d3d191d982c991733Greg Clayton ExecutionContext exe_ctx (valobj.GetExecutionContextRef()); 541a510437e795477e5f629263d3d191d982c991733Greg Clayton 542a510437e795477e5f629263d3d191d982c991733Greg Clayton Process *process = exe_ctx.GetProcessPtr(); 543a510437e795477e5f629263d3d191d982c991733Greg Clayton if (process) 544a510437e795477e5f629263d3d191d982c991733Greg Clayton { 545a510437e795477e5f629263d3d191d982c991733Greg Clayton Error error; 546a510437e795477e5f629263d3d191d982c991733Greg Clayton ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error); 547a510437e795477e5f629263d3d191d982c991733Greg Clayton if (isa != LLDB_INVALID_ADDRESS) 548d387b462eecb908af265ecc7006781b4532073adGreg Clayton objc_class_sp = GetClassDescriptorFromISA (isa); 549a510437e795477e5f629263d3d191d982c991733Greg Clayton } 550a510437e795477e5f629263d3d191d982c991733Greg Clayton } 551be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton } 552be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton return objc_class_sp; 553be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton} 554be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton 555be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg ClaytonObjCLanguageRuntime::ClassDescriptorSP 556a510437e795477e5f629263d3d191d982c991733Greg ClaytonObjCLanguageRuntime::GetNonKVOClassDescriptor (ValueObject& valobj) 557a510437e795477e5f629263d3d191d982c991733Greg Clayton{ 558a510437e795477e5f629263d3d191d982c991733Greg Clayton ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (GetClassDescriptor (valobj)); 559a510437e795477e5f629263d3d191d982c991733Greg Clayton if (objc_class_sp) 560a510437e795477e5f629263d3d191d982c991733Greg Clayton { 561a510437e795477e5f629263d3d191d982c991733Greg Clayton if (!objc_class_sp->IsKVO()) 562a510437e795477e5f629263d3d191d982c991733Greg Clayton return objc_class_sp; 563a510437e795477e5f629263d3d191d982c991733Greg Clayton 564a510437e795477e5f629263d3d191d982c991733Greg Clayton ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass()); 565a510437e795477e5f629263d3d191d982c991733Greg Clayton if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid()) 566a510437e795477e5f629263d3d191d982c991733Greg Clayton return non_kvo_objc_class_sp; 567a510437e795477e5f629263d3d191d982c991733Greg Clayton } 568a510437e795477e5f629263d3d191d982c991733Greg Clayton return ClassDescriptorSP(); 569a510437e795477e5f629263d3d191d982c991733Greg Clayton} 570a510437e795477e5f629263d3d191d982c991733Greg Clayton 571a510437e795477e5f629263d3d191d982c991733Greg Clayton 572a510437e795477e5f629263d3d191d982c991733Greg ClaytonObjCLanguageRuntime::ClassDescriptorSP 573d387b462eecb908af265ecc7006781b4532073adGreg ClaytonObjCLanguageRuntime::GetClassDescriptorFromISA (ObjCISA isa) 574a510437e795477e5f629263d3d191d982c991733Greg Clayton{ 575a510437e795477e5f629263d3d191d982c991733Greg Clayton if (isa) 576a510437e795477e5f629263d3d191d982c991733Greg Clayton { 577a510437e795477e5f629263d3d191d982c991733Greg Clayton UpdateISAToDescriptorMap(); 578ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton ObjCLanguageRuntime::ISAToDescriptorIterator pos = m_isa_to_descriptor.find(isa); 579ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton if (pos != m_isa_to_descriptor.end()) 580a510437e795477e5f629263d3d191d982c991733Greg Clayton return pos->second; 581a510437e795477e5f629263d3d191d982c991733Greg Clayton } 582a510437e795477e5f629263d3d191d982c991733Greg Clayton return ClassDescriptorSP(); 583a510437e795477e5f629263d3d191d982c991733Greg Clayton} 584a510437e795477e5f629263d3d191d982c991733Greg Clayton 585a510437e795477e5f629263d3d191d982c991733Greg ClaytonObjCLanguageRuntime::ClassDescriptorSP 586be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg ClaytonObjCLanguageRuntime::GetNonKVOClassDescriptor (ObjCISA isa) 587be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton{ 588be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton if (isa) 589ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata { 590d387b462eecb908af265ecc7006781b4532073adGreg Clayton ClassDescriptorSP objc_class_sp = GetClassDescriptorFromISA (isa); 591be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton if (objc_class_sp && objc_class_sp->IsValid()) 592be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton { 593a510437e795477e5f629263d3d191d982c991733Greg Clayton if (!objc_class_sp->IsKVO()) 594be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton return objc_class_sp; 595a510437e795477e5f629263d3d191d982c991733Greg Clayton 596a510437e795477e5f629263d3d191d982c991733Greg Clayton ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass()); 597a510437e795477e5f629263d3d191d982c991733Greg Clayton if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid()) 598a510437e795477e5f629263d3d191d982c991733Greg Clayton return non_kvo_objc_class_sp; 599be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton } 600ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata } 601be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton return ClassDescriptorSP(); 602ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata} 603be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton 604be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton 605be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton 606