1 //===-- ObjCLanguageRuntime.h ---------------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_ObjCLanguageRuntime_h_
11 #define liblldb_ObjCLanguageRuntime_h_
17 #include <unordered_set>
19 // Other libraries and framework includes
21 #include "lldb/lldb-private.h"
22 #include "lldb/Core/PluginInterface.h"
23 #include "lldb/Symbol/ClangASTType.h"
24 #include "lldb/Symbol/Type.h"
25 #include "lldb/Symbol/TypeVendor.h"
26 #include "lldb/Target/LanguageRuntime.h"
28 namespace lldb_private {
30 class ClangUtilityFunction;
32 class ObjCLanguageRuntime :
33 public LanguageRuntime
51 m_type (eTypeUnspecified),
52 m_category_is_valid (false)
56 MethodName (const char *name, bool strict) :
61 m_type (eTypeUnspecified),
62 m_category_is_valid (false)
64 SetName (name, strict);
71 IsValid (bool strict) const
73 // If "strict" is true, the name must have everything specified including
74 // the leading "+" or "-" on the method name
75 if (strict && m_type == eTypeUnspecified)
77 // Other than that, m_full will only be filled in if the objective C
85 return (bool)GetCategory();
101 GetFullNameWithoutCategory (bool empty_if_no_category);
104 SetName (const char *name, bool strict);
110 GetClassNameWithCategory ();
118 // Get all possible names for a method. Examples:
119 // If name is "+[NSString(my_additions) myStringWithCString:]"
120 // names[0] => "+[NSString(my_additions) myStringWithCString:]"
121 // names[1] => "+[NSString myStringWithCString:]"
122 // If name is specified without the leading '+' or '-' like "[NSString(my_additions) myStringWithCString:]"
123 // names[0] => "+[NSString(my_additions) myStringWithCString:]"
124 // names[1] => "-[NSString(my_additions) myStringWithCString:]"
125 // names[2] => "+[NSString myStringWithCString:]"
126 // names[3] => "-[NSString myStringWithCString:]"
128 GetFullNames (std::vector<ConstString> &names, bool append);
130 ConstString m_full; // Full name: "+[NSString(my_additions) myStringWithCString:]"
131 ConstString m_class; // Class name: "NSString"
132 ConstString m_class_category; // Class with category: "NSString(my_additions)"
133 ConstString m_category; // Category: "my_additions"
134 ConstString m_selector; // Selector: "myStringWithCString:"
136 bool m_category_is_valid;
139 typedef lldb::addr_t ObjCISA;
141 class ClassDescriptor;
142 typedef std::shared_ptr<ClassDescriptor> ClassDescriptorSP;
144 // the information that we want to support retrieving from an ObjC class
145 // this needs to be pure virtual since there are at least 2 different implementations
146 // of the runtime, and more might come
147 class ClassDescriptor
152 m_is_kvo (eLazyBoolCalculate),
153 m_is_cf (eLazyBoolCalculate),
166 virtual ClassDescriptorSP
167 GetSuperclass () = 0;
169 // virtual if any implementation has some other version-specific rules
170 // but for the known v1/v2 this is all that needs to be done
174 if (m_is_kvo == eLazyBoolCalculate)
176 const char* class_name = GetClassName().AsCString();
177 if (class_name && *class_name)
178 m_is_kvo = (LazyBool)(strstr(class_name,"NSKVONotifying_") == class_name);
180 return (m_is_kvo == eLazyBoolYes);
183 // virtual if any implementation has some other version-specific rules
184 // but for the known v1/v2 this is all that needs to be done
188 if (m_is_cf == eLazyBoolCalculate)
190 const char* class_name = GetClassName().AsCString();
191 if (class_name && *class_name)
192 m_is_cf = (LazyBool)(strcmp(class_name,"__NSCFType") == 0 ||
193 strcmp(class_name,"NSCFType") == 0);
195 return (m_is_cf == eLazyBoolYes);
202 GetTaggedPointerInfo (uint64_t* info_bits = NULL,
203 uint64_t* value_bits = NULL,
204 uint64_t* payload = NULL) = 0;
207 GetInstanceSize () = 0;
209 // use to implement version-specific additional constraints on pointers
211 CheckPointer (lldb::addr_t value,
212 uint32_t ptr_size) const
220 // This should return true iff the interface could be completed
222 Describe (std::function <void (ObjCISA)> const &superclass_func,
223 std::function <bool (const char*, const char*)> const &instance_method_func,
224 std::function <bool (const char*, const char*)> const &class_method_func,
225 std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func) const
233 return m_type_wp.lock();
237 SetType (const lldb::TypeSP &type_sp)
242 struct iVarDescriptor {
255 virtual iVarDescriptor
256 GetIVarAtIndex (size_t idx)
258 return iVarDescriptor();
263 IsPointerValid (lldb::addr_t value,
265 bool allow_NULLs = false,
266 bool allow_tagged = false,
267 bool check_version_specific = false) const;
272 lldb::TypeWP m_type_wp;
278 virtual ClangASTType RealizeType (ClangASTContext& ast_ctx, const char* name, bool allow_unknownanytype);
279 virtual ClangASTType RealizeType (const char* name, bool allow_unknownanytype);
281 virtual ClangASTType RealizeType (clang::ASTContext& ast_ctx, const char* name, bool allow_unknownanytype) = 0;
283 virtual ~EncodingToType();
286 std::unique_ptr<ClangASTContext> m_scratch_ast_ctx_ap;
289 typedef std::shared_ptr<EncodingToType> EncodingToTypeSP;
291 virtual EncodingToTypeSP
292 GetEncodingToType ();
294 virtual ClassDescriptorSP
295 GetClassDescriptor (ValueObject& in_value);
298 GetNonKVOClassDescriptor (ValueObject& in_value);
300 virtual ClassDescriptorSP
301 GetClassDescriptorFromClassName (const ConstString &class_name);
303 virtual ClassDescriptorSP
304 GetClassDescriptorFromISA (ObjCISA isa);
307 GetNonKVOClassDescriptor (ObjCISA isa);
310 ~ObjCLanguageRuntime();
312 virtual lldb::LanguageType
313 GetLanguageType () const
315 return lldb::eLanguageTypeObjC;
319 IsModuleObjCLibrary (const lldb::ModuleSP &module_sp) = 0;
322 ReadObjCLibrary (const lldb::ModuleSP &module_sp) = 0;
325 HasReadObjCLibrary () = 0;
327 virtual lldb::ThreadPlanSP
328 GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0;
331 LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t sel);
334 AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr);
337 LookupInClassNameCache (lldb::addr_t class_addr);
340 AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp);
343 AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_or_type_name);
346 LookupInCompleteClassCache (ConstString &name);
348 virtual ClangUtilityFunction *
349 CreateObjectChecker (const char *) = 0;
351 virtual ObjCRuntimeVersions
354 return eObjC_VersionUnknown;
358 IsValidISA(ObjCISA isa)
360 UpdateISAToDescriptorMap();
361 return m_isa_to_descriptor.count(isa) > 0;
365 UpdateISAToDescriptorMapIfNeeded() = 0;
368 UpdateISAToDescriptorMap()
370 if (m_process && m_process->GetStopID() != m_isa_to_descriptor_stop_id)
372 UpdateISAToDescriptorMapIfNeeded ();
377 GetISA(const ConstString &name);
380 GetActualTypeName(ObjCISA isa);
383 GetParentClass(ObjCISA isa);
391 // Finds the byte offset of the child_type ivar in parent_type. If it can't find the
392 // offset, returns LLDB_INVALID_IVAR_OFFSET.
395 GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name);
397 // Given the name of an Objective-C runtime symbol (e.g., ivar offset symbol),
398 // try to determine from the runtime what the value of that symbol would be.
399 // Useful when the underlying binary is stripped.
401 LookupRuntimeSymbol (const ConstString &name)
403 return LLDB_INVALID_ADDRESS;
406 //------------------------------------------------------------------
407 /// Chop up an objective C function prototype.
409 /// Chop up an objective C function fullname and optionally fill in
410 /// any non-NULL ConstString objects. If a ConstString * is NULL,
411 /// then this name doesn't get filled in
414 /// A fully specified objective C function name. The string might
415 /// contain a category and it includes the leading "+" or "-" and
416 /// the square brackets, no types for the arguments, just the plain
417 /// selector. A few examples:
418 /// "-[NSStringDrawingContext init]"
419 /// "-[NSStringDrawingContext addString:inRect:]"
420 /// "-[NSString(NSStringDrawing) sizeWithAttributes:]"
421 /// "+[NSString(NSStringDrawing) usesFontLeading]"
423 /// @param[out] class_name
424 /// If non-NULL, this string will be filled in with the class
425 /// name including the category. The examples above would return:
426 /// "NSStringDrawingContext"
427 /// "NSStringDrawingContext"
428 /// "NSString(NSStringDrawing)"
429 /// "NSString(NSStringDrawing)"
431 /// @param[out] selector_name
432 /// If non-NULL, this string will be filled in with the selector
433 /// name. The examples above would return:
435 /// "addString:inRect:"
436 /// "sizeWithAttributes:"
437 /// "usesFontLeading"
439 /// @param[out] name_sans_category
440 /// If non-NULL, this string will be filled in with the class
441 /// name _without_ the category. If there is no category, and empty
442 /// string will be returned (as the result would be normally returned
443 /// in the "class_name" argument). The examples above would return:
446 /// "-[NSString sizeWithAttributes:]"
447 /// "+[NSString usesFontLeading]"
449 /// @param[out] class_name_sans_category
450 /// If non-NULL, this string will be filled in with the prototype
451 /// name _without_ the category. If there is no category, and empty
452 /// string will be returned (as this is already the value that was
453 /// passed in). The examples above would return:
460 /// Returns the number of strings that were successfully filled
462 //------------------------------------------------------------------
464 // ParseMethodName (const char *name,
465 // ConstString *class_name, // Class name (with category if there is one)
466 // ConstString *selector_name, // selector only
467 // ConstString *name_sans_category, // full function name with no category (empty if no category)
468 // ConstString *class_name_sans_category);// Class name without category (empty if no category)
471 IsPossibleObjCMethodName (const char *name)
475 bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '[';
476 bool ends_right = (name[strlen(name) - 1] == ']');
477 return (starts_right && ends_right);
481 IsPossibleObjCSelector (const char *name)
486 if (strchr(name, ':') == NULL)
488 else if (name[strlen(name) - 1] == ':')
495 HasNewLiteralsAndIndexing ()
497 if (m_has_new_literals_and_indexing == eLazyBoolCalculate)
499 if (CalculateHasNewLiteralsAndIndexing())
500 m_has_new_literals_and_indexing = eLazyBoolYes;
502 m_has_new_literals_and_indexing = eLazyBoolNo;
505 return (m_has_new_literals_and_indexing == eLazyBoolYes);
509 SymbolsDidLoad (const ModuleList& module_list)
511 m_negative_complete_class_cache.clear();
515 //------------------------------------------------------------------
516 // Classes that inherit from ObjCLanguageRuntime can see and modify these
517 //------------------------------------------------------------------
518 ObjCLanguageRuntime(Process *process);
520 virtual bool CalculateHasNewLiteralsAndIndexing()
527 ISAIsCached (ObjCISA isa) const
529 return m_isa_to_descriptor.find(isa) != m_isa_to_descriptor.end();
533 AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp)
537 m_isa_to_descriptor[isa] = descriptor_sp;
544 AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name);
547 AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, uint32_t class_name_hash)
551 m_isa_to_descriptor[isa] = descriptor_sp;
552 m_hash_to_isa_map.insert(std::make_pair(class_name_hash, isa));
559 // We keep a map of <Class,Selector>->Implementation so we don't have to call the resolver
560 // function over and over.
562 // FIXME: We need to watch for the loading of Protocols, and flush the cache for any
563 // class that we see so changed.
569 sel_addr = LLDB_INVALID_ADDRESS;
570 class_addr = LLDB_INVALID_ADDRESS;
572 ClassAndSel (lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr) :
573 class_addr (in_class_addr),
574 sel_addr(in_sel_addr)
577 bool operator== (const ClassAndSel &rhs)
579 if (class_addr == rhs.class_addr
580 && sel_addr == rhs.sel_addr)
586 bool operator< (const ClassAndSel &rhs) const
588 if (class_addr < rhs.class_addr)
590 else if (class_addr > rhs.class_addr)
594 if (sel_addr < rhs.sel_addr)
601 lldb::addr_t class_addr;
602 lldb::addr_t sel_addr;
605 typedef std::map<ClassAndSel,lldb::addr_t> MsgImplMap;
606 typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap;
607 typedef std::multimap<uint32_t, ObjCISA> HashToISAMap;
608 typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
609 typedef HashToISAMap::iterator HashToISAIterator;
611 MsgImplMap m_impl_cache;
612 LazyBool m_has_new_literals_and_indexing;
613 ISAToDescriptorMap m_isa_to_descriptor;
614 HashToISAMap m_hash_to_isa_map;
617 uint32_t m_isa_to_descriptor_stop_id;
619 typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap;
620 CompleteClassMap m_complete_class_cache;
622 struct ConstStringSetHelpers {
623 size_t operator () (const ConstString& arg) const // for hashing
625 return (size_t)arg.GetCString();
627 bool operator () (const ConstString& arg1, const ConstString& arg2) const // for equality
629 return arg1.operator==(arg2);
632 typedef std::unordered_set<ConstString, ConstStringSetHelpers, ConstStringSetHelpers> CompleteClassSet;
633 CompleteClassSet m_negative_complete_class_cache;
635 ISAToDescriptorIterator
636 GetDescriptorIterator (const ConstString &name);
638 DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime);
641 } // namespace lldb_private
643 #endif // liblldb_ObjCLanguageRuntime_h_