blob: 7a6bfbe46a8c0fc44c17f717b40ba030bf4acbac [file] [log] [blame]
Jim Ingham642036f2010-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 Ingham3df164e2012-03-05 04:47:34 +000011#include "lldb/Target/Target.h"
Jim Ingham642036f2010-09-23 02:01:19 +000012#include "lldb/Core/PluginManager.h"
13
14using namespace lldb;
15using namespace lldb_private;
16
Greg Claytond96df0a2013-03-11 18:42:51 +000017
18class ExceptionSearchFilter : public SearchFilter
19{
20public:
21 ExceptionSearchFilter (const lldb::TargetSP &target_sp,
22 lldb::LanguageType language) :
23 SearchFilter (target_sp),
24 m_language (language),
25 m_language_runtime (NULL),
26 m_filter_sp ()
27 {
28 UpdateModuleListIfNeeded ();
29 }
30
31 virtual bool
32 ModulePasses (const lldb::ModuleSP &module_sp)
33 {
34 UpdateModuleListIfNeeded ();
35 if (m_filter_sp)
36 return m_filter_sp->ModulePasses (module_sp);
37 return false;
38 }
39
40 virtual bool
41 ModulePasses (const FileSpec &spec)
42 {
43 UpdateModuleListIfNeeded ();
44 if (m_filter_sp)
45 return m_filter_sp->ModulePasses (spec);
46 return false;
47
48 }
49
50 virtual void
51 Search (Searcher &searcher)
52 {
53 UpdateModuleListIfNeeded ();
54 if (m_filter_sp)
55 m_filter_sp->Search (searcher);
56 }
57
58 virtual void
59 GetDescription (Stream *s)
60 {
61 UpdateModuleListIfNeeded ();
62 if (m_filter_sp)
63 m_filter_sp->GetDescription (s);
64 }
65
66protected:
67 LanguageType m_language;
68 LanguageRuntime *m_language_runtime;
69 SearchFilterSP m_filter_sp;
70
71 void
72 UpdateModuleListIfNeeded ()
73 {
74 ProcessSP process_sp (m_target_sp->GetProcessSP());
75 if (process_sp)
76 {
77 bool refreash_filter = !m_filter_sp;
78 if (m_language_runtime == NULL)
79 {
80 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
81 refreash_filter = true;
82 }
83 else
84 {
85 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
86 if (m_language_runtime != language_runtime)
87 {
88 m_language_runtime = language_runtime;
89 refreash_filter = true;
90 }
91 }
92
93 if (refreash_filter && m_language_runtime)
94 {
95 m_filter_sp = m_language_runtime->CreateExceptionSearchFilter ();
96 }
97 }
98 else
99 {
100 m_filter_sp.reset();
101 m_language_runtime = NULL;
102 }
103 }
104};
105
106// The Target is the one that knows how to create breakpoints, so this function
107// is meant to be used either by the target or internally in Set/ClearExceptionBreakpoints.
108class ExceptionBreakpointResolver : public BreakpointResolver
109{
110public:
111 ExceptionBreakpointResolver (lldb::LanguageType language,
112 bool catch_bp,
113 bool throw_bp) :
114 BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver),
115 m_language (language),
116 m_language_runtime (NULL),
117 m_catch_bp (catch_bp),
118 m_throw_bp (throw_bp)
119 {
120 }
121
122 virtual
123 ~ExceptionBreakpointResolver()
124 {
125 }
126
127 virtual Searcher::CallbackReturn
128 SearchCallback (SearchFilter &filter,
129 SymbolContext &context,
130 Address *addr,
131 bool containing)
132 {
133
134 if (SetActualResolver())
135 return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing);
136 else
137 return eCallbackReturnStop;
138 }
139
140 virtual Searcher::Depth
141 GetDepth ()
142 {
143 if (SetActualResolver())
144 return m_actual_resolver_sp->GetDepth();
145 else
146 return eDepthTarget;
147 }
148
149 virtual void
150 GetDescription (Stream *s)
151 {
152 s->Printf ("Exception breakpoint (catch: %s throw: %s)",
153 m_catch_bp ? "on" : "off",
154 m_throw_bp ? "on" : "off");
155
156 SetActualResolver();
157 if (m_actual_resolver_sp)
158 {
159 s->Printf (" using: ");
160 m_actual_resolver_sp->GetDescription (s);
161 }
162 else
163 s->Printf (" the correct runtime exception handler will be determined when you run");
164 }
165
166 virtual void
167 Dump (Stream *s) const
168 {
169 }
170
171 /// Methods for support type inquiry through isa, cast, and dyn_cast:
172 static inline bool classof(const BreakpointResolverName *) { return true; }
173 static inline bool classof(const BreakpointResolver *V) {
174 return V->getResolverID() == BreakpointResolver::ExceptionResolver;
175 }
176protected:
177 bool
178 SetActualResolver()
179 {
180 ProcessSP process_sp;
181 if (m_breakpoint)
182 {
183 process_sp = m_breakpoint->GetTarget().GetProcessSP();
184 if (process_sp)
185 {
186 bool refreash_resolver = !m_actual_resolver_sp;
187 if (m_language_runtime == NULL)
188 {
189 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
190 refreash_resolver = true;
191 }
192 else
193 {
194 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
195 if (m_language_runtime != language_runtime)
196 {
197 m_language_runtime = language_runtime;
198 refreash_resolver = true;
199 }
200 }
201
202 if (refreash_resolver && m_language_runtime)
203 {
204 m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
205 }
206 }
207 else
208 {
209 m_actual_resolver_sp.reset();
210 m_language_runtime = NULL;
211 }
212 }
213 else
214 {
215 m_actual_resolver_sp.reset();
216 m_language_runtime = NULL;
217 }
218 return (bool)m_actual_resolver_sp;
219 }
220 lldb::BreakpointResolverSP m_actual_resolver_sp;
221 lldb::LanguageType m_language;
222 LanguageRuntime *m_language_runtime;
223 bool m_catch_bp;
224 bool m_throw_bp;
225};
226
227
Jim Ingham642036f2010-09-23 02:01:19 +0000228LanguageRuntime*
229LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language)
230{
231 std::auto_ptr<LanguageRuntime> language_runtime_ap;
232 LanguageRuntimeCreateInstance create_callback;
233
234 for (uint32_t idx = 0;
235 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != NULL;
236 ++idx)
237 {
238 language_runtime_ap.reset (create_callback(process, language));
239
240 if (language_runtime_ap.get())
241 return language_runtime_ap.release();
242 }
243
244 return NULL;
245}
246
247//----------------------------------------------------------------------
248// Constructor
249//----------------------------------------------------------------------
Jim Inghamb66cd072010-09-28 01:25:32 +0000250LanguageRuntime::LanguageRuntime(Process *process) :
251 m_process (process)
Jim Ingham642036f2010-09-23 02:01:19 +0000252{
253}
254
255//----------------------------------------------------------------------
256// Destructor
257//----------------------------------------------------------------------
258LanguageRuntime::~LanguageRuntime()
259{
260}
Jim Ingham3df164e2012-03-05 04:47:34 +0000261
262BreakpointSP
Greg Claytond96df0a2013-03-11 18:42:51 +0000263LanguageRuntime::CreateExceptionBreakpoint (Target &target,
264 lldb::LanguageType language,
265 bool catch_bp,
266 bool throw_bp,
267 bool is_internal)
Jim Ingham3df164e2012-03-05 04:47:34 +0000268{
Greg Claytond96df0a2013-03-11 18:42:51 +0000269 BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
270 SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language));
Jim Ingham3df164e2012-03-05 04:47:34 +0000271
Greg Claytond96df0a2013-03-11 18:42:51 +0000272 BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal));
Jim Ingham090f8312013-01-26 02:19:28 +0000273 if (is_internal)
274 exc_breakpt_sp->SetBreakpointKind("exception");
Jim Ingham3df164e2012-03-05 04:47:34 +0000275
276 return exc_breakpt_sp;
277}
278
Sean Callanan61ff3a32012-10-23 00:50:09 +0000279struct language_name_pair {
280 const char *name;
281 LanguageType type;
Jim Ingham4722b102012-03-06 00:37:27 +0000282};
Sean Callanan61ff3a32012-10-23 00:50:09 +0000283
284struct language_name_pair language_names[] =
285{
286 // To allow GetNameForLanguageType to be a simple array lookup, the first
287 // part of this array must follow enum LanguageType exactly.
288 { "unknown", eLanguageTypeUnknown },
289 { "c89", eLanguageTypeC89 },
290 { "c", eLanguageTypeC },
291 { "ada83", eLanguageTypeAda83 },
292 { "c++", eLanguageTypeC_plus_plus },
293 { "cobol74", eLanguageTypeCobol74 },
294 { "cobol85", eLanguageTypeCobol85 },
295 { "fortran77", eLanguageTypeFortran77 },
296 { "fortran90", eLanguageTypeFortran90 },
297 { "pascal83", eLanguageTypePascal83 },
298 { "modula2", eLanguageTypeModula2 },
299 { "java", eLanguageTypeJava },
300 { "c99", eLanguageTypeC99 },
301 { "ada95", eLanguageTypeAda95 },
302 { "fortran95", eLanguageTypeFortran95 },
303 { "pli", eLanguageTypePLI },
304 { "objective-c", eLanguageTypeObjC },
305 { "objective-c++", eLanguageTypeObjC_plus_plus },
306 { "upc", eLanguageTypeUPC },
307 { "d", eLanguageTypeD },
308 { "python", eLanguageTypePython },
309 // Now synonyms, in arbitrary order
310 { "objc", eLanguageTypeObjC },
311 { "objc++", eLanguageTypeObjC_plus_plus }
312};
313
314static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair);
Jim Ingham4722b102012-03-06 00:37:27 +0000315
316LanguageType
317LanguageRuntime::GetLanguageTypeFromString (const char *string)
318{
319 for (uint32_t i = 0; i < num_languages; i++)
320 {
Sean Callanan61ff3a32012-10-23 00:50:09 +0000321 if (strcasecmp (language_names[i].name, string) == 0)
322 return (LanguageType) language_names[i].type;
Jim Ingham4722b102012-03-06 00:37:27 +0000323 }
324 return eLanguageTypeUnknown;
325}
326
327const char *
328LanguageRuntime::GetNameForLanguageType (LanguageType language)
329{
330 if (language < num_languages)
Sean Callanan61ff3a32012-10-23 00:50:09 +0000331 return language_names[language].name;
Jim Ingham4722b102012-03-06 00:37:27 +0000332 else
Sean Callanan61ff3a32012-10-23 00:50:09 +0000333 return language_names[eLanguageTypeUnknown].name;
Jim Ingham4722b102012-03-06 00:37:27 +0000334}
Greg Claytond96df0a2013-03-11 18:42:51 +0000335
336lldb::SearchFilterSP
337LanguageRuntime::CreateExceptionSearchFilter ()
338{
339 return m_process->GetTarget().GetSearchFilterForModule(NULL);
340}
341
342
343