blob: 26e091e708f8328f8fa8c99549df17c32f2762a2 [file] [log] [blame]
Jim Ingham22777012010-09-23 02:01:19 +00001//===-- LanguageRuntime.cpp -------------------------------------------------*- 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#include "lldb/Target/LanguageRuntime.h"
Jim Inghama72b31c2015-04-22 19:42:18 +000011#include "lldb/Target/ObjCLanguageRuntime.h"
Jim Ingham219ba192012-03-05 04:47:34 +000012#include "lldb/Target/Target.h"
Jim Ingham22777012010-09-23 02:01:19 +000013#include "lldb/Core/PluginManager.h"
Jim Ingham33df7cd2014-12-06 01:28:03 +000014#include "lldb/Core/SearchFilter.h"
Jim Ingham22777012010-09-23 02:01:19 +000015
16using namespace lldb;
17using namespace lldb_private;
18
Greg Claytonbff78252013-03-11 18:42:51 +000019
20class ExceptionSearchFilter : public SearchFilter
21{
22public:
23 ExceptionSearchFilter (const lldb::TargetSP &target_sp,
Jim Ingham33df7cd2014-12-06 01:28:03 +000024 lldb::LanguageType language,
25 bool update_module_list = true) :
Greg Claytonbff78252013-03-11 18:42:51 +000026 SearchFilter (target_sp),
27 m_language (language),
28 m_language_runtime (NULL),
29 m_filter_sp ()
30 {
Jim Ingham33df7cd2014-12-06 01:28:03 +000031 if (update_module_list)
32 UpdateModuleListIfNeeded ();
Greg Claytonbff78252013-03-11 18:42:51 +000033 }
Jim Ingham33df7cd2014-12-06 01:28:03 +000034
35 virtual
36 ~ExceptionSearchFilter() {};
37
Eric Christopher2325e382014-12-10 22:29:58 +000038 bool
39 ModulePasses (const lldb::ModuleSP &module_sp) override
Greg Claytonbff78252013-03-11 18:42:51 +000040 {
41 UpdateModuleListIfNeeded ();
42 if (m_filter_sp)
43 return m_filter_sp->ModulePasses (module_sp);
44 return false;
45 }
46
Eric Christopher2325e382014-12-10 22:29:58 +000047 bool
48 ModulePasses (const FileSpec &spec) override
Greg Claytonbff78252013-03-11 18:42:51 +000049 {
50 UpdateModuleListIfNeeded ();
51 if (m_filter_sp)
52 return m_filter_sp->ModulePasses (spec);
53 return false;
54
55 }
56
Eric Christopher2325e382014-12-10 22:29:58 +000057 void
58 Search (Searcher &searcher) override
Greg Claytonbff78252013-03-11 18:42:51 +000059 {
60 UpdateModuleListIfNeeded ();
61 if (m_filter_sp)
62 m_filter_sp->Search (searcher);
63 }
64
Eric Christopher2325e382014-12-10 22:29:58 +000065 void
66 GetDescription (Stream *s) override
Greg Claytonbff78252013-03-11 18:42:51 +000067 {
68 UpdateModuleListIfNeeded ();
69 if (m_filter_sp)
70 m_filter_sp->GetDescription (s);
71 }
72
73protected:
74 LanguageType m_language;
75 LanguageRuntime *m_language_runtime;
76 SearchFilterSP m_filter_sp;
77
Jim Ingham33df7cd2014-12-06 01:28:03 +000078 SearchFilterSP
79 DoCopyForBreakpoint(Breakpoint &breakpoint) override
80 {
81 return SearchFilterSP(new ExceptionSearchFilter(TargetSP(), m_language, false));
82 }
83
Greg Claytonbff78252013-03-11 18:42:51 +000084 void
85 UpdateModuleListIfNeeded ()
86 {
87 ProcessSP process_sp (m_target_sp->GetProcessSP());
88 if (process_sp)
89 {
90 bool refreash_filter = !m_filter_sp;
91 if (m_language_runtime == NULL)
92 {
93 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
94 refreash_filter = true;
95 }
96 else
97 {
98 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
99 if (m_language_runtime != language_runtime)
100 {
101 m_language_runtime = language_runtime;
102 refreash_filter = true;
103 }
104 }
105
106 if (refreash_filter && m_language_runtime)
107 {
108 m_filter_sp = m_language_runtime->CreateExceptionSearchFilter ();
109 }
110 }
111 else
112 {
113 m_filter_sp.reset();
114 m_language_runtime = NULL;
115 }
116 }
117};
118
119// The Target is the one that knows how to create breakpoints, so this function
120// is meant to be used either by the target or internally in Set/ClearExceptionBreakpoints.
121class ExceptionBreakpointResolver : public BreakpointResolver
122{
123public:
124 ExceptionBreakpointResolver (lldb::LanguageType language,
125 bool catch_bp,
126 bool throw_bp) :
127 BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver),
128 m_language (language),
129 m_language_runtime (NULL),
130 m_catch_bp (catch_bp),
131 m_throw_bp (throw_bp)
132 {
133 }
134
135 virtual
136 ~ExceptionBreakpointResolver()
137 {
138 }
139
Eric Christopher2325e382014-12-10 22:29:58 +0000140 Searcher::CallbackReturn
Greg Claytonbff78252013-03-11 18:42:51 +0000141 SearchCallback (SearchFilter &filter,
142 SymbolContext &context,
143 Address *addr,
Eric Christopher2325e382014-12-10 22:29:58 +0000144 bool containing) override
Greg Claytonbff78252013-03-11 18:42:51 +0000145 {
146
147 if (SetActualResolver())
148 return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing);
149 else
150 return eCallbackReturnStop;
151 }
152
Eric Christopher2325e382014-12-10 22:29:58 +0000153 Searcher::Depth
154 GetDepth () override
Greg Claytonbff78252013-03-11 18:42:51 +0000155 {
156 if (SetActualResolver())
157 return m_actual_resolver_sp->GetDepth();
158 else
159 return eDepthTarget;
160 }
161
Eric Christopher2325e382014-12-10 22:29:58 +0000162 void
163 GetDescription (Stream *s) override
Greg Claytonbff78252013-03-11 18:42:51 +0000164 {
165 s->Printf ("Exception breakpoint (catch: %s throw: %s)",
166 m_catch_bp ? "on" : "off",
167 m_throw_bp ? "on" : "off");
168
169 SetActualResolver();
170 if (m_actual_resolver_sp)
171 {
172 s->Printf (" using: ");
173 m_actual_resolver_sp->GetDescription (s);
174 }
175 else
176 s->Printf (" the correct runtime exception handler will be determined when you run");
177 }
178
Eric Christopher2325e382014-12-10 22:29:58 +0000179 void
180 Dump (Stream *s) const override
Greg Claytonbff78252013-03-11 18:42:51 +0000181 {
182 }
183
184 /// Methods for support type inquiry through isa, cast, and dyn_cast:
185 static inline bool classof(const BreakpointResolverName *) { return true; }
186 static inline bool classof(const BreakpointResolver *V) {
187 return V->getResolverID() == BreakpointResolver::ExceptionResolver;
188 }
189protected:
Jim Ingham33df7cd2014-12-06 01:28:03 +0000190 BreakpointResolverSP
191 CopyForBreakpoint (Breakpoint &breakpoint) override
192 {
193 return BreakpointResolverSP(new ExceptionBreakpointResolver(m_language, m_catch_bp, m_throw_bp));
194 }
195
Greg Claytonbff78252013-03-11 18:42:51 +0000196 bool
197 SetActualResolver()
198 {
199 ProcessSP process_sp;
200 if (m_breakpoint)
201 {
202 process_sp = m_breakpoint->GetTarget().GetProcessSP();
203 if (process_sp)
204 {
205 bool refreash_resolver = !m_actual_resolver_sp;
206 if (m_language_runtime == NULL)
207 {
208 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
209 refreash_resolver = true;
210 }
211 else
212 {
213 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
214 if (m_language_runtime != language_runtime)
215 {
216 m_language_runtime = language_runtime;
217 refreash_resolver = true;
218 }
219 }
220
221 if (refreash_resolver && m_language_runtime)
222 {
223 m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
224 }
225 }
226 else
227 {
228 m_actual_resolver_sp.reset();
229 m_language_runtime = NULL;
230 }
231 }
232 else
233 {
234 m_actual_resolver_sp.reset();
235 m_language_runtime = NULL;
236 }
237 return (bool)m_actual_resolver_sp;
238 }
239 lldb::BreakpointResolverSP m_actual_resolver_sp;
240 lldb::LanguageType m_language;
241 LanguageRuntime *m_language_runtime;
242 bool m_catch_bp;
243 bool m_throw_bp;
244};
245
246
Jim Ingham22777012010-09-23 02:01:19 +0000247LanguageRuntime*
248LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language)
249{
Greg Clayton7b0992d2013-04-18 22:45:39 +0000250 std::unique_ptr<LanguageRuntime> language_runtime_ap;
Jim Ingham22777012010-09-23 02:01:19 +0000251 LanguageRuntimeCreateInstance create_callback;
252
253 for (uint32_t idx = 0;
254 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != NULL;
255 ++idx)
256 {
257 language_runtime_ap.reset (create_callback(process, language));
258
259 if (language_runtime_ap.get())
260 return language_runtime_ap.release();
261 }
262
263 return NULL;
264}
265
266//----------------------------------------------------------------------
267// Constructor
268//----------------------------------------------------------------------
Jim Ingham5a369122010-09-28 01:25:32 +0000269LanguageRuntime::LanguageRuntime(Process *process) :
270 m_process (process)
Jim Ingham22777012010-09-23 02:01:19 +0000271{
272}
273
274//----------------------------------------------------------------------
275// Destructor
276//----------------------------------------------------------------------
277LanguageRuntime::~LanguageRuntime()
278{
279}
Jim Ingham219ba192012-03-05 04:47:34 +0000280
Jim Inghama72b31c2015-04-22 19:42:18 +0000281Breakpoint::BreakpointPreconditionSP
282LanguageRuntime::CreateExceptionPrecondition (lldb::LanguageType language,
283 bool catch_bp,
284 bool throw_bp)
285{
286 switch (language)
287 {
288 case eLanguageTypeObjC:
289 if (throw_bp)
290 return Breakpoint::BreakpointPreconditionSP(new ObjCLanguageRuntime::ObjCExceptionPrecondition ());
291 break;
292 default:
293 break;
294 }
295 return Breakpoint::BreakpointPreconditionSP();
296}
297
Jim Ingham219ba192012-03-05 04:47:34 +0000298BreakpointSP
Greg Claytonbff78252013-03-11 18:42:51 +0000299LanguageRuntime::CreateExceptionBreakpoint (Target &target,
300 lldb::LanguageType language,
301 bool catch_bp,
302 bool throw_bp,
303 bool is_internal)
Jim Ingham219ba192012-03-05 04:47:34 +0000304{
Greg Claytonbff78252013-03-11 18:42:51 +0000305 BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
306 SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language));
Greg Claytoneb023e72013-10-11 19:48:25 +0000307 bool hardware = false;
Jim Ingham1460e4b2014-01-10 23:46:59 +0000308 bool resolve_indirect_functions = false;
309 BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal, hardware, resolve_indirect_functions));
Jim Inghama72b31c2015-04-22 19:42:18 +0000310 if (exc_breakpt_sp)
311 {
312 Breakpoint::BreakpointPreconditionSP precondition_sp = CreateExceptionPrecondition(language, catch_bp, throw_bp);
313 if (precondition_sp)
314 exc_breakpt_sp->SetPrecondition(precondition_sp);
315
316 if (is_internal)
317 exc_breakpt_sp->SetBreakpointKind("exception");
318 }
Jim Ingham219ba192012-03-05 04:47:34 +0000319
320 return exc_breakpt_sp;
321}
322
Sean Callanand9477392012-10-23 00:50:09 +0000323struct language_name_pair {
324 const char *name;
325 LanguageType type;
Jim Inghamfab10e82012-03-06 00:37:27 +0000326};
Sean Callanand9477392012-10-23 00:50:09 +0000327
328struct language_name_pair language_names[] =
329{
330 // To allow GetNameForLanguageType to be a simple array lookup, the first
331 // part of this array must follow enum LanguageType exactly.
332 { "unknown", eLanguageTypeUnknown },
333 { "c89", eLanguageTypeC89 },
334 { "c", eLanguageTypeC },
335 { "ada83", eLanguageTypeAda83 },
336 { "c++", eLanguageTypeC_plus_plus },
337 { "cobol74", eLanguageTypeCobol74 },
338 { "cobol85", eLanguageTypeCobol85 },
339 { "fortran77", eLanguageTypeFortran77 },
340 { "fortran90", eLanguageTypeFortran90 },
341 { "pascal83", eLanguageTypePascal83 },
342 { "modula2", eLanguageTypeModula2 },
343 { "java", eLanguageTypeJava },
344 { "c99", eLanguageTypeC99 },
345 { "ada95", eLanguageTypeAda95 },
346 { "fortran95", eLanguageTypeFortran95 },
347 { "pli", eLanguageTypePLI },
348 { "objective-c", eLanguageTypeObjC },
349 { "objective-c++", eLanguageTypeObjC_plus_plus },
350 { "upc", eLanguageTypeUPC },
351 { "d", eLanguageTypeD },
352 { "python", eLanguageTypePython },
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000353 { "opencl", eLanguageTypeOpenCL },
354 { "go", eLanguageTypeGo },
355 { "modula3", eLanguageTypeModula3 },
356 { "haskell", eLanguageTypeHaskell },
357 { "c++03", eLanguageTypeC_plus_plus_03 },
358 { "c++11", eLanguageTypeC_plus_plus_11 },
359 { "ocaml", eLanguageTypeOCaml },
360 { "rust", eLanguageTypeRust },
361 { "c11", eLanguageTypeC11 },
Bruce Mitchenerca7b0aa2014-08-26 21:22:49 +0000362 { "swift", eLanguageTypeSwift },
363 { "julia", eLanguageTypeJulia },
364 { "dylan", eLanguageTypeDylan },
Bruce Mitchener2ba84a62015-02-06 06:46:52 +0000365 { "c++14", eLanguageTypeC_plus_plus_14 },
366 { "fortran03", eLanguageTypeFortran03 },
367 { "fortran08", eLanguageTypeFortran08 },
Colin Riley9e14f612015-04-03 09:03:15 +0000368 // Vendor Extensions
369 { "renderscript", eLanguageTypeExtRenderScript},
Sean Callanand9477392012-10-23 00:50:09 +0000370 // Now synonyms, in arbitrary order
371 { "objc", eLanguageTypeObjC },
372 { "objc++", eLanguageTypeObjC_plus_plus }
373};
374
375static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair);
Jim Inghamfab10e82012-03-06 00:37:27 +0000376
377LanguageType
378LanguageRuntime::GetLanguageTypeFromString (const char *string)
379{
380 for (uint32_t i = 0; i < num_languages; i++)
381 {
Sean Callanand9477392012-10-23 00:50:09 +0000382 if (strcasecmp (language_names[i].name, string) == 0)
383 return (LanguageType) language_names[i].type;
Jim Inghamfab10e82012-03-06 00:37:27 +0000384 }
385 return eLanguageTypeUnknown;
386}
387
388const char *
389LanguageRuntime::GetNameForLanguageType (LanguageType language)
390{
391 if (language < num_languages)
Sean Callanand9477392012-10-23 00:50:09 +0000392 return language_names[language].name;
Jim Inghamfab10e82012-03-06 00:37:27 +0000393 else
Sean Callanand9477392012-10-23 00:50:09 +0000394 return language_names[eLanguageTypeUnknown].name;
Jim Inghamfab10e82012-03-06 00:37:27 +0000395}
Greg Claytonbff78252013-03-11 18:42:51 +0000396
Jim Inghamde50d362015-04-17 00:44:36 +0000397void
398LanguageRuntime::PrintAllLanguages (Stream &s, const char *prefix, const char *suffix)
399{
400 for (uint32_t i = 1; i < num_languages; i++)
401 {
402 s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
403 }
404}
405
Siva Chandra0783ab92015-03-24 18:32:27 +0000406bool
407LanguageRuntime::LanguageIsCPlusPlus (LanguageType language)
408{
409 switch (language)
410 {
411 case eLanguageTypeC_plus_plus:
412 case eLanguageTypeC_plus_plus_03:
413 case eLanguageTypeC_plus_plus_11:
414 case eLanguageTypeC_plus_plus_14:
415 return true;
416 default:
417 return false;
418 }
419}
420
Greg Claytonbff78252013-03-11 18:42:51 +0000421lldb::SearchFilterSP
422LanguageRuntime::CreateExceptionSearchFilter ()
423{
424 return m_process->GetTarget().GetSearchFilterForModule(NULL);
425}
426
427
428