blob: 6008cacd160290b3e922df8d4360e640a33d1106 [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"
Colin Rileyc9c55a22015-05-04 18:39:38 +000015#include "lldb/Interpreter/CommandInterpreter.h"
Jim Ingham22777012010-09-23 02:01:19 +000016
17using namespace lldb;
18using namespace lldb_private;
19
Greg Claytonbff78252013-03-11 18:42:51 +000020
21class ExceptionSearchFilter : public SearchFilter
22{
23public:
24 ExceptionSearchFilter (const lldb::TargetSP &target_sp,
Jim Ingham33df7cd2014-12-06 01:28:03 +000025 lldb::LanguageType language,
26 bool update_module_list = true) :
Greg Claytonbff78252013-03-11 18:42:51 +000027 SearchFilter (target_sp),
28 m_language (language),
29 m_language_runtime (NULL),
30 m_filter_sp ()
31 {
Jim Ingham33df7cd2014-12-06 01:28:03 +000032 if (update_module_list)
33 UpdateModuleListIfNeeded ();
Greg Claytonbff78252013-03-11 18:42:51 +000034 }
Jim Ingham33df7cd2014-12-06 01:28:03 +000035
36 virtual
37 ~ExceptionSearchFilter() {};
38
Eric Christopher2325e382014-12-10 22:29:58 +000039 bool
40 ModulePasses (const lldb::ModuleSP &module_sp) override
Greg Claytonbff78252013-03-11 18:42:51 +000041 {
42 UpdateModuleListIfNeeded ();
43 if (m_filter_sp)
44 return m_filter_sp->ModulePasses (module_sp);
45 return false;
46 }
47
Eric Christopher2325e382014-12-10 22:29:58 +000048 bool
49 ModulePasses (const FileSpec &spec) override
Greg Claytonbff78252013-03-11 18:42:51 +000050 {
51 UpdateModuleListIfNeeded ();
52 if (m_filter_sp)
53 return m_filter_sp->ModulePasses (spec);
54 return false;
55
56 }
57
Eric Christopher2325e382014-12-10 22:29:58 +000058 void
59 Search (Searcher &searcher) override
Greg Claytonbff78252013-03-11 18:42:51 +000060 {
61 UpdateModuleListIfNeeded ();
62 if (m_filter_sp)
63 m_filter_sp->Search (searcher);
64 }
65
Eric Christopher2325e382014-12-10 22:29:58 +000066 void
67 GetDescription (Stream *s) override
Greg Claytonbff78252013-03-11 18:42:51 +000068 {
69 UpdateModuleListIfNeeded ();
70 if (m_filter_sp)
71 m_filter_sp->GetDescription (s);
72 }
73
74protected:
75 LanguageType m_language;
76 LanguageRuntime *m_language_runtime;
77 SearchFilterSP m_filter_sp;
78
Jim Ingham33df7cd2014-12-06 01:28:03 +000079 SearchFilterSP
80 DoCopyForBreakpoint(Breakpoint &breakpoint) override
81 {
82 return SearchFilterSP(new ExceptionSearchFilter(TargetSP(), m_language, false));
83 }
84
Greg Claytonbff78252013-03-11 18:42:51 +000085 void
86 UpdateModuleListIfNeeded ()
87 {
88 ProcessSP process_sp (m_target_sp->GetProcessSP());
89 if (process_sp)
90 {
91 bool refreash_filter = !m_filter_sp;
92 if (m_language_runtime == NULL)
93 {
94 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
95 refreash_filter = true;
96 }
97 else
98 {
99 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
100 if (m_language_runtime != language_runtime)
101 {
102 m_language_runtime = language_runtime;
103 refreash_filter = true;
104 }
105 }
106
107 if (refreash_filter && m_language_runtime)
108 {
109 m_filter_sp = m_language_runtime->CreateExceptionSearchFilter ();
110 }
111 }
112 else
113 {
114 m_filter_sp.reset();
115 m_language_runtime = NULL;
116 }
117 }
118};
119
120// The Target is the one that knows how to create breakpoints, so this function
121// is meant to be used either by the target or internally in Set/ClearExceptionBreakpoints.
122class ExceptionBreakpointResolver : public BreakpointResolver
123{
124public:
125 ExceptionBreakpointResolver (lldb::LanguageType language,
126 bool catch_bp,
127 bool throw_bp) :
128 BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver),
129 m_language (language),
130 m_language_runtime (NULL),
131 m_catch_bp (catch_bp),
132 m_throw_bp (throw_bp)
133 {
134 }
135
136 virtual
137 ~ExceptionBreakpointResolver()
138 {
139 }
140
Eric Christopher2325e382014-12-10 22:29:58 +0000141 Searcher::CallbackReturn
Greg Claytonbff78252013-03-11 18:42:51 +0000142 SearchCallback (SearchFilter &filter,
143 SymbolContext &context,
144 Address *addr,
Eric Christopher2325e382014-12-10 22:29:58 +0000145 bool containing) override
Greg Claytonbff78252013-03-11 18:42:51 +0000146 {
147
148 if (SetActualResolver())
149 return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing);
150 else
151 return eCallbackReturnStop;
152 }
153
Eric Christopher2325e382014-12-10 22:29:58 +0000154 Searcher::Depth
155 GetDepth () override
Greg Claytonbff78252013-03-11 18:42:51 +0000156 {
157 if (SetActualResolver())
158 return m_actual_resolver_sp->GetDepth();
159 else
160 return eDepthTarget;
161 }
162
Eric Christopher2325e382014-12-10 22:29:58 +0000163 void
164 GetDescription (Stream *s) override
Greg Claytonbff78252013-03-11 18:42:51 +0000165 {
166 s->Printf ("Exception breakpoint (catch: %s throw: %s)",
167 m_catch_bp ? "on" : "off",
168 m_throw_bp ? "on" : "off");
169
170 SetActualResolver();
171 if (m_actual_resolver_sp)
172 {
173 s->Printf (" using: ");
174 m_actual_resolver_sp->GetDescription (s);
175 }
176 else
177 s->Printf (" the correct runtime exception handler will be determined when you run");
178 }
179
Eric Christopher2325e382014-12-10 22:29:58 +0000180 void
181 Dump (Stream *s) const override
Greg Claytonbff78252013-03-11 18:42:51 +0000182 {
183 }
184
185 /// Methods for support type inquiry through isa, cast, and dyn_cast:
186 static inline bool classof(const BreakpointResolverName *) { return true; }
187 static inline bool classof(const BreakpointResolver *V) {
188 return V->getResolverID() == BreakpointResolver::ExceptionResolver;
189 }
190protected:
Jim Ingham33df7cd2014-12-06 01:28:03 +0000191 BreakpointResolverSP
192 CopyForBreakpoint (Breakpoint &breakpoint) override
193 {
194 return BreakpointResolverSP(new ExceptionBreakpointResolver(m_language, m_catch_bp, m_throw_bp));
195 }
196
Greg Claytonbff78252013-03-11 18:42:51 +0000197 bool
198 SetActualResolver()
199 {
200 ProcessSP process_sp;
201 if (m_breakpoint)
202 {
203 process_sp = m_breakpoint->GetTarget().GetProcessSP();
204 if (process_sp)
205 {
206 bool refreash_resolver = !m_actual_resolver_sp;
207 if (m_language_runtime == NULL)
208 {
209 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
210 refreash_resolver = true;
211 }
212 else
213 {
214 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
215 if (m_language_runtime != language_runtime)
216 {
217 m_language_runtime = language_runtime;
218 refreash_resolver = true;
219 }
220 }
221
222 if (refreash_resolver && m_language_runtime)
223 {
224 m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
225 }
226 }
227 else
228 {
229 m_actual_resolver_sp.reset();
230 m_language_runtime = NULL;
231 }
232 }
233 else
234 {
235 m_actual_resolver_sp.reset();
236 m_language_runtime = NULL;
237 }
238 return (bool)m_actual_resolver_sp;
239 }
240 lldb::BreakpointResolverSP m_actual_resolver_sp;
241 lldb::LanguageType m_language;
242 LanguageRuntime *m_language_runtime;
243 bool m_catch_bp;
244 bool m_throw_bp;
245};
246
247
Jim Ingham22777012010-09-23 02:01:19 +0000248LanguageRuntime*
249LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language)
250{
Greg Clayton7b0992d2013-04-18 22:45:39 +0000251 std::unique_ptr<LanguageRuntime> language_runtime_ap;
Jim Ingham22777012010-09-23 02:01:19 +0000252 LanguageRuntimeCreateInstance create_callback;
253
254 for (uint32_t idx = 0;
255 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != NULL;
256 ++idx)
257 {
258 language_runtime_ap.reset (create_callback(process, language));
259
260 if (language_runtime_ap.get())
261 return language_runtime_ap.release();
262 }
263
264 return NULL;
265}
266
267//----------------------------------------------------------------------
268// Constructor
269//----------------------------------------------------------------------
Jim Ingham5a369122010-09-28 01:25:32 +0000270LanguageRuntime::LanguageRuntime(Process *process) :
271 m_process (process)
Jim Ingham22777012010-09-23 02:01:19 +0000272{
273}
274
275//----------------------------------------------------------------------
276// Destructor
277//----------------------------------------------------------------------
278LanguageRuntime::~LanguageRuntime()
279{
280}
Jim Ingham219ba192012-03-05 04:47:34 +0000281
Jim Inghama72b31c2015-04-22 19:42:18 +0000282Breakpoint::BreakpointPreconditionSP
283LanguageRuntime::CreateExceptionPrecondition (lldb::LanguageType language,
284 bool catch_bp,
285 bool throw_bp)
286{
287 switch (language)
288 {
289 case eLanguageTypeObjC:
290 if (throw_bp)
291 return Breakpoint::BreakpointPreconditionSP(new ObjCLanguageRuntime::ObjCExceptionPrecondition ());
292 break;
293 default:
294 break;
295 }
296 return Breakpoint::BreakpointPreconditionSP();
297}
298
Jim Ingham219ba192012-03-05 04:47:34 +0000299BreakpointSP
Greg Claytonbff78252013-03-11 18:42:51 +0000300LanguageRuntime::CreateExceptionBreakpoint (Target &target,
301 lldb::LanguageType language,
302 bool catch_bp,
303 bool throw_bp,
304 bool is_internal)
Jim Ingham219ba192012-03-05 04:47:34 +0000305{
Greg Claytonbff78252013-03-11 18:42:51 +0000306 BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
307 SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language));
Greg Claytoneb023e72013-10-11 19:48:25 +0000308 bool hardware = false;
Jim Ingham1460e4b2014-01-10 23:46:59 +0000309 bool resolve_indirect_functions = false;
310 BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal, hardware, resolve_indirect_functions));
Jim Inghama72b31c2015-04-22 19:42:18 +0000311 if (exc_breakpt_sp)
312 {
313 Breakpoint::BreakpointPreconditionSP precondition_sp = CreateExceptionPrecondition(language, catch_bp, throw_bp);
314 if (precondition_sp)
315 exc_breakpt_sp->SetPrecondition(precondition_sp);
316
317 if (is_internal)
318 exc_breakpt_sp->SetBreakpointKind("exception");
319 }
Jim Ingham219ba192012-03-05 04:47:34 +0000320
321 return exc_breakpt_sp;
322}
323
Sean Callanand9477392012-10-23 00:50:09 +0000324struct language_name_pair {
325 const char *name;
326 LanguageType type;
Jim Inghamfab10e82012-03-06 00:37:27 +0000327};
Sean Callanand9477392012-10-23 00:50:09 +0000328
329struct language_name_pair language_names[] =
330{
331 // To allow GetNameForLanguageType to be a simple array lookup, the first
332 // part of this array must follow enum LanguageType exactly.
333 { "unknown", eLanguageTypeUnknown },
334 { "c89", eLanguageTypeC89 },
335 { "c", eLanguageTypeC },
336 { "ada83", eLanguageTypeAda83 },
337 { "c++", eLanguageTypeC_plus_plus },
338 { "cobol74", eLanguageTypeCobol74 },
339 { "cobol85", eLanguageTypeCobol85 },
340 { "fortran77", eLanguageTypeFortran77 },
341 { "fortran90", eLanguageTypeFortran90 },
342 { "pascal83", eLanguageTypePascal83 },
343 { "modula2", eLanguageTypeModula2 },
344 { "java", eLanguageTypeJava },
345 { "c99", eLanguageTypeC99 },
346 { "ada95", eLanguageTypeAda95 },
347 { "fortran95", eLanguageTypeFortran95 },
348 { "pli", eLanguageTypePLI },
349 { "objective-c", eLanguageTypeObjC },
350 { "objective-c++", eLanguageTypeObjC_plus_plus },
351 { "upc", eLanguageTypeUPC },
352 { "d", eLanguageTypeD },
353 { "python", eLanguageTypePython },
Bruce Mitchener1d0089f2014-07-03 00:49:08 +0000354 { "opencl", eLanguageTypeOpenCL },
355 { "go", eLanguageTypeGo },
356 { "modula3", eLanguageTypeModula3 },
357 { "haskell", eLanguageTypeHaskell },
358 { "c++03", eLanguageTypeC_plus_plus_03 },
359 { "c++11", eLanguageTypeC_plus_plus_11 },
360 { "ocaml", eLanguageTypeOCaml },
361 { "rust", eLanguageTypeRust },
362 { "c11", eLanguageTypeC11 },
Bruce Mitchenerca7b0aa2014-08-26 21:22:49 +0000363 { "swift", eLanguageTypeSwift },
364 { "julia", eLanguageTypeJulia },
365 { "dylan", eLanguageTypeDylan },
Bruce Mitchener2ba84a62015-02-06 06:46:52 +0000366 { "c++14", eLanguageTypeC_plus_plus_14 },
367 { "fortran03", eLanguageTypeFortran03 },
368 { "fortran08", eLanguageTypeFortran08 },
Colin Riley9e14f612015-04-03 09:03:15 +0000369 // Vendor Extensions
370 { "renderscript", eLanguageTypeExtRenderScript},
Sean Callanand9477392012-10-23 00:50:09 +0000371 // Now synonyms, in arbitrary order
372 { "objc", eLanguageTypeObjC },
373 { "objc++", eLanguageTypeObjC_plus_plus }
374};
375
376static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair);
Jim Inghamfab10e82012-03-06 00:37:27 +0000377
378LanguageType
379LanguageRuntime::GetLanguageTypeFromString (const char *string)
380{
381 for (uint32_t i = 0; i < num_languages; i++)
382 {
Sean Callanand9477392012-10-23 00:50:09 +0000383 if (strcasecmp (language_names[i].name, string) == 0)
384 return (LanguageType) language_names[i].type;
Jim Inghamfab10e82012-03-06 00:37:27 +0000385 }
386 return eLanguageTypeUnknown;
387}
388
389const char *
390LanguageRuntime::GetNameForLanguageType (LanguageType language)
391{
392 if (language < num_languages)
Sean Callanand9477392012-10-23 00:50:09 +0000393 return language_names[language].name;
Jim Inghamfab10e82012-03-06 00:37:27 +0000394 else
Sean Callanand9477392012-10-23 00:50:09 +0000395 return language_names[eLanguageTypeUnknown].name;
Jim Inghamfab10e82012-03-06 00:37:27 +0000396}
Greg Claytonbff78252013-03-11 18:42:51 +0000397
Jim Inghamde50d362015-04-17 00:44:36 +0000398void
399LanguageRuntime::PrintAllLanguages (Stream &s, const char *prefix, const char *suffix)
400{
401 for (uint32_t i = 1; i < num_languages; i++)
402 {
403 s.Printf("%s%s%s", prefix, language_names[i].name, suffix);
404 }
405}
406
Siva Chandra0783ab92015-03-24 18:32:27 +0000407bool
408LanguageRuntime::LanguageIsCPlusPlus (LanguageType language)
409{
410 switch (language)
411 {
412 case eLanguageTypeC_plus_plus:
413 case eLanguageTypeC_plus_plus_03:
414 case eLanguageTypeC_plus_plus_11:
415 case eLanguageTypeC_plus_plus_14:
416 return true;
417 default:
418 return false;
419 }
420}
421
Colin Rileyc9c55a22015-05-04 18:39:38 +0000422void
423LanguageRuntime::InitializeCommands (CommandObject* parent)
424{
425 if (!parent)
426 return;
427
428 if (!parent->IsMultiwordObject())
429 return;
430
431 LanguageRuntimeCreateInstance create_callback;
432
433 for (uint32_t idx = 0;
434 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != nullptr;
435 ++idx)
436 {
437 if (LanguageRuntimeGetCommandObject command_callback =
438 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(idx))
439 {
440 CommandObjectSP command = command_callback(parent->GetCommandInterpreter());
441 if (command)
442 {
443 parent->LoadSubCommand(command->GetCommandName(), command);
444 }
445 }
446 }
447}
448
Greg Claytonbff78252013-03-11 18:42:51 +0000449lldb::SearchFilterSP
450LanguageRuntime::CreateExceptionSearchFilter ()
451{
452 return m_process->GetTarget().GetSearchFilterForModule(NULL);
453}
454
455
456