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