1254721Semaste//===-- ObjCLanguageRuntime.h ---------------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#ifndef liblldb_ObjCLanguageRuntime_h_ 11254721Semaste#define liblldb_ObjCLanguageRuntime_h_ 12254721Semaste 13254721Semaste// C Includes 14254721Semaste// C++ Includes 15254721Semaste#include <functional> 16254721Semaste#include <map> 17254721Semaste#include <unordered_set> 18254721Semaste 19254721Semaste// Other libraries and framework includes 20254721Semaste// Project includes 21254721Semaste#include "lldb/lldb-private.h" 22254721Semaste#include "lldb/Core/PluginInterface.h" 23254721Semaste#include "lldb/Symbol/Type.h" 24254721Semaste#include "lldb/Symbol/TypeVendor.h" 25254721Semaste#include "lldb/Target/LanguageRuntime.h" 26254721Semaste 27254721Semastenamespace lldb_private { 28254721Semaste 29254721Semasteclass ClangUtilityFunction; 30254721Semaste 31254721Semasteclass ObjCLanguageRuntime : 32254721Semaste public LanguageRuntime 33254721Semaste{ 34254721Semastepublic: 35254721Semaste class MethodName 36254721Semaste { 37254721Semaste public: 38254721Semaste enum Type 39254721Semaste { 40254721Semaste eTypeUnspecified, 41254721Semaste eTypeClassMethod, 42254721Semaste eTypeInstanceMethod 43254721Semaste }; 44254721Semaste 45254721Semaste MethodName () : 46254721Semaste m_full(), 47254721Semaste m_class(), 48254721Semaste m_category(), 49254721Semaste m_selector(), 50254721Semaste m_type (eTypeUnspecified), 51254721Semaste m_category_is_valid (false) 52254721Semaste { 53254721Semaste } 54254721Semaste 55254721Semaste MethodName (const char *name, bool strict) : 56254721Semaste m_full(), 57254721Semaste m_class(), 58254721Semaste m_category(), 59254721Semaste m_selector(), 60254721Semaste m_type (eTypeUnspecified), 61254721Semaste m_category_is_valid (false) 62254721Semaste { 63254721Semaste SetName (name, strict); 64254721Semaste } 65254721Semaste 66254721Semaste void 67254721Semaste Clear(); 68254721Semaste 69254721Semaste bool 70254721Semaste IsValid (bool strict) const 71254721Semaste { 72254721Semaste // If "strict" is true, the name must have everything specified including 73254721Semaste // the leading "+" or "-" on the method name 74254721Semaste if (strict && m_type == eTypeUnspecified) 75254721Semaste return false; 76254721Semaste // Other than that, m_full will only be filled in if the objective C 77254721Semaste // name is valid. 78254721Semaste return (bool)m_full; 79254721Semaste } 80254721Semaste 81254721Semaste bool 82254721Semaste HasCategory() 83254721Semaste { 84254721Semaste return (bool)GetCategory(); 85254721Semaste } 86254721Semaste 87254721Semaste Type 88254721Semaste GetType () const 89254721Semaste { 90254721Semaste return m_type; 91254721Semaste } 92254721Semaste 93254721Semaste const ConstString & 94254721Semaste GetFullName () const 95254721Semaste { 96254721Semaste return m_full; 97254721Semaste } 98254721Semaste 99254721Semaste ConstString 100254721Semaste GetFullNameWithoutCategory (bool empty_if_no_category); 101254721Semaste 102254721Semaste bool 103254721Semaste SetName (const char *name, bool strict); 104254721Semaste 105254721Semaste const ConstString & 106254721Semaste GetClassName (); 107254721Semaste 108254721Semaste const ConstString & 109254721Semaste GetClassNameWithCategory (); 110254721Semaste 111254721Semaste const ConstString & 112254721Semaste GetCategory (); 113254721Semaste 114254721Semaste const ConstString & 115254721Semaste GetSelector (); 116254721Semaste 117254721Semaste // Get all possible names for a method. Examples: 118254721Semaste // If name is "+[NSString(my_additions) myStringWithCString:]" 119254721Semaste // names[0] => "+[NSString(my_additions) myStringWithCString:]" 120254721Semaste // names[1] => "+[NSString myStringWithCString:]" 121254721Semaste // If name is specified without the leading '+' or '-' like "[NSString(my_additions) myStringWithCString:]" 122254721Semaste // names[0] => "+[NSString(my_additions) myStringWithCString:]" 123254721Semaste // names[1] => "-[NSString(my_additions) myStringWithCString:]" 124254721Semaste // names[2] => "+[NSString myStringWithCString:]" 125254721Semaste // names[3] => "-[NSString myStringWithCString:]" 126254721Semaste size_t 127254721Semaste GetFullNames (std::vector<ConstString> &names, bool append); 128254721Semaste protected: 129254721Semaste ConstString m_full; // Full name: "+[NSString(my_additions) myStringWithCString:]" 130254721Semaste ConstString m_class; // Class name: "NSString" 131254721Semaste ConstString m_class_category; // Class with category: "NSString(my_additions)" 132254721Semaste ConstString m_category; // Category: "my_additions" 133254721Semaste ConstString m_selector; // Selector: "myStringWithCString:" 134254721Semaste Type m_type; 135254721Semaste bool m_category_is_valid; 136254721Semaste 137254721Semaste }; 138254721Semaste typedef lldb::addr_t ObjCISA; 139254721Semaste 140254721Semaste class ClassDescriptor; 141254721Semaste typedef std::shared_ptr<ClassDescriptor> ClassDescriptorSP; 142254721Semaste 143254721Semaste // the information that we want to support retrieving from an ObjC class 144254721Semaste // this needs to be pure virtual since there are at least 2 different implementations 145254721Semaste // of the runtime, and more might come 146254721Semaste class ClassDescriptor 147254721Semaste { 148254721Semaste public: 149254721Semaste 150254721Semaste ClassDescriptor() : 151254721Semaste m_is_kvo (eLazyBoolCalculate), 152254721Semaste m_is_cf (eLazyBoolCalculate), 153254721Semaste m_type_wp () 154254721Semaste { 155254721Semaste } 156254721Semaste 157254721Semaste virtual 158254721Semaste ~ClassDescriptor () 159254721Semaste { 160254721Semaste } 161254721Semaste 162254721Semaste virtual ConstString 163254721Semaste GetClassName () = 0; 164254721Semaste 165254721Semaste virtual ClassDescriptorSP 166254721Semaste GetSuperclass () = 0; 167254721Semaste 168254721Semaste // virtual if any implementation has some other version-specific rules 169254721Semaste // but for the known v1/v2 this is all that needs to be done 170254721Semaste virtual bool 171254721Semaste IsKVO () 172254721Semaste { 173254721Semaste if (m_is_kvo == eLazyBoolCalculate) 174254721Semaste { 175254721Semaste const char* class_name = GetClassName().AsCString(); 176254721Semaste if (class_name && *class_name) 177254721Semaste m_is_kvo = (LazyBool)(strstr(class_name,"NSKVONotifying_") == class_name); 178254721Semaste } 179254721Semaste return (m_is_kvo == eLazyBoolYes); 180254721Semaste } 181254721Semaste 182254721Semaste // virtual if any implementation has some other version-specific rules 183254721Semaste // but for the known v1/v2 this is all that needs to be done 184254721Semaste virtual bool 185254721Semaste IsCFType () 186254721Semaste { 187254721Semaste if (m_is_cf == eLazyBoolCalculate) 188254721Semaste { 189254721Semaste const char* class_name = GetClassName().AsCString(); 190254721Semaste if (class_name && *class_name) 191254721Semaste m_is_cf = (LazyBool)(strcmp(class_name,"__NSCFType") == 0 || 192254721Semaste strcmp(class_name,"NSCFType") == 0); 193254721Semaste } 194254721Semaste return (m_is_cf == eLazyBoolYes); 195254721Semaste } 196254721Semaste 197254721Semaste virtual bool 198254721Semaste IsValid () = 0; 199254721Semaste 200254721Semaste virtual bool 201254721Semaste GetTaggedPointerInfo (uint64_t* info_bits = NULL, 202254721Semaste uint64_t* value_bits = NULL, 203254721Semaste uint64_t* payload = NULL) = 0; 204254721Semaste 205254721Semaste virtual uint64_t 206254721Semaste GetInstanceSize () = 0; 207254721Semaste 208254721Semaste // use to implement version-specific additional constraints on pointers 209254721Semaste virtual bool 210254721Semaste CheckPointer (lldb::addr_t value, 211254721Semaste uint32_t ptr_size) const 212254721Semaste { 213254721Semaste return true; 214254721Semaste } 215254721Semaste 216254721Semaste virtual ObjCISA 217254721Semaste GetISA () = 0; 218254721Semaste 219254721Semaste // This should return true iff the interface could be completed 220254721Semaste virtual bool 221254721Semaste Describe (std::function <void (ObjCISA)> const &superclass_func, 222254721Semaste std::function <bool (const char*, const char*)> const &instance_method_func, 223254721Semaste std::function <bool (const char*, const char*)> const &class_method_func, 224254721Semaste std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func) 225254721Semaste { 226254721Semaste return false; 227254721Semaste } 228254721Semaste 229254721Semaste lldb::TypeSP 230254721Semaste GetType () 231254721Semaste { 232254721Semaste return m_type_wp.lock(); 233254721Semaste } 234254721Semaste 235254721Semaste void 236254721Semaste SetType (const lldb::TypeSP &type_sp) 237254721Semaste { 238254721Semaste m_type_wp = type_sp; 239254721Semaste } 240254721Semaste 241254721Semaste protected: 242254721Semaste bool 243254721Semaste IsPointerValid (lldb::addr_t value, 244254721Semaste uint32_t ptr_size, 245254721Semaste bool allow_NULLs = false, 246254721Semaste bool allow_tagged = false, 247254721Semaste bool check_version_specific = false) const; 248254721Semaste 249254721Semaste private: 250254721Semaste LazyBool m_is_kvo; 251254721Semaste LazyBool m_is_cf; 252254721Semaste lldb::TypeWP m_type_wp; 253254721Semaste }; 254254721Semaste 255254721Semaste virtual ClassDescriptorSP 256254721Semaste GetClassDescriptor (ValueObject& in_value); 257254721Semaste 258254721Semaste ClassDescriptorSP 259254721Semaste GetNonKVOClassDescriptor (ValueObject& in_value); 260254721Semaste 261254721Semaste virtual ClassDescriptorSP 262254721Semaste GetClassDescriptorFromClassName (const ConstString &class_name); 263254721Semaste 264254721Semaste virtual ClassDescriptorSP 265254721Semaste GetClassDescriptorFromISA (ObjCISA isa); 266254721Semaste 267254721Semaste ClassDescriptorSP 268254721Semaste GetNonKVOClassDescriptor (ObjCISA isa); 269254721Semaste 270254721Semaste virtual 271254721Semaste ~ObjCLanguageRuntime(); 272254721Semaste 273254721Semaste virtual lldb::LanguageType 274254721Semaste GetLanguageType () const 275254721Semaste { 276254721Semaste return lldb::eLanguageTypeObjC; 277254721Semaste } 278254721Semaste 279254721Semaste virtual bool 280254721Semaste IsModuleObjCLibrary (const lldb::ModuleSP &module_sp) = 0; 281254721Semaste 282254721Semaste virtual bool 283254721Semaste ReadObjCLibrary (const lldb::ModuleSP &module_sp) = 0; 284254721Semaste 285254721Semaste virtual bool 286254721Semaste HasReadObjCLibrary () = 0; 287254721Semaste 288254721Semaste virtual lldb::ThreadPlanSP 289254721Semaste GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0; 290254721Semaste 291254721Semaste lldb::addr_t 292254721Semaste LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t sel); 293254721Semaste 294254721Semaste void 295254721Semaste AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr); 296254721Semaste 297254721Semaste TypeAndOrName 298254721Semaste LookupInClassNameCache (lldb::addr_t class_addr); 299254721Semaste 300254721Semaste void 301254721Semaste AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp); 302254721Semaste 303254721Semaste void 304254721Semaste AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_or_type_name); 305254721Semaste 306254721Semaste lldb::TypeSP 307254721Semaste LookupInCompleteClassCache (ConstString &name); 308254721Semaste 309254721Semaste virtual ClangUtilityFunction * 310254721Semaste CreateObjectChecker (const char *) = 0; 311254721Semaste 312254721Semaste virtual ObjCRuntimeVersions 313254721Semaste GetRuntimeVersion () 314254721Semaste { 315254721Semaste return eObjC_VersionUnknown; 316254721Semaste } 317254721Semaste 318254721Semaste bool 319254721Semaste IsValidISA(ObjCISA isa) 320254721Semaste { 321254721Semaste UpdateISAToDescriptorMap(); 322254721Semaste return m_isa_to_descriptor.count(isa) > 0; 323254721Semaste } 324254721Semaste 325254721Semaste virtual void 326254721Semaste UpdateISAToDescriptorMapIfNeeded() = 0; 327254721Semaste 328254721Semaste void 329254721Semaste UpdateISAToDescriptorMap() 330254721Semaste { 331254721Semaste if (m_process && m_process->GetStopID() != m_isa_to_descriptor_stop_id) 332254721Semaste { 333254721Semaste UpdateISAToDescriptorMapIfNeeded (); 334254721Semaste } 335254721Semaste } 336254721Semaste 337254721Semaste virtual ObjCISA 338254721Semaste GetISA(const ConstString &name); 339254721Semaste 340254721Semaste virtual ConstString 341254721Semaste GetActualTypeName(ObjCISA isa); 342254721Semaste 343254721Semaste virtual ObjCISA 344254721Semaste GetParentClass(ObjCISA isa); 345254721Semaste 346254721Semaste virtual TypeVendor * 347254721Semaste GetTypeVendor() 348254721Semaste { 349254721Semaste return NULL; 350254721Semaste } 351254721Semaste 352254721Semaste // Finds the byte offset of the child_type ivar in parent_type. If it can't find the 353254721Semaste // offset, returns LLDB_INVALID_IVAR_OFFSET. 354254721Semaste 355254721Semaste virtual size_t 356254721Semaste GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name); 357254721Semaste 358254721Semaste // Given the name of an Objective-C runtime symbol (e.g., ivar offset symbol), 359254721Semaste // try to determine from the runtime what the value of that symbol would be. 360254721Semaste // Useful when the underlying binary is stripped. 361254721Semaste virtual lldb::addr_t 362254721Semaste LookupRuntimeSymbol (const ConstString &name) 363254721Semaste { 364254721Semaste return LLDB_INVALID_ADDRESS; 365254721Semaste } 366254721Semaste 367254721Semaste //------------------------------------------------------------------ 368254721Semaste /// Chop up an objective C function prototype. 369254721Semaste /// 370254721Semaste /// Chop up an objective C function fullname and optionally fill in 371254721Semaste /// any non-NULL ConstString objects. If a ConstString * is NULL, 372254721Semaste /// then this name doesn't get filled in 373254721Semaste /// 374254721Semaste /// @param[in] name 375254721Semaste /// A fully specified objective C function name. The string might 376254721Semaste /// contain a category and it includes the leading "+" or "-" and 377254721Semaste /// the square brackets, no types for the arguments, just the plain 378254721Semaste /// selector. A few examples: 379254721Semaste /// "-[NSStringDrawingContext init]" 380254721Semaste /// "-[NSStringDrawingContext addString:inRect:]" 381254721Semaste /// "-[NSString(NSStringDrawing) sizeWithAttributes:]" 382254721Semaste /// "+[NSString(NSStringDrawing) usesFontLeading]" 383254721Semaste /// 384254721Semaste /// @param[out] class_name 385254721Semaste /// If non-NULL, this string will be filled in with the class 386254721Semaste /// name including the category. The examples above would return: 387254721Semaste /// "NSStringDrawingContext" 388254721Semaste /// "NSStringDrawingContext" 389254721Semaste /// "NSString(NSStringDrawing)" 390254721Semaste /// "NSString(NSStringDrawing)" 391254721Semaste /// 392254721Semaste /// @param[out] selector_name 393254721Semaste /// If non-NULL, this string will be filled in with the selector 394254721Semaste /// name. The examples above would return: 395254721Semaste /// "init" 396254721Semaste /// "addString:inRect:" 397254721Semaste /// "sizeWithAttributes:" 398254721Semaste /// "usesFontLeading" 399254721Semaste /// 400254721Semaste /// @param[out] name_sans_category 401254721Semaste /// If non-NULL, this string will be filled in with the class 402254721Semaste /// name _without_ the category. If there is no category, and empty 403254721Semaste /// string will be returned (as the result would be normally returned 404254721Semaste /// in the "class_name" argument). The examples above would return: 405254721Semaste /// <empty> 406254721Semaste /// <empty> 407254721Semaste /// "-[NSString sizeWithAttributes:]" 408254721Semaste /// "+[NSString usesFontLeading]" 409254721Semaste /// 410254721Semaste /// @param[out] class_name_sans_category 411254721Semaste /// If non-NULL, this string will be filled in with the prototype 412254721Semaste /// name _without_ the category. If there is no category, and empty 413254721Semaste /// string will be returned (as this is already the value that was 414254721Semaste /// passed in). The examples above would return: 415254721Semaste /// <empty> 416254721Semaste /// <empty> 417254721Semaste /// "NSString" 418254721Semaste /// "NSString" 419254721Semaste /// 420254721Semaste /// @return 421254721Semaste /// Returns the number of strings that were successfully filled 422254721Semaste /// in. 423254721Semaste //------------------------------------------------------------------ 424254721Semaste// static uint32_t 425254721Semaste// ParseMethodName (const char *name, 426254721Semaste// ConstString *class_name, // Class name (with category if there is one) 427254721Semaste// ConstString *selector_name, // selector only 428254721Semaste// ConstString *name_sans_category, // full function name with no category (empty if no category) 429254721Semaste// ConstString *class_name_sans_category);// Class name without category (empty if no category) 430254721Semaste 431254721Semaste static bool 432254721Semaste IsPossibleObjCMethodName (const char *name) 433254721Semaste { 434254721Semaste if (!name) 435254721Semaste return false; 436254721Semaste bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '['; 437254721Semaste bool ends_right = (name[strlen(name) - 1] == ']'); 438254721Semaste return (starts_right && ends_right); 439254721Semaste } 440254721Semaste 441254721Semaste static bool 442254721Semaste IsPossibleObjCSelector (const char *name) 443254721Semaste { 444254721Semaste if (!name) 445254721Semaste return false; 446254721Semaste 447254721Semaste if (strchr(name, ':') == NULL) 448254721Semaste return true; 449254721Semaste else if (name[strlen(name) - 1] == ':') 450254721Semaste return true; 451254721Semaste else 452254721Semaste return false; 453254721Semaste } 454254721Semaste 455254721Semaste bool 456254721Semaste HasNewLiteralsAndIndexing () 457254721Semaste { 458254721Semaste if (m_has_new_literals_and_indexing == eLazyBoolCalculate) 459254721Semaste { 460254721Semaste if (CalculateHasNewLiteralsAndIndexing()) 461254721Semaste m_has_new_literals_and_indexing = eLazyBoolYes; 462254721Semaste else 463254721Semaste m_has_new_literals_and_indexing = eLazyBoolNo; 464254721Semaste } 465254721Semaste 466254721Semaste return (m_has_new_literals_and_indexing == eLazyBoolYes); 467254721Semaste } 468254721Semaste 469254721Semaste virtual void 470254721Semaste SymbolsDidLoad (const ModuleList& module_list) 471254721Semaste { 472254721Semaste m_negative_complete_class_cache.clear(); 473254721Semaste } 474254721Semaste 475254721Semasteprotected: 476254721Semaste //------------------------------------------------------------------ 477254721Semaste // Classes that inherit from ObjCLanguageRuntime can see and modify these 478254721Semaste //------------------------------------------------------------------ 479254721Semaste ObjCLanguageRuntime(Process *process); 480254721Semaste 481254721Semaste virtual bool CalculateHasNewLiteralsAndIndexing() 482254721Semaste { 483254721Semaste return false; 484254721Semaste } 485254721Semaste 486254721Semaste 487254721Semaste bool 488254721Semaste ISAIsCached (ObjCISA isa) const 489254721Semaste { 490254721Semaste return m_isa_to_descriptor.find(isa) != m_isa_to_descriptor.end(); 491254721Semaste } 492254721Semaste 493254721Semaste bool 494254721Semaste AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp) 495254721Semaste { 496254721Semaste if (isa != 0) 497254721Semaste { 498254721Semaste m_isa_to_descriptor[isa] = descriptor_sp; 499254721Semaste return true; 500254721Semaste } 501254721Semaste return false; 502254721Semaste } 503254721Semaste 504254721Semaste bool 505254721Semaste AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name); 506254721Semaste 507254721Semaste bool 508254721Semaste AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, uint32_t class_name_hash) 509254721Semaste { 510254721Semaste if (isa != 0) 511254721Semaste { 512254721Semaste m_isa_to_descriptor[isa] = descriptor_sp; 513254721Semaste m_hash_to_isa_map.insert(std::make_pair(class_name_hash, isa)); 514254721Semaste return true; 515254721Semaste } 516254721Semaste return false; 517254721Semaste } 518254721Semaste 519254721Semasteprivate: 520254721Semaste // We keep a map of <Class,Selector>->Implementation so we don't have to call the resolver 521254721Semaste // function over and over. 522254721Semaste 523254721Semaste // FIXME: We need to watch for the loading of Protocols, and flush the cache for any 524254721Semaste // class that we see so changed. 525254721Semaste 526254721Semaste struct ClassAndSel 527254721Semaste { 528254721Semaste ClassAndSel() 529254721Semaste { 530254721Semaste sel_addr = LLDB_INVALID_ADDRESS; 531254721Semaste class_addr = LLDB_INVALID_ADDRESS; 532254721Semaste } 533254721Semaste ClassAndSel (lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr) : 534254721Semaste class_addr (in_class_addr), 535254721Semaste sel_addr(in_sel_addr) 536254721Semaste { 537254721Semaste } 538254721Semaste bool operator== (const ClassAndSel &rhs) 539254721Semaste { 540254721Semaste if (class_addr == rhs.class_addr 541254721Semaste && sel_addr == rhs.sel_addr) 542254721Semaste return true; 543254721Semaste else 544254721Semaste return false; 545254721Semaste } 546254721Semaste 547254721Semaste bool operator< (const ClassAndSel &rhs) const 548254721Semaste { 549254721Semaste if (class_addr < rhs.class_addr) 550254721Semaste return true; 551254721Semaste else if (class_addr > rhs.class_addr) 552254721Semaste return false; 553254721Semaste else 554254721Semaste { 555254721Semaste if (sel_addr < rhs.sel_addr) 556254721Semaste return true; 557254721Semaste else 558254721Semaste return false; 559254721Semaste } 560254721Semaste } 561254721Semaste 562254721Semaste lldb::addr_t class_addr; 563254721Semaste lldb::addr_t sel_addr; 564254721Semaste }; 565254721Semaste 566254721Semaste typedef std::map<ClassAndSel,lldb::addr_t> MsgImplMap; 567254721Semaste typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap; 568254721Semaste typedef std::multimap<uint32_t, ObjCISA> HashToISAMap; 569254721Semaste typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator; 570254721Semaste typedef HashToISAMap::iterator HashToISAIterator; 571254721Semaste 572254721Semaste MsgImplMap m_impl_cache; 573254721Semaste LazyBool m_has_new_literals_and_indexing; 574254721Semaste ISAToDescriptorMap m_isa_to_descriptor; 575254721Semaste HashToISAMap m_hash_to_isa_map; 576254721Semaste 577254721Semasteprotected: 578254721Semaste uint32_t m_isa_to_descriptor_stop_id; 579254721Semaste 580254721Semaste typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap; 581254721Semaste CompleteClassMap m_complete_class_cache; 582254721Semaste 583254721Semaste struct ConstStringSetHelpers { 584254721Semaste size_t operator () (const ConstString& arg) const // for hashing 585254721Semaste { 586254721Semaste return (size_t)arg.GetCString(); 587254721Semaste } 588254721Semaste bool operator () (const ConstString& arg1, const ConstString& arg2) const // for equality 589254721Semaste { 590254721Semaste return arg1.operator==(arg2); 591254721Semaste } 592254721Semaste }; 593254721Semaste typedef std::unordered_set<ConstString, ConstStringSetHelpers, ConstStringSetHelpers> CompleteClassSet; 594254721Semaste CompleteClassSet m_negative_complete_class_cache; 595254721Semaste 596254721Semaste ISAToDescriptorIterator 597254721Semaste GetDescriptorIterator (const ConstString &name); 598254721Semaste 599254721Semaste DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime); 600254721Semaste}; 601254721Semaste 602254721Semaste} // namespace lldb_private 603254721Semaste 604254721Semaste#endif // liblldb_ObjCLanguageRuntime_h_ 605