ObjCLanguageRuntime.h revision 81a5a09e76cfc1f110c0416e372f9f6cc27d79cf
1//===-- ObjCLanguageRuntime.h ---------------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef liblldb_ObjCLanguageRuntime_h_ 11#define liblldb_ObjCLanguageRuntime_h_ 12 13// C Includes 14// C++ Includes 15#include <map> 16 17// Other libraries and framework includes 18// Project includes 19#include "lldb/lldb-private.h" 20#include "lldb/Core/PluginInterface.h" 21#include "lldb/Symbol/Type.h" 22#include "lldb/Symbol/TypeVendor.h" 23#include "lldb/Target/LanguageRuntime.h" 24 25namespace lldb_private { 26 27class ClangUtilityFunction; 28 29class ObjCLanguageRuntime : 30 public LanguageRuntime 31{ 32public: 33 34 typedef lldb::addr_t ObjCISA; 35 36 class ClassDescriptor; 37 typedef STD_SHARED_PTR(ClassDescriptor) ClassDescriptorSP; 38 39 // the information that we want to support retrieving from an ObjC class 40 // this needs to be pure virtual since there are at least 2 different implementations 41 // of the runtime, and more might come 42 class ClassDescriptor 43 { 44 public: 45 46 ClassDescriptor() : 47 m_is_kvo(eLazyBoolCalculate), 48 m_is_cf(eLazyBoolCalculate) 49 {} 50 51 ClassDescriptor (ObjCISA isa, lldb::ProcessSP process) : 52 m_is_kvo(eLazyBoolCalculate), 53 m_is_cf(eLazyBoolCalculate) 54 {} 55 56 virtual ConstString 57 GetClassName () = 0; 58 59 virtual ClassDescriptorSP 60 GetSuperclass () = 0; 61 62 // virtual if any implementation has some other version-specific rules 63 // but for the known v1/v2 this is all that needs to be done 64 virtual bool 65 IsKVO () 66 { 67 if (m_is_kvo == eLazyBoolCalculate) 68 { 69 const char* class_name = GetClassName().AsCString(); 70 m_is_kvo = (LazyBool)(strstr(class_name,"NSKVONotifying_") == class_name); 71 } 72 return (m_is_kvo == eLazyBoolYes); 73 } 74 75 // virtual if any implementation has some other version-specific rules 76 // but for the known v1/v2 this is all that needs to be done 77 virtual bool 78 IsCFType () 79 { 80 if (m_is_cf == eLazyBoolCalculate) 81 { 82 const char* class_name = GetClassName().AsCString(); 83 m_is_cf = (LazyBool)(strcmp(class_name,"__NSCFType") == 0 || 84 strcmp(class_name,"NSCFType") == 0); 85 } 86 return (m_is_cf == eLazyBoolYes); 87 } 88 89 virtual bool 90 IsValid () = 0; 91 92 virtual bool 93 IsTagged () = 0; 94 95 virtual uint64_t 96 GetInstanceSize () = 0; 97 98 virtual bool 99 IsRealized () 100 { 101 // anything other than some instances of v2 classes are always realized 102 return true; 103 } 104 105 // use to implement version-specific additional constraints on pointers 106 virtual bool 107 CheckPointer (lldb::addr_t value, 108 uint32_t ptr_size) 109 { 110 return true; 111 } 112 113 virtual ObjCISA 114 GetISA () = 0; 115 116 // This should return true iff the interface could be completed 117 virtual bool 118 CompleteInterface (clang::ObjCInterfaceDecl *interface_decl) 119 { 120 return false; 121 } 122 123 virtual 124 ~ClassDescriptor () 125 {} 126 127 protected: 128 bool 129 IsPointerValid (lldb::addr_t value, 130 uint32_t ptr_size, 131 bool allow_NULLs = false, 132 bool allow_tagged = false, 133 bool check_version_specific = false); 134 135 private: 136 LazyBool m_is_kvo; 137 LazyBool m_is_cf; 138 }; 139 140 // a convenience subclass of ClassDescriptor meant to represent invalid objects 141 class ClassDescriptor_Invalid : public ClassDescriptor 142 { 143 public: 144 ClassDescriptor_Invalid() {} 145 146 virtual ConstString 147 GetClassName () { return ConstString(""); } 148 149 virtual ClassDescriptorSP 150 GetSuperclass () { return ClassDescriptorSP(new ClassDescriptor_Invalid()); } 151 152 virtual bool 153 IsValid () { return false; } 154 155 virtual bool 156 IsTagged () { return false; } 157 158 virtual uint64_t 159 GetInstanceSize () { return 0; } 160 161 virtual ObjCISA 162 GetISA () { return 0; } 163 164 virtual bool 165 CheckPointer (lldb::addr_t value, 166 uint32_t ptr_size) { return false; } 167 168 virtual 169 ~ClassDescriptor_Invalid () 170 {} 171 172 }; 173 174 virtual ClassDescriptorSP 175 GetClassDescriptor (ValueObject& in_value) 176 { 177 return ClassDescriptorSP(); 178 } 179 180 virtual ClassDescriptorSP 181 GetClassDescriptor (ObjCISA isa) 182 { 183 return ClassDescriptorSP(); 184 } 185 186 virtual 187 ~ObjCLanguageRuntime(); 188 189 virtual lldb::LanguageType 190 GetLanguageType () const 191 { 192 return lldb::eLanguageTypeObjC; 193 } 194 195 virtual bool 196 IsModuleObjCLibrary (const lldb::ModuleSP &module_sp) = 0; 197 198 virtual bool 199 ReadObjCLibrary (const lldb::ModuleSP &module_sp) = 0; 200 201 virtual bool 202 HasReadObjCLibrary () = 0; 203 204 virtual lldb::ThreadPlanSP 205 GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0; 206 207 lldb::addr_t 208 LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t sel); 209 210 void 211 AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr); 212 213 TypeAndOrName 214 LookupInClassNameCache (lldb::addr_t class_addr); 215 216 void 217 AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp); 218 219 void 220 AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_or_type_name); 221 222 lldb::TypeSP 223 LookupInCompleteClassCache (ConstString &name); 224 225 virtual ClangUtilityFunction * 226 CreateObjectChecker (const char *) = 0; 227 228 virtual ObjCRuntimeVersions 229 GetRuntimeVersion () 230 { 231 return eObjC_VersionUnknown; 232 } 233 234 virtual bool 235 IsValidISA(ObjCISA isa) = 0; 236 237 virtual ObjCISA 238 GetISA(ValueObject& valobj) = 0; 239 240 virtual void 241 UpdateISAToDescriptorMap_Impl() 242 { 243 // to be implemented by runtimes if they support doing this 244 } 245 246 void 247 UpdateISAToDescriptorMap() 248 { 249 if (m_isa_to_descriptor_cache_is_up_to_date) 250 return; 251 252 m_isa_to_descriptor_cache_is_up_to_date = true; 253 254 UpdateISAToDescriptorMap_Impl(); 255 } 256 257 virtual ObjCISA 258 GetISA(const ConstString &name); 259 260 virtual ConstString 261 GetActualTypeName(ObjCISA isa); 262 263 virtual ObjCISA 264 GetParentClass(ObjCISA isa); 265 266 virtual TypeVendor * 267 GetTypeVendor() 268 { 269 return NULL; 270 } 271 272 // Finds the byte offset of the child_type ivar in parent_type. If it can't find the 273 // offset, returns LLDB_INVALID_IVAR_OFFSET. 274 275 virtual size_t 276 GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name); 277 278 //------------------------------------------------------------------ 279 /// Chop up an objective C function prototype. 280 /// 281 /// Chop up an objective C function fullname and optionally fill in 282 /// any non-NULL ConstString objects. If a ConstString * is NULL, 283 /// then this name doesn't get filled in 284 /// 285 /// @param[in] name 286 /// A fully specified objective C function name. The string might 287 /// contain a category and it includes the leading "+" or "-" and 288 /// the square brackets, no types for the arguments, just the plain 289 /// selector. A few examples: 290 /// "-[NSStringDrawingContext init]" 291 /// "-[NSStringDrawingContext addString:inRect:]" 292 /// "-[NSString(NSStringDrawing) sizeWithAttributes:]" 293 /// "+[NSString(NSStringDrawing) usesFontLeading]" 294 /// 295 /// @param[out] class_name 296 /// If non-NULL, this string will be filled in with the class 297 /// name including the category. The examples above would return: 298 /// "NSStringDrawingContext" 299 /// "NSStringDrawingContext" 300 /// "NSString(NSStringDrawing)" 301 /// "NSString(NSStringDrawing)" 302 /// 303 /// @param[out] selector_name 304 /// If non-NULL, this string will be filled in with the selector 305 /// name. The examples above would return: 306 /// "init" 307 /// "addString:inRect:" 308 /// "sizeWithAttributes:" 309 /// "usesFontLeading" 310 /// 311 /// @param[out] name_sans_category 312 /// If non-NULL, this string will be filled in with the class 313 /// name _without_ the category. If there is no category, and empty 314 /// string will be returned (as the result would be normally returned 315 /// in the "class_name" argument). The examples above would return: 316 /// <empty> 317 /// <empty> 318 /// "-[NSString sizeWithAttributes:]" 319 /// "+[NSString usesFontLeading]" 320 /// 321 /// @param[out] class_name_sans_category 322 /// If non-NULL, this string will be filled in with the prototype 323 /// name _without_ the category. If there is no category, and empty 324 /// string will be returned (as this is already the value that was 325 /// passed in). The examples above would return: 326 /// <empty> 327 /// <empty> 328 /// "NSString" 329 /// "NSString" 330 /// 331 /// @return 332 /// Returns the number of strings that were successfully filled 333 /// in. 334 //------------------------------------------------------------------ 335 static uint32_t 336 ParseMethodName (const char *name, 337 ConstString *class_name, // Class name (with category if there is one) 338 ConstString *selector_name, // selector only 339 ConstString *name_sans_category, // full function name with no category (empty if no category) 340 ConstString *class_name_sans_category);// Class name without category (empty if no category) 341 342 static bool 343 IsPossibleObjCMethodName (const char *name) 344 { 345 if (!name) 346 return false; 347 bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '['; 348 bool ends_right = (name[strlen(name) - 1] == ']'); 349 return (starts_right && ends_right); 350 } 351 352 static bool 353 IsPossibleObjCSelector (const char *name) 354 { 355 if (!name) 356 return false; 357 358 if (strchr(name, ':') == NULL) 359 return true; 360 else if (name[strlen(name) - 1] == ':') 361 return true; 362 else 363 return false; 364 } 365 366 bool 367 HasNewLiteralsAndIndexing () 368 { 369 if (m_has_new_literals_and_indexing == eLazyBoolCalculate) 370 { 371 if (CalculateHasNewLiteralsAndIndexing()) 372 m_has_new_literals_and_indexing = eLazyBoolYes; 373 else 374 m_has_new_literals_and_indexing = eLazyBoolNo; 375 } 376 377 return (m_has_new_literals_and_indexing == eLazyBoolYes); 378 } 379 380protected: 381 //------------------------------------------------------------------ 382 // Classes that inherit from ObjCLanguageRuntime can see and modify these 383 //------------------------------------------------------------------ 384 ObjCLanguageRuntime(Process *process); 385 386 virtual bool CalculateHasNewLiteralsAndIndexing() 387 { 388 return false; 389 } 390private: 391 // We keep a map of <Class,Selector>->Implementation so we don't have to call the resolver 392 // function over and over. 393 394 // FIXME: We need to watch for the loading of Protocols, and flush the cache for any 395 // class that we see so changed. 396 397 struct ClassAndSel 398 { 399 ClassAndSel() 400 { 401 sel_addr = LLDB_INVALID_ADDRESS; 402 class_addr = LLDB_INVALID_ADDRESS; 403 } 404 ClassAndSel (lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr) : 405 class_addr (in_class_addr), 406 sel_addr(in_sel_addr) 407 { 408 } 409 bool operator== (const ClassAndSel &rhs) 410 { 411 if (class_addr == rhs.class_addr 412 && sel_addr == rhs.sel_addr) 413 return true; 414 else 415 return false; 416 } 417 418 bool operator< (const ClassAndSel &rhs) const 419 { 420 if (class_addr < rhs.class_addr) 421 return true; 422 else if (class_addr > rhs.class_addr) 423 return false; 424 else 425 { 426 if (sel_addr < rhs.sel_addr) 427 return true; 428 else 429 return false; 430 } 431 } 432 433 lldb::addr_t class_addr; 434 lldb::addr_t sel_addr; 435 }; 436 437 typedef std::map<ClassAndSel,lldb::addr_t> MsgImplMap; 438 MsgImplMap m_impl_cache; 439 440 LazyBool m_has_new_literals_and_indexing; 441protected: 442 typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap; 443 typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator; 444 ISAToDescriptorMap m_isa_to_descriptor_cache; 445 bool m_isa_to_descriptor_cache_is_up_to_date; 446 447 typedef std::map<lldb::addr_t,TypeAndOrName> ClassNameMap; 448 typedef ClassNameMap::iterator ClassNameIterator; 449 ClassNameMap m_class_name_cache; 450 451 typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap; 452 CompleteClassMap m_complete_class_cache; 453 454 DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime); 455}; 456 457} // namespace lldb_private 458 459#endif // liblldb_ObjCLanguageRuntime_h_ 460