1 //===-- 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"
11 #include "lldb/Target/Target.h"
12 #include "lldb/Core/PluginManager.h"
13 
14 using namespace lldb;
15 using namespace lldb_private;
16 
17 LanguageRuntime*
18 LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language)
19 {
20     std::auto_ptr<LanguageRuntime> language_runtime_ap;
21     LanguageRuntimeCreateInstance create_callback;
22 
23     for (uint32_t idx = 0;
24          (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != NULL;
25          ++idx)
26     {
27         language_runtime_ap.reset (create_callback(process, language));
28 
29         if (language_runtime_ap.get())
30             return language_runtime_ap.release();
31     }
32 
33     return NULL;
34 }
35 
36 //----------------------------------------------------------------------
37 // Constructor
38 //----------------------------------------------------------------------
39 LanguageRuntime::LanguageRuntime(Process *process) :
40     m_process (process)
41 {
42 }
43 
44 //----------------------------------------------------------------------
45 // Destructor
46 //----------------------------------------------------------------------
47 LanguageRuntime::~LanguageRuntime()
48 {
49 }
50 
51 BreakpointSP
52 LanguageRuntime::CreateExceptionBreakpoint(
53     Target &target,
54     lldb::LanguageType language,
55     bool catch_bp,
56     bool throw_bp,
57     bool is_internal)
58 {
59     BreakpointSP exc_breakpt_sp;
60     BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(NULL, language, catch_bp, throw_bp));
61     SearchFilterSP filter_sp(target.GetSearchFilterForModule(NULL));
62 
63     exc_breakpt_sp = target.CreateBreakpoint (filter_sp, resolver_sp, is_internal);
64     if (is_internal)
65         exc_breakpt_sp->SetBreakpointKind("exception");
66 
67     return exc_breakpt_sp;
68 }
69 
70 LanguageRuntime::ExceptionBreakpointResolver::ExceptionBreakpointResolver (Breakpoint *bkpt,
71                         LanguageType language,
72                         bool catch_bp,
73                         bool throw_bp) :
74     BreakpointResolver (bkpt, BreakpointResolver::ExceptionResolver),
75     m_language (language),
76     m_catch_bp (catch_bp),
77     m_throw_bp (throw_bp)
78 
79 {
80 }
81 
82 void
83 LanguageRuntime::ExceptionBreakpointResolver::GetDescription (Stream *s)
84 {
85     s->Printf ("Exception breakpoint (catch: %s throw: %s)",
86            m_catch_bp ? "on" : "off",
87            m_throw_bp ? "on" : "off");
88 
89     SetActualResolver();
90     if (m_actual_resolver_sp)
91     {
92         s->Printf (" using: ");
93         m_actual_resolver_sp->GetDescription (s);
94     }
95     else
96         s->Printf (" the correct runtime exception handler will be determined when you run");
97 }
98 
99 bool
100 LanguageRuntime::ExceptionBreakpointResolver::SetActualResolver()
101 {
102     ProcessSP process_sp = m_process_wp.lock();
103 
104     // See if our process weak pointer is still good:
105     if (!process_sp)
106     {
107         // If not, our resolver is no good, so chuck that.  Then see if we can get the
108         // target's new process.
109         m_actual_resolver_sp.reset();
110         if (m_breakpoint)
111         {
112             Target &target = m_breakpoint->GetTarget();
113             process_sp = target.GetProcessSP();
114             if (process_sp)
115             {
116                 m_process_wp = process_sp;
117                 process_sp = m_process_wp.lock();
118             }
119         }
120     }
121 
122     if (process_sp)
123     {
124         if (m_actual_resolver_sp)
125             return true;
126         else
127         {
128             // If we have a process but not a resolver, set one now.
129             LanguageRuntime *runtime = process_sp->GetLanguageRuntime(m_language);
130             if (runtime)
131             {
132                 m_actual_resolver_sp = runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
133                 return (bool) m_actual_resolver_sp;
134             }
135             else
136                 return false;
137         }
138     }
139     else
140         return false;
141 }
142 
143 Searcher::CallbackReturn
144 LanguageRuntime::ExceptionBreakpointResolver::SearchCallback (SearchFilter &filter,
145                 SymbolContext &context,
146                 Address *addr,
147                 bool containing)
148 {
149 
150     if (!SetActualResolver())
151     {
152         return eCallbackReturnStop;
153     }
154     else
155         return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing);
156 }
157 
158 Searcher::Depth
159 LanguageRuntime::ExceptionBreakpointResolver::GetDepth ()
160 {
161     if (!SetActualResolver())
162         return eDepthTarget;
163     else
164         return m_actual_resolver_sp->GetDepth();
165 }
166 
167 /*
168 typedef enum LanguageType
169 {
170     eLanguageTypeUnknown         = 0x0000,   ///< Unknown or invalid language value.
171     eLanguageTypeC89             = 0x0001,   ///< ISO C:1989.
172     eLanguageTypeC               = 0x0002,   ///< Non-standardized C, such as K&R.
173     eLanguageTypeAda83           = 0x0003,   ///< ISO Ada:1983.
174     eLanguageTypeC_plus_plus     = 0x0004,   ///< ISO C++:1998.
175     eLanguageTypeCobol74         = 0x0005,   ///< ISO Cobol:1974.
176     eLanguageTypeCobol85         = 0x0006,   ///< ISO Cobol:1985.
177     eLanguageTypeFortran77       = 0x0007,   ///< ISO Fortran 77.
178     eLanguageTypeFortran90       = 0x0008,   ///< ISO Fortran 90.
179     eLanguageTypePascal83        = 0x0009,   ///< ISO Pascal:1983.
180     eLanguageTypeModula2         = 0x000a,   ///< ISO Modula-2:1996.
181     eLanguageTypeJava            = 0x000b,   ///< Java.
182     eLanguageTypeC99             = 0x000c,   ///< ISO C:1999.
183     eLanguageTypeAda95           = 0x000d,   ///< ISO Ada:1995.
184     eLanguageTypeFortran95       = 0x000e,   ///< ISO Fortran 95.
185     eLanguageTypePLI             = 0x000f,   ///< ANSI PL/I:1976.
186     eLanguageTypeObjC            = 0x0010,   ///< Objective-C.
187     eLanguageTypeObjC_plus_plus  = 0x0011,   ///< Objective-C++.
188     eLanguageTypeUPC             = 0x0012,   ///< Unified Parallel C.
189     eLanguageTypeD               = 0x0013,   ///< D.
190     eLanguageTypePython          = 0x0014    ///< Python.
191 } LanguageType;
192  */
193 
194 struct language_name_pair {
195     const char *name;
196     LanguageType type;
197 };
198 
199 struct language_name_pair language_names[] =
200 {
201     // To allow GetNameForLanguageType to be a simple array lookup, the first
202     // part of this array must follow enum LanguageType exactly.
203     {   "unknown",          eLanguageTypeUnknown        },
204     {   "c89",              eLanguageTypeC89            },
205     {   "c",                eLanguageTypeC              },
206     {   "ada83",            eLanguageTypeAda83          },
207     {   "c++",              eLanguageTypeC_plus_plus    },
208     {   "cobol74",          eLanguageTypeCobol74        },
209     {   "cobol85",          eLanguageTypeCobol85        },
210     {   "fortran77",        eLanguageTypeFortran77      },
211     {   "fortran90",        eLanguageTypeFortran90      },
212     {   "pascal83",         eLanguageTypePascal83       },
213     {   "modula2",          eLanguageTypeModula2        },
214     {   "java",             eLanguageTypeJava           },
215     {   "c99",              eLanguageTypeC99            },
216     {   "ada95",            eLanguageTypeAda95          },
217     {   "fortran95",        eLanguageTypeFortran95      },
218     {   "pli",              eLanguageTypePLI            },
219     {   "objective-c",      eLanguageTypeObjC           },
220     {   "objective-c++",    eLanguageTypeObjC_plus_plus },
221     {   "upc",              eLanguageTypeUPC            },
222     {   "d",                eLanguageTypeD              },
223     {   "python",           eLanguageTypePython         },
224     // Now synonyms, in arbitrary order
225     {   "objc",             eLanguageTypeObjC           },
226     {   "objc++",           eLanguageTypeObjC_plus_plus }
227 };
228 
229 static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair);
230 
231 LanguageType
232 LanguageRuntime::GetLanguageTypeFromString (const char *string)
233 {
234     for (uint32_t i = 0; i < num_languages; i++)
235     {
236         if (strcasecmp (language_names[i].name, string) == 0)
237             return (LanguageType) language_names[i].type;
238     }
239     return eLanguageTypeUnknown;
240 }
241 
242 const char *
243 LanguageRuntime::GetNameForLanguageType (LanguageType language)
244 {
245     if (language < num_languages)
246         return language_names[language].name;
247     else
248         return language_names[eLanguageTypeUnknown].name;
249 }
250 
251