blob: 46a065547cf7f4801a3c00834e14097ef9ce2e0f [file] [log] [blame]
Greg Clayton9b8ff512012-02-01 01:46:19 +00001//===-- ObjCLanguageRuntime.cpp ---------------------------------*- C++ -*-===//
Jim Ingham642036f2010-09-23 02:01:19 +00002//
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//===----------------------------------------------------------------------===//
Jim Ingham324067b2010-09-30 00:54:27 +00009#include "clang/AST/Type.h"
Jim Ingham642036f2010-09-23 02:01:19 +000010
Jim Inghamb66cd072010-09-28 01:25:32 +000011#include "lldb/Core/Log.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000012#include "lldb/Core/Module.h"
Jim Ingham642036f2010-09-23 02:01:19 +000013#include "lldb/Core/PluginManager.h"
Jim Ingham324067b2010-09-30 00:54:27 +000014#include "lldb/Core/ValueObject.h"
15#include "lldb/Symbol/ClangASTContext.h"
Jim Inghamef80aab2011-05-02 18:13:59 +000016#include "lldb/Symbol/Type.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000017#include "lldb/Symbol/TypeList.h"
Jim Inghamb66cd072010-09-28 01:25:32 +000018#include "lldb/Target/ObjCLanguageRuntime.h"
Sean Callanan931acec2012-02-22 23:57:45 +000019#include "lldb/Target/Target.h"
Jim Ingham642036f2010-09-23 02:01:19 +000020
21using namespace lldb;
22using namespace lldb_private;
23
24//----------------------------------------------------------------------
25// Destructor
26//----------------------------------------------------------------------
27ObjCLanguageRuntime::~ObjCLanguageRuntime()
28{
29}
30
31ObjCLanguageRuntime::ObjCLanguageRuntime (Process *process) :
Sean Callanan6e12c7a2012-03-08 02:39:03 +000032 LanguageRuntime (process),
Sean Callanan6fe8d362012-09-15 01:05:12 +000033 m_has_new_literals_and_indexing (eLazyBoolCalculate),
Greg Claytona5104372012-10-11 18:07:21 +000034 m_isa_to_descriptor_cache(),
Sean Callanan6fe8d362012-09-15 01:05:12 +000035 m_isa_to_descriptor_cache_is_up_to_date (false)
Jim Ingham642036f2010-09-23 02:01:19 +000036{
37
Jim Inghamb66cd072010-09-28 01:25:32 +000038}
39
40void
41ObjCLanguageRuntime::AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t selector, lldb::addr_t impl_addr)
42{
Greg Claytone005f2c2010-11-06 01:53:30 +000043 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Jim Inghamb66cd072010-09-28 01:25:32 +000044 if (log)
45 {
46 log->Printf ("Caching: class 0x%llx selector 0x%llx implementation 0x%llx.", class_addr, selector, impl_addr);
47 }
48 m_impl_cache.insert (std::pair<ClassAndSel,lldb::addr_t> (ClassAndSel(class_addr, selector), impl_addr));
49}
50
51lldb::addr_t
52ObjCLanguageRuntime::LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t selector)
53{
54 MsgImplMap::iterator pos, end = m_impl_cache.end();
55 pos = m_impl_cache.find (ClassAndSel(class_addr, selector));
56 if (pos != end)
57 return (*pos).second;
58 return LLDB_INVALID_ADDRESS;
59}
Jim Inghamef80aab2011-05-02 18:13:59 +000060
Jim Ingham58513662011-06-24 22:03:24 +000061
Sean Callanan931acec2012-02-22 23:57:45 +000062lldb::TypeSP
63ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name)
64{
65 CompleteClassMap::iterator complete_class_iter = m_complete_class_cache.find(name);
66
67 if (complete_class_iter != m_complete_class_cache.end())
68 {
Greg Claytonef22b902012-10-23 22:41:19 +000069 // Check the weak pointer to make sure the type hasn't been unloaded
70 TypeSP complete_type_sp (complete_class_iter->second.lock());
Sean Callanan931acec2012-02-22 23:57:45 +000071
Greg Claytonef22b902012-10-23 22:41:19 +000072 if (complete_type_sp)
73 return complete_type_sp;
Sean Callanan931acec2012-02-22 23:57:45 +000074 else
Greg Claytonef22b902012-10-23 22:41:19 +000075 m_complete_class_cache.erase(name);
Sean Callanan931acec2012-02-22 23:57:45 +000076 }
77
78 ModuleList &modules = m_process->GetTarget().GetImages();
Greg Claytonef22b902012-10-23 22:41:19 +000079
Sean Callanan931acec2012-02-22 23:57:45 +000080 SymbolContextList sc_list;
Greg Claytonef22b902012-10-23 22:41:19 +000081 const size_t matching_symbols = modules.FindSymbolsWithNameAndType (name,
82 eSymbolTypeObjCClass,
83 sc_list);
Sean Callanan931acec2012-02-22 23:57:45 +000084
Greg Claytonef22b902012-10-23 22:41:19 +000085 if (matching_symbols)
Sean Callanan931acec2012-02-22 23:57:45 +000086 {
Greg Claytonef22b902012-10-23 22:41:19 +000087 SymbolContext sc;
Sean Callanan931acec2012-02-22 23:57:45 +000088
Greg Claytonef22b902012-10-23 22:41:19 +000089 sc_list.GetContextAtIndex(0, sc);
90
91 ModuleSP module_sp(sc.module_sp);
92
93 if (!module_sp)
Sean Callanan931acec2012-02-22 23:57:45 +000094 return TypeSP();
Sean Callanan931acec2012-02-22 23:57:45 +000095
Greg Claytonef22b902012-10-23 22:41:19 +000096 const SymbolContext null_sc;
97 const bool exact_match = true;
98 const uint32_t max_matches = UINT32_MAX;
99 TypeList types;
100
101 const uint32_t num_types = module_sp->FindTypes (null_sc,
102 name,
103 exact_match,
104 max_matches,
105 types);
106
107 if (num_types)
Sean Callanan931acec2012-02-22 23:57:45 +0000108 {
Greg Claytonef22b902012-10-23 22:41:19 +0000109 TypeSP incomplete_type_sp;
110
111 uint32_t i;
112 for (i = 0; i < num_types; ++i)
113 {
114 TypeSP type_sp (types.GetTypeAtIndex(i));
115
116 if (ClangASTContext::IsObjCClassType(type_sp->GetClangForwardType()))
117 {
118 if (type_sp->IsCompleteObjCClass())
119 {
120 m_complete_class_cache[name] = type_sp;
121 return type_sp;
122 }
123 else if (!incomplete_type_sp)
124 incomplete_type_sp = type_sp;
125 }
126 }
127
128 // We didn't find any "real" definitions, so just use any??? Why was
129 // this being done? Prior to this, if there was 1 match only, then it
130 // would always use any objc definition, else we would only accept a
131 // definition if it was the real thing???? Doesn't make sense.
132
133 if (incomplete_type_sp)
134 {
135 m_complete_class_cache[name] = incomplete_type_sp;
136 return incomplete_type_sp;
137 }
Sean Callanan931acec2012-02-22 23:57:45 +0000138 }
139 }
Sean Callanan931acec2012-02-22 23:57:45 +0000140 return TypeSP();
141}
142
Jim Ingham58513662011-06-24 22:03:24 +0000143size_t
144ObjCLanguageRuntime::GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name)
145{
146 return LLDB_INVALID_IVAR_OFFSET;
147}
148
Jim Ingham3ad4da02011-08-15 01:32:22 +0000149
Greg Clayton662e5672012-01-19 03:24:53 +0000150uint32_t
Jim Ingham3ad4da02011-08-15 01:32:22 +0000151ObjCLanguageRuntime::ParseMethodName (const char *name,
Greg Claytone14d3d32012-01-19 00:52:59 +0000152 ConstString *class_name, // Class name (with category if any)
153 ConstString *selector_name, // selector on its own
154 ConstString *name_sans_category, // Full function prototype with no category
155 ConstString *class_name_sans_category)// Class name with no category (or empty if no category as answer will be in "class_name"
Jim Ingham3ad4da02011-08-15 01:32:22 +0000156{
Greg Claytone14d3d32012-01-19 00:52:59 +0000157 if (class_name)
158 class_name->Clear();
159 if (selector_name)
160 selector_name->Clear();
161 if (name_sans_category)
162 name_sans_category->Clear();
163 if (class_name_sans_category)
164 class_name_sans_category->Clear();
Jim Ingham3ad4da02011-08-15 01:32:22 +0000165
Greg Clayton662e5672012-01-19 03:24:53 +0000166 uint32_t result = 0;
167
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000168 if (IsPossibleObjCMethodName (name))
Jim Ingham3ad4da02011-08-15 01:32:22 +0000169 {
170 int name_len = strlen (name);
171 // Objective C methods must have at least:
172 // "-[" or "+[" prefix
173 // One character for a class name
174 // One character for the space between the class name
175 // One character for the method name
176 // "]" suffix
177 if (name_len >= 6 && name[name_len - 1] == ']')
178 {
Greg Claytone14d3d32012-01-19 00:52:59 +0000179 const char *selector_name_ptr = strchr (name, ' ');
Greg Clayton00db2152011-10-04 22:41:51 +0000180 if (selector_name_ptr)
Jim Ingham3ad4da02011-08-15 01:32:22 +0000181 {
182 if (class_name)
Greg Clayton662e5672012-01-19 03:24:53 +0000183 {
Greg Clayton00db2152011-10-04 22:41:51 +0000184 class_name->SetCStringWithLength (name + 2, selector_name_ptr - name - 2);
Greg Clayton662e5672012-01-19 03:24:53 +0000185 ++result;
186 }
Jim Ingham3ad4da02011-08-15 01:32:22 +0000187
188 // Skip the space
Greg Clayton00db2152011-10-04 22:41:51 +0000189 ++selector_name_ptr;
Jim Ingham3ad4da02011-08-15 01:32:22 +0000190 // Extract the objective C basename and add it to the
191 // accelerator tables
Greg Clayton00db2152011-10-04 22:41:51 +0000192 size_t selector_name_len = name_len - (selector_name_ptr - name) - 1;
193 if (selector_name)
Greg Clayton662e5672012-01-19 03:24:53 +0000194 {
Greg Clayton00db2152011-10-04 22:41:51 +0000195 selector_name->SetCStringWithLength (selector_name_ptr, selector_name_len);
Greg Clayton662e5672012-01-19 03:24:53 +0000196 ++result;
197 }
Jim Ingham3ad4da02011-08-15 01:32:22 +0000198
199 // Also see if this is a "category" on our class. If so strip off the category name,
200 // and add the class name without it to the basename table.
201
Greg Claytone14d3d32012-01-19 00:52:59 +0000202 if (name_sans_category || class_name_sans_category)
Jim Ingham3ad4da02011-08-15 01:32:22 +0000203 {
Greg Claytone14d3d32012-01-19 00:52:59 +0000204 const char *open_paren = strchr (name, '(');
Greg Claytone14d3d32012-01-19 00:52:59 +0000205 if (open_paren)
Jim Ingham3ad4da02011-08-15 01:32:22 +0000206 {
Greg Claytone14d3d32012-01-19 00:52:59 +0000207 if (class_name_sans_category)
Greg Clayton662e5672012-01-19 03:24:53 +0000208 {
Greg Claytone14d3d32012-01-19 00:52:59 +0000209 class_name_sans_category->SetCStringWithLength (name + 2, open_paren - name - 2);
Greg Clayton662e5672012-01-19 03:24:53 +0000210 ++result;
211 }
Sean Callananc1cd3792012-01-19 01:10:27 +0000212
213 if (name_sans_category)
Jim Ingham3ad4da02011-08-15 01:32:22 +0000214 {
Greg Clayton662e5672012-01-19 03:24:53 +0000215 const char *close_paren = strchr (open_paren, ')');
216 if (open_paren < close_paren)
Sean Callananc1cd3792012-01-19 01:10:27 +0000217 {
218 std::string buffer (name, open_paren - name);
219 buffer.append (close_paren + 1);
220 name_sans_category->SetCString (buffer.c_str());
Greg Clayton662e5672012-01-19 03:24:53 +0000221 ++result;
Sean Callananc1cd3792012-01-19 01:10:27 +0000222 }
Jim Ingham3ad4da02011-08-15 01:32:22 +0000223 }
224 }
225 }
226 }
Jim Ingham3ad4da02011-08-15 01:32:22 +0000227 }
Jim Ingham3ad4da02011-08-15 01:32:22 +0000228 }
Greg Clayton662e5672012-01-19 03:24:53 +0000229 return result;
Jim Ingham3ad4da02011-08-15 01:32:22 +0000230}
Enrico Granataae2ae942012-09-04 18:47:54 +0000231
232bool
233ObjCLanguageRuntime::ClassDescriptor::IsPointerValid (lldb::addr_t value,
234 uint32_t ptr_size,
235 bool allow_NULLs,
236 bool allow_tagged,
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000237 bool check_version_specific) const
Enrico Granataae2ae942012-09-04 18:47:54 +0000238{
239 if (!value)
240 return allow_NULLs;
241 if ( (value % 2) == 1 && allow_tagged)
242 return true;
243 if ((value % ptr_size) == 0)
244 return (check_version_specific ? CheckPointer(value,ptr_size) : true);
245 else
246 return false;
247}
248
249ObjCLanguageRuntime::ObjCISA
Sean Callananc718b962012-09-11 21:44:01 +0000250ObjCLanguageRuntime::GetISA(const ConstString &name)
251{
Sean Callanan6fe8d362012-09-15 01:05:12 +0000252 UpdateISAToDescriptorMap();
Sean Callananc718b962012-09-11 21:44:01 +0000253 for (const ISAToDescriptorMap::value_type &val : m_isa_to_descriptor_cache)
254 if (val.second && val.second->GetClassName() == name)
255 return val.first;
Sean Callananc718b962012-09-11 21:44:01 +0000256 return 0;
257}
258
259ObjCLanguageRuntime::ObjCISA
Enrico Granataae2ae942012-09-04 18:47:54 +0000260ObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa)
261{
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000262 ClassDescriptorSP objc_class_sp (GetClassDescriptor(isa));
263 if (objc_class_sp)
Enrico Granataae2ae942012-09-04 18:47:54 +0000264 {
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000265 ClassDescriptorSP objc_super_class_sp (objc_class_sp->GetSuperclass());
266 if (objc_super_class_sp)
267 return objc_super_class_sp->GetISA();
Enrico Granataae2ae942012-09-04 18:47:54 +0000268 }
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000269 return 0;
Enrico Granataae2ae942012-09-04 18:47:54 +0000270}
271
Enrico Granataae2ae942012-09-04 18:47:54 +0000272ConstString
273ObjCLanguageRuntime::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
274{
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000275 ClassDescriptorSP objc_class_sp (GetNonKVOClassDescriptor(isa));
276 if (objc_class_sp)
277 return objc_class_sp->GetClassName();
278 return ConstString();
Enrico Granataae2ae942012-09-04 18:47:54 +0000279}
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000280
281ObjCLanguageRuntime::ClassDescriptorSP
Greg Claytona5104372012-10-11 18:07:21 +0000282ObjCLanguageRuntime::GetClassDescriptor (const ConstString &class_name)
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000283{
Greg Claytona5104372012-10-11 18:07:21 +0000284 UpdateISAToDescriptorMap();
285 for (const ISAToDescriptorMap::value_type &val : m_isa_to_descriptor_cache)
286 if (val.second && val.second->GetClassName() == class_name)
287 return val.second;
288 return ClassDescriptorSP();
289
290}
291
292ObjCLanguageRuntime::ClassDescriptorSP
293ObjCLanguageRuntime::GetClassDescriptor (ValueObject& valobj)
294{
295 ClassDescriptorSP objc_class_sp;
296 // if we get an invalid VO (which might still happen when playing around
297 // with pointers returned by the expression parser, don't consider this
298 // a valid ObjC object)
299 if (valobj.GetValue().GetContextType() != Value::eContextTypeInvalid)
300 {
301 addr_t isa_pointer = valobj.GetPointerValue();
302 if (isa_pointer != LLDB_INVALID_ADDRESS)
303 {
304 ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
305
306 Process *process = exe_ctx.GetProcessPtr();
307 if (process)
308 {
309 Error error;
310 ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
311 if (isa != LLDB_INVALID_ADDRESS)
312 objc_class_sp = GetClassDescriptor (isa);
313 }
314 }
315 }
316 return objc_class_sp;
317}
318
319ObjCLanguageRuntime::ClassDescriptorSP
320ObjCLanguageRuntime::GetNonKVOClassDescriptor (ValueObject& valobj)
321{
322 ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (GetClassDescriptor (valobj));
323 if (objc_class_sp)
324 {
325 if (!objc_class_sp->IsKVO())
326 return objc_class_sp;
327
328 ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass());
329 if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid())
330 return non_kvo_objc_class_sp;
331 }
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000332 return ClassDescriptorSP();
333}
334
Greg Claytona5104372012-10-11 18:07:21 +0000335
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000336ObjCLanguageRuntime::ClassDescriptorSP
337ObjCLanguageRuntime::GetClassDescriptor (ObjCISA isa)
338{
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000339 if (isa)
340 {
Greg Claytona5104372012-10-11 18:07:21 +0000341 UpdateISAToDescriptorMap();
342 ObjCLanguageRuntime::ISAToDescriptorIterator pos = m_isa_to_descriptor_cache.find(isa);
343 if (pos != m_isa_to_descriptor_cache.end())
344 return pos->second;
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000345 }
Greg Claytona5104372012-10-11 18:07:21 +0000346 return ClassDescriptorSP();
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000347}
348
349ObjCLanguageRuntime::ClassDescriptorSP
350ObjCLanguageRuntime::GetNonKVOClassDescriptor (ObjCISA isa)
351{
352 if (isa)
353 {
354 ClassDescriptorSP objc_class_sp = GetClassDescriptor (isa);
355 if (objc_class_sp && objc_class_sp->IsValid())
356 {
Greg Claytona5104372012-10-11 18:07:21 +0000357 if (!objc_class_sp->IsKVO())
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000358 return objc_class_sp;
Greg Claytona5104372012-10-11 18:07:21 +0000359
360 ClassDescriptorSP non_kvo_objc_class_sp(objc_class_sp->GetSuperclass());
361 if (non_kvo_objc_class_sp && non_kvo_objc_class_sp->IsValid())
362 return non_kvo_objc_class_sp;
Greg Claytonbe2f3aa2012-10-09 17:51:53 +0000363 }
364 }
365 return ClassDescriptorSP();
366}
367
368
369