19b8ff51183563d68818795caef3174d4fc2c2c1dGreg Clayton//===-- ObjCLanguageRuntime.cpp ---------------------------------*- C++ -*-===//
2642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//
3642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//                     The LLVM Compiler Infrastructure
4642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//
5642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// This file is distributed under the University of Illinois Open Source
6642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// License. See LICENSE.TXT for details.
7642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//
8642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//===----------------------------------------------------------------------===//
9324067bc91877dbbd6ec3a8663914fa3dbb7e3c9Jim Ingham#include "clang/AST/Type.h"
10642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
11b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Core/Log.h"
12ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton#include "lldb/Core/MappedHash.h"
1349ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Core/Module.h"
14642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham#include "lldb/Core/PluginManager.h"
15f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton#include "lldb/Core/Timer.h"
16324067bc91877dbbd6ec3a8663914fa3dbb7e3c9Jim Ingham#include "lldb/Core/ValueObject.h"
17324067bc91877dbbd6ec3a8663914fa3dbb7e3c9Jim Ingham#include "lldb/Symbol/ClangASTContext.h"
18ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham#include "lldb/Symbol/Type.h"
1949ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Symbol/TypeList.h"
20b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham#include "lldb/Target/ObjCLanguageRuntime.h"
21931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan#include "lldb/Target/Target.h"
22642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
23f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton#include "llvm/ADT/StringRef.h"
24f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
25642036f22366d47ea8e6f8498bedb92b88f7f79fJim Inghamusing namespace lldb;
26642036f22366d47ea8e6f8498bedb92b88f7f79fJim Inghamusing namespace lldb_private;
27642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
28642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//----------------------------------------------------------------------
29642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham// Destructor
30642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham//----------------------------------------------------------------------
31642036f22366d47ea8e6f8498bedb92b88f7f79fJim InghamObjCLanguageRuntime::~ObjCLanguageRuntime()
32642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham{
33642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham}
34642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
35642036f22366d47ea8e6f8498bedb92b88f7f79fJim InghamObjCLanguageRuntime::ObjCLanguageRuntime (Process *process) :
366e12c7a5a851f661677b16c544aac2f93fb6e86dSean Callanan    LanguageRuntime (process),
376fe8d36ff420335095d437b35ff96fe4b7cd3ed9Sean Callanan    m_has_new_literals_and_indexing (eLazyBoolCalculate),
38ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    m_isa_to_descriptor(),
39ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    m_isa_to_descriptor_stop_id (UINT32_MAX)
40642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham{
41642036f22366d47ea8e6f8498bedb92b88f7f79fJim Ingham
42b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham}
43b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham
44ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Claytonbool
45ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg ClaytonObjCLanguageRuntime::AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name)
46ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
47ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (isa != 0)
48ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
49ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        m_isa_to_descriptor[isa] = descriptor_sp;
50ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        // class_name is assumed to be valid
51ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        m_hash_to_isa_map.insert(std::make_pair(MappedHash::HashStringUsingDJB(class_name), isa));
52ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return true;
53ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
54ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    return false;
55ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton}
56ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
57b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Inghamvoid
58b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim InghamObjCLanguageRuntime::AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t selector, lldb::addr_t impl_addr)
59b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham{
60952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
61b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham    if (log)
62b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham    {
635f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        log->Printf ("Caching: class 0x%" PRIx64 " selector 0x%" PRIx64 " implementation 0x%" PRIx64 ".", class_addr, selector, impl_addr);
64b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham    }
65b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham    m_impl_cache.insert (std::pair<ClassAndSel,lldb::addr_t> (ClassAndSel(class_addr, selector), impl_addr));
66b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham}
67b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham
68b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Inghamlldb::addr_t
69b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim InghamObjCLanguageRuntime::LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t selector)
70b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham{
71b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham    MsgImplMap::iterator pos, end = m_impl_cache.end();
72b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham    pos = m_impl_cache.find (ClassAndSel(class_addr, selector));
73b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham    if (pos != end)
74b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham        return (*pos).second;
75b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham    return LLDB_INVALID_ADDRESS;
76b66cd074ec097b5b0a6f2ce292f5072aa1217ca6Jim Ingham}
77ef80aabe53b7fdf61309ba6d3d6865c94c681345Jim Ingham
7858513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
79931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callananlldb::TypeSP
80931acecd4e3af534028936431dc0f75a9fd6eb02Sean CallananObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name)
81931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan{
82931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan    CompleteClassMap::iterator complete_class_iter = m_complete_class_cache.find(name);
83931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan
84931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan    if (complete_class_iter != m_complete_class_cache.end())
85931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan    {
86ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        // Check the weak pointer to make sure the type hasn't been unloaded
87ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        TypeSP complete_type_sp (complete_class_iter->second.lock());
88931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan
89ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        if (complete_type_sp)
90ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton            return complete_type_sp;
91931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan        else
92ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton            m_complete_class_cache.erase(name);
93931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan    }
94931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan
9512fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata    if (m_negative_complete_class_cache.count(name) > 0)
9612fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata        return TypeSP();
9712fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata
98146d9522c95c0c8c5409539813b55e08b99196eeEnrico Granata    const ModuleList &modules = m_process->GetTarget().GetImages();
99ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton
100931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan    SymbolContextList sc_list;
101ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton    const size_t matching_symbols = modules.FindSymbolsWithNameAndType (name,
102ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                                                                        eSymbolTypeObjCClass,
103ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                                                                        sc_list);
104931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan
105ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton    if (matching_symbols)
106931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan    {
107ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        SymbolContext sc;
108931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan
109ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        sc_list.GetContextAtIndex(0, sc);
110ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton
111ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        ModuleSP module_sp(sc.module_sp);
112ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton
113ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        if (!module_sp)
114931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan            return TypeSP();
115931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan
116ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        const SymbolContext null_sc;
117ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        const bool exact_match = true;
118ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        const uint32_t max_matches = UINT32_MAX;
119ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        TypeList types;
120ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton
121ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        const uint32_t num_types = module_sp->FindTypes (null_sc,
122ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                                                         name,
123ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                                                         exact_match,
124ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                                                         max_matches,
125ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                                                         types);
126ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton
127ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton        if (num_types)
128282c22c6a6b6e54324b0d474b90d918bbfd3a10eSean Callanan        {
129ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton            uint32_t i;
130ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton            for (i = 0; i < num_types; ++i)
131ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton            {
132ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                TypeSP type_sp (types.GetTypeAtIndex(i));
133ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton
13452f792329be5db8e38961350589e97e8f2823acdGreg Clayton                if (type_sp->GetClangForwardType().IsObjCObjectOrInterfaceType())
135ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                {
136ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                    if (type_sp->IsCompleteObjCClass())
137ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                    {
138ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                        m_complete_class_cache[name] = type_sp;
139ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                        return type_sp;
140ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                    }
141ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton                }
142ef22b90240618ed8056dac14a756dff574f8218aGreg Clayton            }
143931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan        }
144931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan    }
14512fbcf5bdbc54e49bf565ec067b3b484c28a52feEnrico Granata    m_negative_complete_class_cache.insert(name);
146931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan    return TypeSP();
147931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan}
148931acecd4e3af534028936431dc0f75a9fd6eb02Sean Callanan
14958513667f6765aa8db13cdc4abd500340c1cac80Jim Inghamsize_t
15058513667f6765aa8db13cdc4abd500340c1cac80Jim InghamObjCLanguageRuntime::GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name)
15158513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham{
15258513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham    return LLDB_INVALID_IVAR_OFFSET;
15358513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham}
15458513667f6765aa8db13cdc4abd500340c1cac80Jim Ingham
155f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonvoid
156f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::Clear()
157f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{
158f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    m_full.Clear();
159f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    m_class.Clear();
160f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    m_category.Clear();
161f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    m_selector.Clear();
162f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    m_type = eTypeUnspecified;
163f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    m_category_is_valid = false;
164f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton}
165f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
166f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//bool
167f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//ObjCLanguageRuntime::MethodName::SetName (const char *name, bool strict)
168f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//{
169f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//    Clear();
170f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//    if (name && name[0])
171f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//    {
172f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        // If "strict" is true. then the method must be specified with a
173f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        // '+' or '-' at the beginning. If "strict" is false, then the '+'
174f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        // or '-' can be omitted
175f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        bool valid_prefix = false;
176f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//
177f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        if (name[0] == '+' || name[0] == '-')
178f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        {
179f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//            valid_prefix = name[1] == '[';
180f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        }
181f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        else if (!strict)
182f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        {
183f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//            // "strict" is false, the name just needs to start with '['
184f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//            valid_prefix = name[0] == '[';
185f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        }
186f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//
187f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        if (valid_prefix)
188f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        {
189f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//            static RegularExpression g_regex("^([-+]?)\\[([A-Za-z_][A-Za-z_0-9]*)(\\([A-Za-z_][A-Za-z_0-9]*\\))? ([A-Za-z_][A-Za-z_0-9:]*)\\]$");
190f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//            llvm::StringRef matches[4];
191f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//            // Since we are using a global regular expression, we must use the threadsafe version of execute
192f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//            if (g_regex.ExecuteThreadSafe(name, matches, 4))
193f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//            {
194f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//                m_full.SetCString(name);
195f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//                if (matches[0].empty())
196f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//                    m_type = eTypeUnspecified;
197f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//                else if (matches[0][0] == '+')
198f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//                    m_type = eTypeClassMethod;
199f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//                else
200f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//                    m_type = eTypeInstanceMethod;
201f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//                m_class.SetString(matches[1]);
202f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//                m_selector.SetString(matches[3]);
203f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//                if (!matches[2].empty())
204f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//                    m_category.SetString(matches[2]);
205f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//            }
206f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//        }
207f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//    }
208f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//    return IsValid(strict);
209f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton//}
2103ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham
211f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonbool
212f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::SetName (const char *name, bool strict)
2133ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham{
214f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    Clear();
215f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    if (name && name[0])
216f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    {
217f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        // If "strict" is true. then the method must be specified with a
218f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        // '+' or '-' at the beginning. If "strict" is false, then the '+'
219f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        // or '-' can be omitted
220f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        bool valid_prefix = false;
221f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
222f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        if (name[0] == '+' || name[0] == '-')
223f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        {
224f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            valid_prefix = name[1] == '[';
225f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            if (name[0] == '+')
226f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                m_type = eTypeClassMethod;
227f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            else
228f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                m_type = eTypeInstanceMethod;
229f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        }
230f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        else if (!strict)
231f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        {
232f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            // "strict" is false, the name just needs to start with '['
233f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            valid_prefix = name[0] == '[';
234f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        }
235f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
236f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        if (valid_prefix)
237f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        {
238f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            int name_len = strlen (name);
239f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            // Objective C methods must have at least:
240f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            //      "-[" or "+[" prefix
241f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            //      One character for a class name
242f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            //      One character for the space between the class name
243f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            //      One character for the method name
244f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            //      "]" suffix
245f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            if (name_len >= (5 + (strict ? 1 : 0)) && name[name_len - 1] == ']')
246f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            {
247f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                m_full.SetCStringWithLength(name, name_len);
248f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            }
249f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        }
250f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    }
251f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    return IsValid(strict);
252f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton}
253662e56733faaeee932eba120d756257682f1bf04Greg Clayton
254f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonconst ConstString &
255f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::GetClassName ()
256f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{
257f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    if (!m_class)
2583ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham    {
259f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        if (IsValid(false))
2603ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham        {
261f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const char *full = m_full.GetCString();
262f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
263f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const char *paren_pos = strchr (class_start, '(');
264f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            if (paren_pos)
2653ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham            {
266f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                m_class.SetCStringWithLength (class_start, paren_pos - class_start);
267f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            }
268f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            else
269f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            {
270f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                // No '(' was found in the full name, we can definitively say
271f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                // that our category was valid (and empty).
272f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                m_category_is_valid = true;
273f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                const char *space_pos = strchr (full, ' ');
274f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                if (space_pos)
2753ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham                {
276f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                    m_class.SetCStringWithLength (class_start, space_pos - class_start);
277f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                    if (!m_class_category)
2783ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham                    {
279f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                        // No category in name, so we can also fill in the m_class_category
280f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                        m_class_category = m_class;
2813ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham                    }
2823ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham                }
2833ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham            }
2843ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham        }
2853ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham    }
286f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    return m_class;
287f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton}
288f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
289f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonconst ConstString &
290f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::GetClassNameWithCategory ()
291f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{
292f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    if (!m_class_category)
293f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    {
294f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        if (IsValid(false))
295f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        {
296f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const char *full = m_full.GetCString();
297f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
298f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const char *space_pos = strchr (full, ' ');
299f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            if (space_pos)
300f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            {
301f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                m_class_category.SetCStringWithLength (class_start, space_pos - class_start);
302f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                // If m_class hasn't been filled in and the class with category doesn't
303f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                // contain a '(', then we can also fill in the m_class
304f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                if (!m_class && strchr (m_class_category.GetCString(), '(') == NULL)
305f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                {
306f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                    m_class = m_class_category;
307f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                    // No '(' was found in the full name, we can definitively say
308f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                    // that our category was valid (and empty).
309f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                    m_category_is_valid = true;
310f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
311f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                }
312f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            }
313f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        }
314f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    }
315f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    return m_class_category;
316f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton}
317f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
318f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonconst ConstString &
319f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::GetSelector ()
320f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{
321f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    if (!m_selector)
322f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    {
323f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        if (IsValid(false))
324f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        {
325f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const char *full = m_full.GetCString();
326f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const char *space_pos = strchr (full, ' ');
327f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            if (space_pos)
328f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            {
329f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                ++space_pos; // skip the space
330f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                m_selector.SetCStringWithLength (space_pos, m_full.GetLength() - (space_pos - full) - 1);
331f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            }
332f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        }
333f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    }
334f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    return m_selector;
335f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton}
336f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
337f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonconst ConstString &
338f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::GetCategory ()
339f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{
340f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    if (!m_category_is_valid && !m_category)
341f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    {
342f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        if (IsValid(false))
343f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        {
344f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            m_category_is_valid = true;
345f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const char *full = m_full.GetCString();
346f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
347f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const char *open_paren_pos = strchr (class_start, '(');
348f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            if (open_paren_pos)
349f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            {
350f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                ++open_paren_pos; // Skip the open paren
351f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                const char *close_paren_pos = strchr (open_paren_pos, ')');
352f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                if (close_paren_pos)
353f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                    m_category.SetCStringWithLength (open_paren_pos, close_paren_pos - open_paren_pos);
354f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            }
355f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        }
356f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    }
357f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    return m_category;
358f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton}
359f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
360f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonConstString
361f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::GetFullNameWithoutCategory (bool empty_if_no_category)
362f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{
363f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    if (IsValid(false))
364f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    {
365f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        if (HasCategory())
366f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        {
367f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            StreamString strm;
368f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            if (m_type == eTypeClassMethod)
369f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                strm.PutChar('+');
370f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            else if (m_type == eTypeInstanceMethod)
371f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                strm.PutChar('-');
372f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            strm.Printf("[%s %s]", GetClassName().GetCString(), GetSelector().GetCString());
373f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            return ConstString(strm.GetString().c_str());
374f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        }
375f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
376f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        if (!empty_if_no_category)
377f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        {
378f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            // Just return the full name since it doesn't have a category
379f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            return GetFullName();
380f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        }
381f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    }
382f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    return ConstString();
383f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton}
384f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
385f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Claytonsize_t
386f892c42725ed36c97e8ce10e758170cf6f1aff83Greg ClaytonObjCLanguageRuntime::MethodName::GetFullNames (std::vector<ConstString> &names, bool append)
387f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton{
388f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    if (!append)
389f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        names.clear();
390f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    if (IsValid(false))
391f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    {
392f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        StreamString strm;
393f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        const bool is_class_method = m_type == eTypeClassMethod;
394f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        const bool is_instance_method = m_type == eTypeInstanceMethod;
395f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        const ConstString &category = GetCategory();
396f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        if (is_class_method || is_instance_method)
397f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        {
398f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            names.push_back (m_full);
399f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            if (category)
400f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            {
401f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                strm.Printf("%c[%s %s]",
402f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                            is_class_method ? '+' : '-',
403f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                            GetClassName().GetCString(),
404f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                            GetSelector().GetCString());
405f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                names.push_back(ConstString(strm.GetString().c_str()));
406f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            }
407f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        }
408f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        else
409f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        {
410f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const ConstString &class_name = GetClassName();
411f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            const ConstString &selector = GetSelector();
412f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            strm.Printf("+[%s %s]", class_name.GetCString(), selector.GetCString());
413f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            names.push_back(ConstString(strm.GetString().c_str()));
414f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            strm.Clear();
415f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString());
416f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            names.push_back(ConstString(strm.GetString().c_str()));
417f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            strm.Clear();
418f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            if (category)
419f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            {
420f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                strm.Printf("+[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
421f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                names.push_back(ConstString(strm.GetString().c_str()));
422f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                strm.Clear();
423f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                strm.Printf("-[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
424f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton                names.push_back(ConstString(strm.GetString().c_str()));
425f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton            }
426f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton        }
427f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    }
428f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton    return names.size();
4293ad4da0f2c2afdea3352deaaf9c044855dc5c95bJim Ingham}
430ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata
431f892c42725ed36c97e8ce10e758170cf6f1aff83Greg Clayton
432ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granatabool
433ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico GranataObjCLanguageRuntime::ClassDescriptor::IsPointerValid (lldb::addr_t value,
434ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata                                                      uint32_t ptr_size,
435ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata                                                      bool allow_NULLs,
436ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata                                                      bool allow_tagged,
437be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton                                                      bool check_version_specific) const
438ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata{
439ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata    if (!value)
440ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata        return allow_NULLs;
441ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata    if ( (value % 2) == 1  && allow_tagged)
442ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata        return true;
443ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata    if ((value % ptr_size) == 0)
444ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata        return (check_version_specific ? CheckPointer(value,ptr_size) : true);
445ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata    else
446ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata        return false;
447ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata}
448ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata
449ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico GranataObjCLanguageRuntime::ObjCISA
450c718b9652bb1a7aea5d133123fcc8bc87277002cSean CallananObjCLanguageRuntime::GetISA(const ConstString &name)
451c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan{
452ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ISAToDescriptorIterator pos = GetDescriptorIterator (name);
453ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (pos != m_isa_to_descriptor.end())
454ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return pos->first;
455c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan    return 0;
456c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan}
457c718b9652bb1a7aea5d133123fcc8bc87277002cSean Callanan
458ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg ClaytonObjCLanguageRuntime::ISAToDescriptorIterator
459ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg ClaytonObjCLanguageRuntime::GetDescriptorIterator (const ConstString &name)
460ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton{
461ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ISAToDescriptorIterator end = m_isa_to_descriptor.end();
462ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
463ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (name)
464ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    {
465ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        UpdateISAToDescriptorMap();
466ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (m_hash_to_isa_map.empty())
467ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
468ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            // No name hashes were provided, we need to just linearly power through the
469ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            // names and find a match
470ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            for (ISAToDescriptorIterator pos = m_isa_to_descriptor.begin(); pos != end; ++pos)
471ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            {
472ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                if (pos->second->GetClassName() == name)
473ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    return pos;
474ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            }
475ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
476ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        else
477ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        {
478ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            // Name hashes were provided, so use them to efficiently lookup name to isa/descriptor
479ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            const uint32_t name_hash = MappedHash::HashStringUsingDJB (name.GetCString());
480ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            std::pair <HashToISAIterator, HashToISAIterator> range = m_hash_to_isa_map.equal_range(name_hash);
481ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            for (HashToISAIterator range_pos = range.first; range_pos != range.second; ++range_pos)
482ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            {
483ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                ISAToDescriptorIterator pos = m_isa_to_descriptor.find (range_pos->second);
484ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                if (pos != m_isa_to_descriptor.end())
485ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                {
486ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                    if (pos->second->GetClassName() == name)
487ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                        return pos;
488ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton                }
489ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton            }
490ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        }
491ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    }
492ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    return end;
493ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton}
494ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
495ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton
496c718b9652bb1a7aea5d133123fcc8bc87277002cSean CallananObjCLanguageRuntime::ObjCISA
497ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico GranataObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa)
498ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata{
499d387b462eecb908af265ecc7006781b4532073adGreg Clayton    ClassDescriptorSP objc_class_sp (GetClassDescriptorFromISA(isa));
500be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    if (objc_class_sp)
501ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata    {
502be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        ClassDescriptorSP objc_super_class_sp (objc_class_sp->GetSuperclass());
503be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        if (objc_super_class_sp)
504be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton            return objc_super_class_sp->GetISA();
505ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata    }
506be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    return 0;
507ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata}
508ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata
509ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico GranataConstString
510ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico GranataObjCLanguageRuntime::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
511ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata{
512be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    ClassDescriptorSP objc_class_sp (GetNonKVOClassDescriptor(isa));
513be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    if (objc_class_sp)
514be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        return objc_class_sp->GetClassName();
515be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    return ConstString();
516be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton}
517be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
518be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg ClaytonObjCLanguageRuntime::ClassDescriptorSP
519d387b462eecb908af265ecc7006781b4532073adGreg ClaytonObjCLanguageRuntime::GetClassDescriptorFromClassName (const ConstString &class_name)
520be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton{
521ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    ISAToDescriptorIterator pos = GetDescriptorIterator (class_name);
522ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (pos != m_isa_to_descriptor.end())
523ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        return pos->second;
524be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    return ClassDescriptorSP();
525a510437e795477e5f629263d3d191d982c991733Greg Clayton
526be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton}
527be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
528be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg ClaytonObjCLanguageRuntime::ClassDescriptorSP
529a510437e795477e5f629263d3d191d982c991733Greg ClaytonObjCLanguageRuntime::GetClassDescriptor (ValueObject& valobj)
530be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton{
531be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    ClassDescriptorSP objc_class_sp;
532a510437e795477e5f629263d3d191d982c991733Greg Clayton    // if we get an invalid VO (which might still happen when playing around
533a510437e795477e5f629263d3d191d982c991733Greg Clayton    // with pointers returned by the expression parser, don't consider this
534a510437e795477e5f629263d3d191d982c991733Greg Clayton    // a valid ObjC object)
53552f792329be5db8e38961350589e97e8f2823acdGreg Clayton    if (valobj.GetClangType().IsValid())
536be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    {
537a510437e795477e5f629263d3d191d982c991733Greg Clayton        addr_t isa_pointer = valobj.GetPointerValue();
538a510437e795477e5f629263d3d191d982c991733Greg Clayton        if (isa_pointer != LLDB_INVALID_ADDRESS)
539a510437e795477e5f629263d3d191d982c991733Greg Clayton        {
540a510437e795477e5f629263d3d191d982c991733Greg Clayton            ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
541a510437e795477e5f629263d3d191d982c991733Greg Clayton
542a510437e795477e5f629263d3d191d982c991733Greg Clayton            Process *process = exe_ctx.GetProcessPtr();
543a510437e795477e5f629263d3d191d982c991733Greg Clayton            if (process)
544a510437e795477e5f629263d3d191d982c991733Greg Clayton            {
545a510437e795477e5f629263d3d191d982c991733Greg Clayton                Error error;
546a510437e795477e5f629263d3d191d982c991733Greg Clayton                ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
547a510437e795477e5f629263d3d191d982c991733Greg Clayton                if (isa != LLDB_INVALID_ADDRESS)
548d387b462eecb908af265ecc7006781b4532073adGreg Clayton                    objc_class_sp = GetClassDescriptorFromISA (isa);
549a510437e795477e5f629263d3d191d982c991733Greg Clayton            }
550a510437e795477e5f629263d3d191d982c991733Greg Clayton        }
551be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    }
552be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    return objc_class_sp;
553be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton}
554be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
555be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg ClaytonObjCLanguageRuntime::ClassDescriptorSP
556a510437e795477e5f629263d3d191d982c991733Greg ClaytonObjCLanguageRuntime::GetNonKVOClassDescriptor (ValueObject& valobj)
557a510437e795477e5f629263d3d191d982c991733Greg Clayton{
558a510437e795477e5f629263d3d191d982c991733Greg Clayton    ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (GetClassDescriptor (valobj));
559a510437e795477e5f629263d3d191d982c991733Greg Clayton    if (objc_class_sp)
560a510437e795477e5f629263d3d191d982c991733Greg Clayton    {
561a510437e795477e5f629263d3d191d982c991733Greg Clayton        if (!objc_class_sp->IsKVO())
562a510437e795477e5f629263d3d191d982c991733Greg Clayton            return objc_class_sp;
563a510437e795477e5f629263d3d191d982c991733Greg Clayton
564a510437e795477e5f629263d3d191d982c991733Greg Clayton        ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass());
565a510437e795477e5f629263d3d191d982c991733Greg Clayton        if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid())
566a510437e795477e5f629263d3d191d982c991733Greg Clayton            return non_kvo_objc_class_sp;
567a510437e795477e5f629263d3d191d982c991733Greg Clayton    }
568a510437e795477e5f629263d3d191d982c991733Greg Clayton    return ClassDescriptorSP();
569a510437e795477e5f629263d3d191d982c991733Greg Clayton}
570a510437e795477e5f629263d3d191d982c991733Greg Clayton
571a510437e795477e5f629263d3d191d982c991733Greg Clayton
572a510437e795477e5f629263d3d191d982c991733Greg ClaytonObjCLanguageRuntime::ClassDescriptorSP
573d387b462eecb908af265ecc7006781b4532073adGreg ClaytonObjCLanguageRuntime::GetClassDescriptorFromISA (ObjCISA isa)
574a510437e795477e5f629263d3d191d982c991733Greg Clayton{
575a510437e795477e5f629263d3d191d982c991733Greg Clayton    if (isa)
576a510437e795477e5f629263d3d191d982c991733Greg Clayton    {
577a510437e795477e5f629263d3d191d982c991733Greg Clayton        UpdateISAToDescriptorMap();
578ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        ObjCLanguageRuntime::ISAToDescriptorIterator pos = m_isa_to_descriptor.find(isa);
579ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        if (pos != m_isa_to_descriptor.end())
580a510437e795477e5f629263d3d191d982c991733Greg Clayton            return pos->second;
581a510437e795477e5f629263d3d191d982c991733Greg Clayton    }
582a510437e795477e5f629263d3d191d982c991733Greg Clayton    return ClassDescriptorSP();
583a510437e795477e5f629263d3d191d982c991733Greg Clayton}
584a510437e795477e5f629263d3d191d982c991733Greg Clayton
585a510437e795477e5f629263d3d191d982c991733Greg ClaytonObjCLanguageRuntime::ClassDescriptorSP
586be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg ClaytonObjCLanguageRuntime::GetNonKVOClassDescriptor (ObjCISA isa)
587be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton{
588be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    if (isa)
589ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata    {
590d387b462eecb908af265ecc7006781b4532073adGreg Clayton        ClassDescriptorSP objc_class_sp = GetClassDescriptorFromISA (isa);
591be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        if (objc_class_sp && objc_class_sp->IsValid())
592be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        {
593a510437e795477e5f629263d3d191d982c991733Greg Clayton            if (!objc_class_sp->IsKVO())
594be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton                return objc_class_sp;
595a510437e795477e5f629263d3d191d982c991733Greg Clayton
596a510437e795477e5f629263d3d191d982c991733Greg Clayton            ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass());
597a510437e795477e5f629263d3d191d982c991733Greg Clayton            if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid())
598a510437e795477e5f629263d3d191d982c991733Greg Clayton                return non_kvo_objc_class_sp;
599be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton        }
600ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata    }
601be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton    return ClassDescriptorSP();
602ae2ae94bd72daf435204e99a0e03ccc64470a843Enrico Granata}
603be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
604be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
605be2f3aac39c2f7e3e6cce513800b35fa4b8f5429Greg Clayton
606