]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/include/lldb/Target/ObjCLanguageRuntime.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / include / lldb / Target / ObjCLanguageRuntime.h
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 <functional>
16 #include <map>
17 #include <unordered_set>
18
19 // Other libraries and framework includes
20 // Project includes
21 #include "lldb/lldb-private.h"
22 #include "lldb/Core/PluginInterface.h"
23 #include "lldb/Symbol/Type.h"
24 #include "lldb/Symbol/TypeVendor.h"
25 #include "lldb/Target/LanguageRuntime.h"
26
27 namespace lldb_private {
28     
29 class ClangUtilityFunction;
30
31 class ObjCLanguageRuntime :
32     public LanguageRuntime
33 {
34 public:
35     class MethodName
36     {
37     public:
38         enum Type
39         {
40             eTypeUnspecified,
41             eTypeClassMethod,
42             eTypeInstanceMethod
43         };
44         
45         MethodName () :
46             m_full(),
47             m_class(),
48             m_category(),
49             m_selector(),
50             m_type (eTypeUnspecified),
51             m_category_is_valid (false)
52         {
53         }
54
55         MethodName (const char *name, bool strict) :
56             m_full(),
57             m_class(),
58             m_category(),
59             m_selector(),
60             m_type (eTypeUnspecified),
61             m_category_is_valid (false)
62         {
63             SetName (name, strict);
64         }
65
66         void
67         Clear();
68
69         bool
70         IsValid (bool strict) const
71         {
72             // If "strict" is true, the name must have everything specified including
73             // the leading "+" or "-" on the method name
74             if (strict && m_type == eTypeUnspecified)
75                 return false;
76             // Other than that, m_full will only be filled in if the objective C
77             // name is valid.
78             return (bool)m_full;
79         }
80         
81         bool
82         HasCategory()
83         {
84             return (bool)GetCategory();
85         }
86
87         Type
88         GetType () const
89         {
90             return m_type;
91         }
92         
93         const ConstString &
94         GetFullName () const
95         {
96             return m_full;
97         }
98         
99         ConstString
100         GetFullNameWithoutCategory (bool empty_if_no_category);
101
102         bool
103         SetName (const char *name, bool strict);
104
105         const ConstString &
106         GetClassName ();
107
108         const ConstString &
109         GetClassNameWithCategory ();
110
111         const ConstString &
112         GetCategory ();
113         
114         const ConstString &
115         GetSelector ();
116
117         // Get all possible names for a method. Examples:
118         // If name is "+[NSString(my_additions) myStringWithCString:]"
119         //  names[0] => "+[NSString(my_additions) myStringWithCString:]"
120         //  names[1] => "+[NSString myStringWithCString:]"
121         // If name is specified without the leading '+' or '-' like "[NSString(my_additions) myStringWithCString:]"
122         //  names[0] => "+[NSString(my_additions) myStringWithCString:]"
123         //  names[1] => "-[NSString(my_additions) myStringWithCString:]"
124         //  names[2] => "+[NSString myStringWithCString:]"
125         //  names[3] => "-[NSString myStringWithCString:]"
126         size_t
127         GetFullNames (std::vector<ConstString> &names, bool append);
128     protected:
129         ConstString m_full;     // Full name:   "+[NSString(my_additions) myStringWithCString:]"
130         ConstString m_class;    // Class name:  "NSString"
131         ConstString m_class_category; // Class with category: "NSString(my_additions)"
132         ConstString m_category; // Category:    "my_additions"
133         ConstString m_selector; // Selector:    "myStringWithCString:"
134         Type m_type;
135         bool m_category_is_valid;
136
137     };
138     typedef lldb::addr_t ObjCISA;
139     
140     class ClassDescriptor;
141     typedef std::shared_ptr<ClassDescriptor> ClassDescriptorSP;
142     
143     // the information that we want to support retrieving from an ObjC class
144     // this needs to be pure virtual since there are at least 2 different implementations
145     // of the runtime, and more might come
146     class ClassDescriptor
147     {
148     public:
149         
150         ClassDescriptor() :
151             m_is_kvo (eLazyBoolCalculate),
152             m_is_cf (eLazyBoolCalculate),
153             m_type_wp ()
154         {
155         }
156
157         virtual
158         ~ClassDescriptor ()
159         {
160         }
161         
162         virtual ConstString
163         GetClassName () = 0;
164         
165         virtual ClassDescriptorSP
166         GetSuperclass () = 0;
167         
168         // virtual if any implementation has some other version-specific rules
169         // but for the known v1/v2 this is all that needs to be done
170         virtual bool
171         IsKVO ()
172         {
173             if (m_is_kvo == eLazyBoolCalculate)
174             {
175                 const char* class_name = GetClassName().AsCString();
176                 if (class_name && *class_name)
177                     m_is_kvo = (LazyBool)(strstr(class_name,"NSKVONotifying_") == class_name);
178             }
179             return (m_is_kvo == eLazyBoolYes);
180         }
181         
182         // virtual if any implementation has some other version-specific rules
183         // but for the known v1/v2 this is all that needs to be done
184         virtual bool
185         IsCFType ()
186         {
187             if (m_is_cf == eLazyBoolCalculate)
188             {
189                 const char* class_name = GetClassName().AsCString();
190                 if (class_name && *class_name)
191                     m_is_cf = (LazyBool)(strcmp(class_name,"__NSCFType") == 0 ||
192                                          strcmp(class_name,"NSCFType") == 0);
193             }
194             return (m_is_cf == eLazyBoolYes);
195         }
196         
197         virtual bool
198         IsValid () = 0;
199         
200         virtual bool
201         GetTaggedPointerInfo (uint64_t* info_bits = NULL,
202                               uint64_t* value_bits = NULL,
203                               uint64_t* payload = NULL) = 0;
204         
205         virtual uint64_t
206         GetInstanceSize () = 0;
207         
208         // use to implement version-specific additional constraints on pointers
209         virtual bool
210         CheckPointer (lldb::addr_t value,
211                       uint32_t ptr_size) const
212         {
213             return true;
214         }
215         
216         virtual ObjCISA
217         GetISA () = 0;
218         
219         // This should return true iff the interface could be completed
220         virtual bool
221         Describe (std::function <void (ObjCISA)> const &superclass_func,
222                   std::function <bool (const char*, const char*)> const &instance_method_func,
223                   std::function <bool (const char*, const char*)> const &class_method_func,
224                   std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func)
225         {
226             return false;
227         }
228         
229         lldb::TypeSP
230         GetType ()
231         {
232             return m_type_wp.lock();
233         }
234         
235         void
236         SetType (const lldb::TypeSP &type_sp)
237         {
238             m_type_wp = type_sp;
239         }
240         
241     protected:
242         bool
243         IsPointerValid (lldb::addr_t value,
244                         uint32_t ptr_size,
245                         bool allow_NULLs = false,
246                         bool allow_tagged = false,
247                         bool check_version_specific = false) const;
248         
249     private:
250         LazyBool m_is_kvo;
251         LazyBool m_is_cf;
252         lldb::TypeWP m_type_wp;
253     };
254     
255     virtual ClassDescriptorSP
256     GetClassDescriptor (ValueObject& in_value);
257     
258     ClassDescriptorSP
259     GetNonKVOClassDescriptor (ValueObject& in_value);
260
261     virtual ClassDescriptorSP
262     GetClassDescriptorFromClassName (const ConstString &class_name);
263
264     virtual ClassDescriptorSP
265     GetClassDescriptorFromISA (ObjCISA isa);
266
267     ClassDescriptorSP
268     GetNonKVOClassDescriptor (ObjCISA isa);
269     
270     virtual
271     ~ObjCLanguageRuntime();
272     
273     virtual lldb::LanguageType
274     GetLanguageType () const
275     {
276         return lldb::eLanguageTypeObjC;
277     }
278     
279     virtual bool
280     IsModuleObjCLibrary (const lldb::ModuleSP &module_sp) = 0;
281     
282     virtual bool
283     ReadObjCLibrary (const lldb::ModuleSP &module_sp) = 0;
284     
285     virtual bool
286     HasReadObjCLibrary () = 0;
287     
288     virtual lldb::ThreadPlanSP
289     GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0;
290
291     lldb::addr_t
292     LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t sel);
293
294     void
295     AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr);
296     
297     TypeAndOrName
298     LookupInClassNameCache (lldb::addr_t class_addr);
299     
300     void
301     AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp);
302     
303     void
304     AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_or_type_name);
305     
306     lldb::TypeSP
307     LookupInCompleteClassCache (ConstString &name);
308     
309     virtual ClangUtilityFunction *
310     CreateObjectChecker (const char *) = 0;
311     
312     virtual ObjCRuntimeVersions
313     GetRuntimeVersion ()
314     {
315         return eObjC_VersionUnknown;
316     }
317         
318     bool
319     IsValidISA(ObjCISA isa)
320     {
321         UpdateISAToDescriptorMap();
322         return m_isa_to_descriptor.count(isa) > 0;
323     }
324
325     virtual void
326     UpdateISAToDescriptorMapIfNeeded() = 0;
327
328     void
329     UpdateISAToDescriptorMap()
330     {
331         if (m_process && m_process->GetStopID() != m_isa_to_descriptor_stop_id)
332         {
333             UpdateISAToDescriptorMapIfNeeded ();
334         }
335     }
336     
337     virtual ObjCISA
338     GetISA(const ConstString &name);
339     
340     virtual ConstString
341     GetActualTypeName(ObjCISA isa);
342     
343     virtual ObjCISA
344     GetParentClass(ObjCISA isa);
345     
346     virtual TypeVendor *
347     GetTypeVendor()
348     {
349         return NULL;
350     }
351     
352     // Finds the byte offset of the child_type ivar in parent_type.  If it can't find the
353     // offset, returns LLDB_INVALID_IVAR_OFFSET.
354     
355     virtual size_t
356     GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name);
357     
358     // Given the name of an Objective-C runtime symbol (e.g., ivar offset symbol),
359     // try to determine from the runtime what the value of that symbol would be.
360     // Useful when the underlying binary is stripped.
361     virtual lldb::addr_t
362     LookupRuntimeSymbol (const ConstString &name)
363     {
364         return LLDB_INVALID_ADDRESS;
365     }
366     
367     //------------------------------------------------------------------
368     /// Chop up an objective C function prototype.
369     ///
370     /// Chop up an objective C function fullname and optionally fill in
371     /// any non-NULL ConstString objects. If a ConstString * is NULL,
372     /// then this name doesn't get filled in
373     ///
374     /// @param[in] name
375     ///     A fully specified objective C function name. The string might
376     ///     contain a category and it includes the leading "+" or "-" and
377     ///     the square brackets, no types for the arguments, just the plain
378     ///     selector. A few examples:
379     ///         "-[NSStringDrawingContext init]"
380     ///         "-[NSStringDrawingContext addString:inRect:]"
381     ///         "-[NSString(NSStringDrawing) sizeWithAttributes:]"
382     ///         "+[NSString(NSStringDrawing) usesFontLeading]"
383     ///         
384     /// @param[out] class_name
385     ///     If non-NULL, this string will be filled in with the class
386     ///     name including the category. The examples above would return:
387     ///         "NSStringDrawingContext"
388     ///         "NSStringDrawingContext"
389     ///         "NSString(NSStringDrawing)"
390     ///         "NSString(NSStringDrawing)"
391     ///
392     /// @param[out] selector_name
393     ///     If non-NULL, this string will be filled in with the selector
394     ///     name. The examples above would return:
395     ///         "init"
396     ///         "addString:inRect:"
397     ///         "sizeWithAttributes:"
398     ///         "usesFontLeading"
399     ///
400     /// @param[out] name_sans_category
401     ///     If non-NULL, this string will be filled in with the class
402     ///     name _without_ the category. If there is no category, and empty
403     ///     string will be returned (as the result would be normally returned
404     ///     in the "class_name" argument). The examples above would return:
405     ///         <empty>
406     ///         <empty>
407     ///         "-[NSString sizeWithAttributes:]"
408     ///         "+[NSString usesFontLeading]"
409     ///
410     /// @param[out] class_name_sans_category
411     ///     If non-NULL, this string will be filled in with the prototype
412     ///     name _without_ the category. If there is no category, and empty
413     ///     string will be returned (as this is already the value that was
414     ///     passed in). The examples above would return:
415     ///         <empty>
416     ///         <empty>
417     ///         "NSString"
418     ///         "NSString"
419     ///
420     /// @return
421     ///     Returns the number of strings that were successfully filled
422     ///     in.
423     //------------------------------------------------------------------
424 //    static uint32_t
425 //    ParseMethodName (const char *name, 
426 //                     ConstString *class_name,               // Class name (with category if there is one)
427 //                     ConstString *selector_name,            // selector only
428 //                     ConstString *name_sans_category,       // full function name with no category (empty if no category)
429 //                     ConstString *class_name_sans_category);// Class name without category (empty if no category)
430     
431     static bool
432     IsPossibleObjCMethodName (const char *name)
433     {
434         if (!name)
435             return false;
436         bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '[';
437         bool ends_right = (name[strlen(name) - 1] == ']');
438         return (starts_right && ends_right);
439     }
440     
441     static bool
442     IsPossibleObjCSelector (const char *name)
443     {
444         if (!name)
445             return false;
446             
447         if (strchr(name, ':') == NULL)
448             return true;
449         else if (name[strlen(name) - 1] == ':')
450             return true;
451         else
452             return false;
453     }
454     
455     bool
456     HasNewLiteralsAndIndexing ()
457     {
458         if (m_has_new_literals_and_indexing == eLazyBoolCalculate)
459         {
460             if (CalculateHasNewLiteralsAndIndexing())
461                 m_has_new_literals_and_indexing = eLazyBoolYes;
462             else
463                 m_has_new_literals_and_indexing = eLazyBoolNo;
464         }
465         
466         return (m_has_new_literals_and_indexing == eLazyBoolYes);
467     }
468     
469     virtual void
470     SymbolsDidLoad (const ModuleList& module_list)
471     {
472         m_negative_complete_class_cache.clear();
473     }
474     
475 protected:
476     //------------------------------------------------------------------
477     // Classes that inherit from ObjCLanguageRuntime can see and modify these
478     //------------------------------------------------------------------
479     ObjCLanguageRuntime(Process *process);
480     
481     virtual bool CalculateHasNewLiteralsAndIndexing()
482     {
483         return false;
484     }
485     
486     
487     bool
488     ISAIsCached (ObjCISA isa) const
489     {
490         return m_isa_to_descriptor.find(isa) != m_isa_to_descriptor.end();
491     }
492
493     bool
494     AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp)
495     {
496         if (isa != 0)
497         {
498             m_isa_to_descriptor[isa] = descriptor_sp;
499             return true;
500         }
501         return false;
502     }
503
504     bool
505     AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name);
506
507     bool
508     AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, uint32_t class_name_hash)
509     {
510         if (isa != 0)
511         {
512             m_isa_to_descriptor[isa] = descriptor_sp;
513             m_hash_to_isa_map.insert(std::make_pair(class_name_hash, isa));
514             return true;
515         }
516         return false;
517     }
518
519 private:
520     // We keep a map of <Class,Selector>->Implementation so we don't have to call the resolver
521     // function over and over.
522     
523     // FIXME: We need to watch for the loading of Protocols, and flush the cache for any
524     // class that we see so changed.
525     
526     struct ClassAndSel
527     {
528         ClassAndSel()
529         {
530             sel_addr = LLDB_INVALID_ADDRESS;
531             class_addr = LLDB_INVALID_ADDRESS;
532         }
533         ClassAndSel (lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr) :
534             class_addr (in_class_addr),
535             sel_addr(in_sel_addr)
536         {
537         }
538         bool operator== (const ClassAndSel &rhs)
539         {
540             if (class_addr == rhs.class_addr
541                 && sel_addr == rhs.sel_addr)
542                 return true;
543             else
544                 return false;
545         }
546         
547         bool operator< (const ClassAndSel &rhs) const
548         {
549             if (class_addr < rhs.class_addr)
550                 return true;
551             else if (class_addr > rhs.class_addr)
552                 return false;
553             else
554             {
555                 if (sel_addr < rhs.sel_addr)
556                     return true;
557                 else
558                     return false;
559             }
560         }
561         
562         lldb::addr_t class_addr;
563         lldb::addr_t sel_addr;
564     };
565
566     typedef std::map<ClassAndSel,lldb::addr_t> MsgImplMap;
567     typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap;
568     typedef std::multimap<uint32_t, ObjCISA> HashToISAMap;
569     typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
570     typedef HashToISAMap::iterator HashToISAIterator;
571
572     MsgImplMap m_impl_cache;
573     LazyBool m_has_new_literals_and_indexing;
574     ISAToDescriptorMap m_isa_to_descriptor;
575     HashToISAMap m_hash_to_isa_map;
576
577 protected:
578     uint32_t m_isa_to_descriptor_stop_id;
579
580     typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap;
581     CompleteClassMap m_complete_class_cache;
582     
583     struct ConstStringSetHelpers {
584         size_t operator () (const ConstString& arg) const // for hashing
585         {
586             return (size_t)arg.GetCString();
587         }
588         bool operator () (const ConstString& arg1, const ConstString& arg2) const // for equality
589         {
590             return arg1.operator==(arg2);
591         }
592     };
593     typedef std::unordered_set<ConstString, ConstStringSetHelpers, ConstStringSetHelpers> CompleteClassSet;
594     CompleteClassSet m_negative_complete_class_cache;
595
596     ISAToDescriptorIterator
597     GetDescriptorIterator (const ConstString &name);
598
599     DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime);
600 };
601
602 } // namespace lldb_private
603
604 #endif  // liblldb_ObjCLanguageRuntime_h_