]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Target/ObjCLanguageRuntime.h
Import libcxxrt master 1cb607e89f6135bbc10f3d3b6fba1f983e258dcc.
[FreeBSD/FreeBSD.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/ClangASTType.h"
24 #include "lldb/Symbol/Type.h"
25 #include "lldb/Symbol/TypeVendor.h"
26 #include "lldb/Target/LanguageRuntime.h"
27
28 namespace lldb_private {
29     
30 class ClangUtilityFunction;
31
32 class ObjCLanguageRuntime :
33     public LanguageRuntime
34 {
35 public:
36     class MethodName
37     {
38     public:
39         enum Type
40         {
41             eTypeUnspecified,
42             eTypeClassMethod,
43             eTypeInstanceMethod
44         };
45         
46         MethodName () :
47             m_full(),
48             m_class(),
49             m_category(),
50             m_selector(),
51             m_type (eTypeUnspecified),
52             m_category_is_valid (false)
53         {
54         }
55
56         MethodName (const char *name, bool strict) :
57             m_full(),
58             m_class(),
59             m_category(),
60             m_selector(),
61             m_type (eTypeUnspecified),
62             m_category_is_valid (false)
63         {
64             SetName (name, strict);
65         }
66
67         void
68         Clear();
69
70         bool
71         IsValid (bool strict) const
72         {
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)
76                 return false;
77             // Other than that, m_full will only be filled in if the objective C
78             // name is valid.
79             return (bool)m_full;
80         }
81         
82         bool
83         HasCategory()
84         {
85             return (bool)GetCategory();
86         }
87
88         Type
89         GetType () const
90         {
91             return m_type;
92         }
93         
94         const ConstString &
95         GetFullName () const
96         {
97             return m_full;
98         }
99         
100         ConstString
101         GetFullNameWithoutCategory (bool empty_if_no_category);
102
103         bool
104         SetName (const char *name, bool strict);
105
106         const ConstString &
107         GetClassName ();
108
109         const ConstString &
110         GetClassNameWithCategory ();
111
112         const ConstString &
113         GetCategory ();
114         
115         const ConstString &
116         GetSelector ();
117
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:]"
127         size_t
128         GetFullNames (std::vector<ConstString> &names, bool append);
129     protected:
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:"
135         Type m_type;
136         bool m_category_is_valid;
137
138     };
139     typedef lldb::addr_t ObjCISA;
140     
141     class ClassDescriptor;
142     typedef std::shared_ptr<ClassDescriptor> ClassDescriptorSP;
143     
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
148     {
149     public:
150         
151         ClassDescriptor() :
152             m_is_kvo (eLazyBoolCalculate),
153             m_is_cf (eLazyBoolCalculate),
154             m_type_wp ()
155         {
156         }
157
158         virtual
159         ~ClassDescriptor ()
160         {
161         }
162         
163         virtual ConstString
164         GetClassName () = 0;
165         
166         virtual ClassDescriptorSP
167         GetSuperclass () = 0;
168         
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
171         virtual bool
172         IsKVO ()
173         {
174             if (m_is_kvo == eLazyBoolCalculate)
175             {
176                 const char* class_name = GetClassName().AsCString();
177                 if (class_name && *class_name)
178                     m_is_kvo = (LazyBool)(strstr(class_name,"NSKVONotifying_") == class_name);
179             }
180             return (m_is_kvo == eLazyBoolYes);
181         }
182         
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
185         virtual bool
186         IsCFType ()
187         {
188             if (m_is_cf == eLazyBoolCalculate)
189             {
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);
194             }
195             return (m_is_cf == eLazyBoolYes);
196         }
197         
198         virtual bool
199         IsValid () = 0;
200         
201         virtual bool
202         GetTaggedPointerInfo (uint64_t* info_bits = NULL,
203                               uint64_t* value_bits = NULL,
204                               uint64_t* payload = NULL) = 0;
205         
206         virtual uint64_t
207         GetInstanceSize () = 0;
208         
209         // use to implement version-specific additional constraints on pointers
210         virtual bool
211         CheckPointer (lldb::addr_t value,
212                       uint32_t ptr_size) const
213         {
214             return true;
215         }
216         
217         virtual ObjCISA
218         GetISA () = 0;
219         
220         // This should return true iff the interface could be completed
221         virtual bool
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
226         {
227             return false;
228         }
229         
230         lldb::TypeSP
231         GetType ()
232         {
233             return m_type_wp.lock();
234         }
235         
236         void
237         SetType (const lldb::TypeSP &type_sp)
238         {
239             m_type_wp = type_sp;
240         }
241         
242         struct iVarDescriptor {
243             ConstString m_name;
244             ClangASTType m_type;
245             uint64_t m_size;
246             int32_t m_offset;
247         };
248         
249         virtual size_t
250         GetNumIVars ()
251         {
252             return 0;
253         }
254         
255         virtual iVarDescriptor
256         GetIVarAtIndex (size_t idx)
257         {
258             return iVarDescriptor();
259         }
260         
261     protected:
262         bool
263         IsPointerValid (lldb::addr_t value,
264                         uint32_t ptr_size,
265                         bool allow_NULLs = false,
266                         bool allow_tagged = false,
267                         bool check_version_specific = false) const;
268         
269     private:
270         LazyBool m_is_kvo;
271         LazyBool m_is_cf;
272         lldb::TypeWP m_type_wp;
273     };
274     
275     class EncodingToType
276     {
277     public:
278         virtual ClangASTType RealizeType (ClangASTContext& ast_ctx, const char* name, bool allow_unknownanytype);
279         virtual ClangASTType RealizeType (const char* name, bool allow_unknownanytype);
280         
281         virtual ClangASTType RealizeType (clang::ASTContext& ast_ctx, const char* name, bool allow_unknownanytype) = 0;
282         
283         virtual ~EncodingToType();
284         
285     protected:
286         std::unique_ptr<ClangASTContext> m_scratch_ast_ctx_ap;
287     };
288     
289     typedef std::shared_ptr<EncodingToType> EncodingToTypeSP;
290     
291     virtual EncodingToTypeSP
292     GetEncodingToType ();
293     
294     virtual ClassDescriptorSP
295     GetClassDescriptor (ValueObject& in_value);
296     
297     ClassDescriptorSP
298     GetNonKVOClassDescriptor (ValueObject& in_value);
299
300     virtual ClassDescriptorSP
301     GetClassDescriptorFromClassName (const ConstString &class_name);
302
303     virtual ClassDescriptorSP
304     GetClassDescriptorFromISA (ObjCISA isa);
305
306     ClassDescriptorSP
307     GetNonKVOClassDescriptor (ObjCISA isa);
308     
309     virtual
310     ~ObjCLanguageRuntime();
311     
312     virtual lldb::LanguageType
313     GetLanguageType () const
314     {
315         return lldb::eLanguageTypeObjC;
316     }
317     
318     virtual bool
319     IsModuleObjCLibrary (const lldb::ModuleSP &module_sp) = 0;
320     
321     virtual bool
322     ReadObjCLibrary (const lldb::ModuleSP &module_sp) = 0;
323     
324     virtual bool
325     HasReadObjCLibrary () = 0;
326     
327     virtual lldb::ThreadPlanSP
328     GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0;
329
330     lldb::addr_t
331     LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t sel);
332
333     void
334     AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr);
335     
336     TypeAndOrName
337     LookupInClassNameCache (lldb::addr_t class_addr);
338     
339     void
340     AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp);
341     
342     void
343     AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_or_type_name);
344     
345     lldb::TypeSP
346     LookupInCompleteClassCache (ConstString &name);
347     
348     virtual ClangUtilityFunction *
349     CreateObjectChecker (const char *) = 0;
350     
351     virtual ObjCRuntimeVersions
352     GetRuntimeVersion ()
353     {
354         return eObjC_VersionUnknown;
355     }
356         
357     bool
358     IsValidISA(ObjCISA isa)
359     {
360         UpdateISAToDescriptorMap();
361         return m_isa_to_descriptor.count(isa) > 0;
362     }
363
364     virtual void
365     UpdateISAToDescriptorMapIfNeeded() = 0;
366
367     void
368     UpdateISAToDescriptorMap()
369     {
370         if (m_process && m_process->GetStopID() != m_isa_to_descriptor_stop_id)
371         {
372             UpdateISAToDescriptorMapIfNeeded ();
373         }
374     }
375     
376     virtual ObjCISA
377     GetISA(const ConstString &name);
378     
379     virtual ConstString
380     GetActualTypeName(ObjCISA isa);
381     
382     virtual ObjCISA
383     GetParentClass(ObjCISA isa);
384     
385     virtual TypeVendor *
386     GetTypeVendor()
387     {
388         return NULL;
389     }
390     
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.
393     
394     virtual size_t
395     GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name);
396     
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.
400     virtual lldb::addr_t
401     LookupRuntimeSymbol (const ConstString &name)
402     {
403         return LLDB_INVALID_ADDRESS;
404     }
405     
406     //------------------------------------------------------------------
407     /// Chop up an objective C function prototype.
408     ///
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
412     ///
413     /// @param[in] name
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]"
422     ///         
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)"
430     ///
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:
434     ///         "init"
435     ///         "addString:inRect:"
436     ///         "sizeWithAttributes:"
437     ///         "usesFontLeading"
438     ///
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:
444     ///         <empty>
445     ///         <empty>
446     ///         "-[NSString sizeWithAttributes:]"
447     ///         "+[NSString usesFontLeading]"
448     ///
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:
454     ///         <empty>
455     ///         <empty>
456     ///         "NSString"
457     ///         "NSString"
458     ///
459     /// @return
460     ///     Returns the number of strings that were successfully filled
461     ///     in.
462     //------------------------------------------------------------------
463 //    static uint32_t
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)
469     
470     static bool
471     IsPossibleObjCMethodName (const char *name)
472     {
473         if (!name)
474             return false;
475         bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '[';
476         bool ends_right = (name[strlen(name) - 1] == ']');
477         return (starts_right && ends_right);
478     }
479     
480     static bool
481     IsPossibleObjCSelector (const char *name)
482     {
483         if (!name)
484             return false;
485             
486         if (strchr(name, ':') == NULL)
487             return true;
488         else if (name[strlen(name) - 1] == ':')
489             return true;
490         else
491             return false;
492     }
493     
494     bool
495     HasNewLiteralsAndIndexing ()
496     {
497         if (m_has_new_literals_and_indexing == eLazyBoolCalculate)
498         {
499             if (CalculateHasNewLiteralsAndIndexing())
500                 m_has_new_literals_and_indexing = eLazyBoolYes;
501             else
502                 m_has_new_literals_and_indexing = eLazyBoolNo;
503         }
504         
505         return (m_has_new_literals_and_indexing == eLazyBoolYes);
506     }
507     
508     virtual void
509     SymbolsDidLoad (const ModuleList& module_list)
510     {
511         m_negative_complete_class_cache.clear();
512     }
513     
514 protected:
515     //------------------------------------------------------------------
516     // Classes that inherit from ObjCLanguageRuntime can see and modify these
517     //------------------------------------------------------------------
518     ObjCLanguageRuntime(Process *process);
519     
520     virtual bool CalculateHasNewLiteralsAndIndexing()
521     {
522         return false;
523     }
524     
525     
526     bool
527     ISAIsCached (ObjCISA isa) const
528     {
529         return m_isa_to_descriptor.find(isa) != m_isa_to_descriptor.end();
530     }
531
532     bool
533     AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp)
534     {
535         if (isa != 0)
536         {
537             m_isa_to_descriptor[isa] = descriptor_sp;
538             return true;
539         }
540         return false;
541     }
542
543     bool
544     AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name);
545
546     bool
547     AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, uint32_t class_name_hash)
548     {
549         if (isa != 0)
550         {
551             m_isa_to_descriptor[isa] = descriptor_sp;
552             m_hash_to_isa_map.insert(std::make_pair(class_name_hash, isa));
553             return true;
554         }
555         return false;
556     }
557
558 private:
559     // We keep a map of <Class,Selector>->Implementation so we don't have to call the resolver
560     // function over and over.
561     
562     // FIXME: We need to watch for the loading of Protocols, and flush the cache for any
563     // class that we see so changed.
564     
565     struct ClassAndSel
566     {
567         ClassAndSel()
568         {
569             sel_addr = LLDB_INVALID_ADDRESS;
570             class_addr = LLDB_INVALID_ADDRESS;
571         }
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)
575         {
576         }
577         bool operator== (const ClassAndSel &rhs)
578         {
579             if (class_addr == rhs.class_addr
580                 && sel_addr == rhs.sel_addr)
581                 return true;
582             else
583                 return false;
584         }
585         
586         bool operator< (const ClassAndSel &rhs) const
587         {
588             if (class_addr < rhs.class_addr)
589                 return true;
590             else if (class_addr > rhs.class_addr)
591                 return false;
592             else
593             {
594                 if (sel_addr < rhs.sel_addr)
595                     return true;
596                 else
597                     return false;
598             }
599         }
600         
601         lldb::addr_t class_addr;
602         lldb::addr_t sel_addr;
603     };
604
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;
610
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;
615
616 protected:
617     uint32_t m_isa_to_descriptor_stop_id;
618
619     typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap;
620     CompleteClassMap m_complete_class_cache;
621     
622     struct ConstStringSetHelpers {
623         size_t operator () (const ConstString& arg) const // for hashing
624         {
625             return (size_t)arg.GetCString();
626         }
627         bool operator () (const ConstString& arg1, const ConstString& arg2) const // for equality
628         {
629             return arg1.operator==(arg2);
630         }
631     };
632     typedef std::unordered_set<ConstString, ConstStringSetHelpers, ConstStringSetHelpers> CompleteClassSet;
633     CompleteClassSet m_negative_complete_class_cache;
634
635     ISAToDescriptorIterator
636     GetDescriptorIterator (const ConstString &name);
637
638     DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime);
639 };
640
641 } // namespace lldb_private
642
643 #endif  // liblldb_ObjCLanguageRuntime_h_