blob: da52d3dc0d0aebc66d9414fc3937483fcbc7e6a0 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectSource.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
Daniel Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner24943d22010-06-08 16:52:24 +000012#include "CommandObjectSource.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
Jim Ingham84cdc152010-06-15 19:49:27 +000018#include "lldb/Interpreter/Args.h"
Greg Clayton63094e02010-06-23 01:19:29 +000019#include "lldb/Core/Debugger.h"
Greg Clayton52c8b6e2011-04-19 04:19:37 +000020#include "lldb/Core/FileLineResolver.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000021#include "lldb/Core/ModuleSpec.h"
Greg Clayton52c8b6e2011-04-19 04:19:37 +000022#include "lldb/Core/SourceManager.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Interpreter/CommandInterpreter.h"
24#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton5f54ac32011-02-08 05:05:52 +000025#include "lldb/Host/FileSpec.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000026#include "lldb/Symbol/CompileUnit.h"
27#include "lldb/Symbol/Function.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028#include "lldb/Target/Process.h"
29#include "lldb/Target/TargetList.h"
Jim Ingham767af882010-07-07 03:36:20 +000030#include "lldb/Interpreter/CommandCompletions.h"
31#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000032
33using namespace lldb;
34using namespace lldb_private;
35
Chris Lattner24943d22010-06-08 16:52:24 +000036//-------------------------------------------------------------------------
Greg Clayton52c8b6e2011-04-19 04:19:37 +000037// CommandObjectSourceInfo
Chris Lattner24943d22010-06-08 16:52:24 +000038//-------------------------------------------------------------------------
39
Jim Inghamda26bd22012-06-08 21:56:10 +000040class CommandObjectSourceInfo : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +000041{
Chris Lattner24943d22010-06-08 16:52:24 +000042
Jim Ingham767af882010-07-07 03:36:20 +000043 class CommandOptions : public Options
Chris Lattner24943d22010-06-08 16:52:24 +000044 {
Jim Ingham767af882010-07-07 03:36:20 +000045 public:
Greg Claytonf15996e2011-04-07 22:46:35 +000046 CommandOptions (CommandInterpreter &interpreter) :
47 Options(interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +000048 {
Jim Ingham767af882010-07-07 03:36:20 +000049 }
Chris Lattner24943d22010-06-08 16:52:24 +000050
Jim Ingham767af882010-07-07 03:36:20 +000051 ~CommandOptions ()
52 {
53 }
Chris Lattner24943d22010-06-08 16:52:24 +000054
Jim Ingham767af882010-07-07 03:36:20 +000055 Error
Greg Clayton143fcc32011-04-13 00:18:08 +000056 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Ingham767af882010-07-07 03:36:20 +000057 {
58 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +000059 const int short_option = g_option_table[option_idx].short_option;
Jim Ingham767af882010-07-07 03:36:20 +000060 switch (short_option)
Chris Lattner24943d22010-06-08 16:52:24 +000061 {
Jim Ingham767af882010-07-07 03:36:20 +000062 case 'l':
63 start_line = Args::StringToUInt32 (option_arg, 0);
64 if (start_line == 0)
Greg Clayton9c236732011-10-26 00:56:27 +000065 error.SetErrorStringWithFormat("invalid line number: '%s'", option_arg);
Jim Ingham767af882010-07-07 03:36:20 +000066 break;
Chris Lattner24943d22010-06-08 16:52:24 +000067
Jim Ingham767af882010-07-07 03:36:20 +000068 case 'f':
69 file_name = option_arg;
70 break;
71
72 default:
Greg Clayton9c236732011-10-26 00:56:27 +000073 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Jim Ingham767af882010-07-07 03:36:20 +000074 break;
Chris Lattner24943d22010-06-08 16:52:24 +000075 }
76
Jim Ingham767af882010-07-07 03:36:20 +000077 return error;
78 }
Chris Lattner24943d22010-06-08 16:52:24 +000079
Jim Ingham767af882010-07-07 03:36:20 +000080 void
Greg Clayton143fcc32011-04-13 00:18:08 +000081 OptionParsingStarting ()
Jim Ingham767af882010-07-07 03:36:20 +000082 {
Jim Ingham767af882010-07-07 03:36:20 +000083 file_spec.Clear();
84 file_name.clear();
85 start_line = 0;
86 }
87
Greg Claytonb3448432011-03-24 21:19:54 +000088 const OptionDefinition*
Jim Ingham767af882010-07-07 03:36:20 +000089 GetDefinitions ()
90 {
91 return g_option_table;
92 }
Greg Claytonb3448432011-03-24 21:19:54 +000093 static OptionDefinition g_option_table[];
Jim Ingham767af882010-07-07 03:36:20 +000094
95 // Instance variables to hold the values for command options.
96 FileSpec file_spec;
97 std::string file_name;
98 uint32_t start_line;
99
100 };
101
102public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000103 CommandObjectSourceInfo(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000104 CommandObjectParsed (interpreter,
105 "source info",
106 "Display information about the source lines from the current executable's debug info.",
107 "source info [<cmd-options>]"),
Greg Claytonf15996e2011-04-07 22:46:35 +0000108 m_options (interpreter)
Jim Ingham767af882010-07-07 03:36:20 +0000109 {
110 }
111
112 ~CommandObjectSourceInfo ()
113 {
114 }
115
116
117 Options *
118 GetOptions ()
119 {
120 return &m_options;
121 }
122
Jim Inghamda26bd22012-06-08 21:56:10 +0000123protected:
Jim Ingham767af882010-07-07 03:36:20 +0000124 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000125 DoExecute (Args& command, CommandReturnObject &result)
Jim Ingham767af882010-07-07 03:36:20 +0000126 {
127 result.AppendError ("Not yet implemented");
128 result.SetStatus (eReturnStatusFailed);
129 return false;
130 }
Jim Inghamda26bd22012-06-08 21:56:10 +0000131
Jim Ingham767af882010-07-07 03:36:20 +0000132 CommandOptions m_options;
133};
134
Greg Claytonb3448432011-03-24 21:19:54 +0000135OptionDefinition
Jim Ingham767af882010-07-07 03:36:20 +0000136CommandObjectSourceInfo::CommandOptions::g_option_table[] =
137{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000138{ LLDB_OPT_SET_1, false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "The line number at which to start the display source."},
139{ LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."},
140{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham767af882010-07-07 03:36:20 +0000141};
142
143#pragma mark CommandObjectSourceList
144//-------------------------------------------------------------------------
145// CommandObjectSourceList
146//-------------------------------------------------------------------------
147
Jim Inghamda26bd22012-06-08 21:56:10 +0000148class CommandObjectSourceList : public CommandObjectParsed
Jim Ingham767af882010-07-07 03:36:20 +0000149{
150
151 class CommandOptions : public Options
152 {
153 public:
Greg Claytonf15996e2011-04-07 22:46:35 +0000154 CommandOptions (CommandInterpreter &interpreter) :
155 Options(interpreter)
Jim Ingham767af882010-07-07 03:36:20 +0000156 {
157 }
158
159 ~CommandOptions ()
160 {
161 }
162
163 Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000164 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Ingham767af882010-07-07 03:36:20 +0000165 {
166 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000167 const int short_option = g_option_table[option_idx].short_option;
Jim Ingham767af882010-07-07 03:36:20 +0000168 switch (short_option)
169 {
170 case 'l':
171 start_line = Args::StringToUInt32 (option_arg, 0);
172 if (start_line == 0)
Greg Clayton9c236732011-10-26 00:56:27 +0000173 error.SetErrorStringWithFormat("invalid line number: '%s'", option_arg);
Jim Ingham767af882010-07-07 03:36:20 +0000174 break;
175
Jim Ingham338f7532010-08-20 01:17:07 +0000176 case 'c':
Jim Ingham767af882010-07-07 03:36:20 +0000177 num_lines = Args::StringToUInt32 (option_arg, 0);
178 if (num_lines == 0)
Greg Clayton9c236732011-10-26 00:56:27 +0000179 error.SetErrorStringWithFormat("invalid line count: '%s'", option_arg);
Jim Ingham767af882010-07-07 03:36:20 +0000180 break;
181
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000182 case 'f':
Jim Ingham767af882010-07-07 03:36:20 +0000183 file_name = option_arg;
184 break;
Jim Ingham338f7532010-08-20 01:17:07 +0000185
186 case 'n':
187 symbol_name = option_arg;
188 break;
Jim Ingham767af882010-07-07 03:36:20 +0000189
Jim Ingham338f7532010-08-20 01:17:07 +0000190 case 's':
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000191 modules.push_back (std::string (option_arg));
192 break;
193
194 case 'b':
195 show_bp_locs = true;
Jim Ingham338f7532010-08-20 01:17:07 +0000196 break;
Jim Ingham767af882010-07-07 03:36:20 +0000197 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000198 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Jim Ingham767af882010-07-07 03:36:20 +0000199 break;
200 }
201
202 return error;
203 }
204
205 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000206 OptionParsingStarting ()
Jim Ingham767af882010-07-07 03:36:20 +0000207 {
Jim Ingham767af882010-07-07 03:36:20 +0000208 file_spec.Clear();
209 file_name.clear();
Jim Ingham338f7532010-08-20 01:17:07 +0000210 symbol_name.clear();
Jim Ingham767af882010-07-07 03:36:20 +0000211 start_line = 0;
212 num_lines = 10;
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000213 show_bp_locs = false;
214 modules.clear();
Jim Ingham767af882010-07-07 03:36:20 +0000215 }
216
Greg Claytonb3448432011-03-24 21:19:54 +0000217 const OptionDefinition*
Jim Ingham767af882010-07-07 03:36:20 +0000218 GetDefinitions ()
219 {
220 return g_option_table;
221 }
Greg Claytonb3448432011-03-24 21:19:54 +0000222 static OptionDefinition g_option_table[];
Jim Ingham767af882010-07-07 03:36:20 +0000223
224 // Instance variables to hold the values for command options.
225 FileSpec file_spec;
226 std::string file_name;
Jim Ingham338f7532010-08-20 01:17:07 +0000227 std::string symbol_name;
Jim Ingham767af882010-07-07 03:36:20 +0000228 uint32_t start_line;
229 uint32_t num_lines;
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000230 STLStringArray modules;
231 bool show_bp_locs;
Jim Ingham767af882010-07-07 03:36:20 +0000232 };
233
234public:
Greg Clayton238c0a12010-09-18 01:14:36 +0000235 CommandObjectSourceList(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000236 CommandObjectParsed (interpreter,
237 "source list",
238 "Display source code (as specified) based on the current executable's debug info.",
239 NULL),
Greg Claytonf15996e2011-04-07 22:46:35 +0000240 m_options (interpreter)
Jim Ingham767af882010-07-07 03:36:20 +0000241 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000242 CommandArgumentEntry arg;
243 CommandArgumentData file_arg;
244
245 // Define the first (and only) variant of this arg.
246 file_arg.arg_type = eArgTypeFilename;
247 file_arg.arg_repetition = eArgRepeatOptional;
248
249 // There is only one variant this argument could be; put it into the argument entry.
250 arg.push_back (file_arg);
251
252 // Push the data for the first argument into the m_arguments vector.
253 m_arguments.push_back (arg);
Jim Ingham767af882010-07-07 03:36:20 +0000254 }
255
256 ~CommandObjectSourceList ()
257 {
258 }
259
260
261 Options *
262 GetOptions ()
263 {
264 return &m_options;
265 }
266
Jim Inghamda26bd22012-06-08 21:56:10 +0000267 virtual const char *
268 GetRepeatCommand (Args &current_command_args, uint32_t index)
Jim Ingham767af882010-07-07 03:36:20 +0000269 {
Jim Inghamda26bd22012-06-08 21:56:10 +0000270 return m_cmd_name.c_str();
271 }
272
273protected:
274 bool
275 DoExecute (Args& command, CommandReturnObject &result)
276 {
277 const int argc = command.GetArgumentCount();
Jim Ingham767af882010-07-07 03:36:20 +0000278
279 if (argc != 0)
280 {
281 result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", GetCommandName());
282 result.SetStatus (eReturnStatusFailed);
Jim Ingham26e089b2011-11-29 21:21:26 +0000283 return false;
Jim Ingham767af882010-07-07 03:36:20 +0000284 }
285
Greg Claytonb72d0f02011-04-12 05:54:46 +0000286 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +0000287 Target *target = exe_ctx.GetTargetPtr();
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000288
Greg Clayton567e7f32011-09-22 04:58:26 +0000289 if (target == NULL)
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000290 target = m_interpreter.GetDebugger().GetSelectedTarget().get();
291
292 if (target == NULL)
293 {
294 result.AppendError ("invalid target, create a debug target using the 'target create' command");
295 result.SetStatus (eReturnStatusFailed);
296 return false;
297 }
298
Jim Ingham338f7532010-08-20 01:17:07 +0000299 if (!m_options.symbol_name.empty())
300 {
301 // Displaying the source for a symbol:
Jim Ingham338f7532010-08-20 01:17:07 +0000302 SymbolContextList sc_list;
303 ConstString name(m_options.symbol_name.c_str());
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000304 bool include_symbols = false;
Sean Callanan302d78c2012-02-10 22:52:19 +0000305 bool include_inlines = true;
Jim Ingham338f7532010-08-20 01:17:07 +0000306 bool append = true;
307 size_t num_matches = 0;
308
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000309 if (m_options.modules.size() > 0)
Jim Ingham338f7532010-08-20 01:17:07 +0000310 {
311 ModuleList matching_modules;
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000312 for (unsigned i = 0, e = m_options.modules.size(); i != e; i++)
Jim Ingham338f7532010-08-20 01:17:07 +0000313 {
Greg Clayton444fe992012-02-26 05:51:37 +0000314 FileSpec module_file_spec(m_options.modules[i].c_str(), false);
315 if (module_file_spec)
Jim Ingham338f7532010-08-20 01:17:07 +0000316 {
Greg Clayton444fe992012-02-26 05:51:37 +0000317 ModuleSpec module_spec (module_file_spec);
Jim Ingham338f7532010-08-20 01:17:07 +0000318 matching_modules.Clear();
Greg Clayton444fe992012-02-26 05:51:37 +0000319 target->GetImages().FindModules (module_spec, matching_modules);
Sean Callanan302d78c2012-02-10 22:52:19 +0000320 num_matches += matching_modules.FindFunctions (name, eFunctionNameTypeAuto, include_symbols, include_inlines, append, sc_list);
Jim Ingham338f7532010-08-20 01:17:07 +0000321 }
322 }
323 }
324 else
325 {
Sean Callanan302d78c2012-02-10 22:52:19 +0000326 num_matches = target->GetImages().FindFunctions (name, eFunctionNameTypeAuto, include_symbols, include_inlines, append, sc_list);
Jim Ingham338f7532010-08-20 01:17:07 +0000327 }
328
329 SymbolContext sc;
330
331 if (num_matches == 0)
332 {
333 result.AppendErrorWithFormat("Could not find function named: \"%s\".\n", m_options.symbol_name.c_str());
334 result.SetStatus (eReturnStatusFailed);
335 return false;
336 }
337
338 sc_list.GetContextAtIndex (0, sc);
339 FileSpec start_file;
340 uint32_t start_line;
341 uint32_t end_line;
342 FileSpec end_file;
343 if (sc.function != NULL)
344 {
345 sc.function->GetStartLineSourceInfo (start_file, start_line);
346 if (start_line == 0)
347 {
348 result.AppendErrorWithFormat("Could not find line information for start of function: \"%s\".\n", m_options.symbol_name.c_str());
349 result.SetStatus (eReturnStatusFailed);
350 return false;
351 }
352 sc.function->GetEndLineSourceInfo (end_file, end_line);
353 }
354 else
355 {
356 result.AppendErrorWithFormat("Could not find function info for: \"%s\".\n", m_options.symbol_name.c_str());
357 result.SetStatus (eReturnStatusFailed);
358 return false;
359 }
360
361 if (num_matches > 1)
362 {
363 // This could either be because there are multiple functions of this name, in which case
364 // we'll have to specify this further... Or it could be because there are multiple inlined instances
365 // of one function. So run through the matches and if they all have the same file & line then we can just
366 // list one.
367
368 bool found_multiple = false;
369
370 for (size_t i = 1; i < num_matches; i++)
371 {
372 SymbolContext scratch_sc;
373 sc_list.GetContextAtIndex (i, scratch_sc);
374 if (scratch_sc.function != NULL)
375 {
376 FileSpec scratch_file;
377 uint32_t scratch_line;
378 scratch_sc.function->GetStartLineSourceInfo (scratch_file, scratch_line);
379 if (scratch_file != start_file
380 || scratch_line != start_line)
381 {
382 found_multiple = true;
383 break;
384 }
385 }
386 }
387 if (found_multiple)
388 {
389 StreamString s;
390 for (size_t i = 0; i < num_matches; i++)
391 {
392 SymbolContext scratch_sc;
393 sc_list.GetContextAtIndex (i, scratch_sc);
394 if (scratch_sc.function != NULL)
395 {
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000396 s.Printf("\n%lu: ", i);
Jim Ingham338f7532010-08-20 01:17:07 +0000397 scratch_sc.function->Dump (&s, true);
398 }
399 }
400 result.AppendErrorWithFormat("Multiple functions found matching: %s: \n%s\n",
401 m_options.symbol_name.c_str(),
402 s.GetData());
403 result.SetStatus (eReturnStatusFailed);
404 return false;
405 }
406 }
407
408
409 // This is a little hacky, but the first line table entry for a function points to the "{" that
410 // starts the function block. It would be nice to actually get the function
411 // declaration in there too. So back up a bit, but not further than what you're going to display.
412 size_t lines_to_back_up = m_options.num_lines >= 10 ? 5 : m_options.num_lines/2;
413 uint32_t line_no;
414 if (start_line <= lines_to_back_up)
415 line_no = 1;
416 else
417 line_no = start_line - lines_to_back_up;
418
419 // For fun, if the function is shorter than the number of lines we're supposed to display,
420 // only display the function...
421 if (end_line != 0)
422 {
423 if (m_options.num_lines > end_line - line_no)
424 m_options.num_lines = end_line - line_no;
425 }
426
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000427 char path_buf[PATH_MAX];
428 start_file.GetPath(path_buf, sizeof(path_buf));
Greg Clayton1cee1e62011-04-20 18:52:45 +0000429
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000430 if (m_options.show_bp_locs)
Greg Clayton1cee1e62011-04-20 18:52:45 +0000431 {
432 const bool show_inlines = true;
433 m_breakpoint_locations.Reset (start_file, 0, show_inlines);
Greg Clayton567e7f32011-09-22 04:58:26 +0000434 SearchFilter target_search_filter (exe_ctx.GetTargetSP());
Greg Clayton1cee1e62011-04-20 18:52:45 +0000435 target_search_filter.Search (m_breakpoint_locations);
436 }
437 else
438 m_breakpoint_locations.Clear();
439
Jim Ingham338f7532010-08-20 01:17:07 +0000440 result.AppendMessageWithFormat("File: %s.\n", path_buf);
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000441 target->GetSourceManager().DisplaySourceLinesWithLineNumbers (start_file,
442 line_no,
443 0,
444 m_options.num_lines,
445 "",
446 &result.GetOutputStream(),
447 GetBreakpointLocations ());
Jim Ingham338f7532010-08-20 01:17:07 +0000448
449 result.SetStatus (eReturnStatusSuccessFinishResult);
450 return true;
451
452 }
453 else if (m_options.file_name.empty())
Jim Ingham767af882010-07-07 03:36:20 +0000454 {
455 // Last valid source manager context, or the current frame if no
456 // valid last context in source manager.
457 // One little trick here, if you type the exact same list command twice in a row, it is
458 // more likely because you typed it once, then typed it again
459 if (m_options.start_line == 0)
460 {
Jim Inghamc7f18c82011-09-29 20:22:33 +0000461 if (target->GetSourceManager().DisplayMoreWithLineNumbers (&result.GetOutputStream(),
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000462 GetBreakpointLocations ()))
Chris Lattner24943d22010-06-08 16:52:24 +0000463 {
Chris Lattner24943d22010-06-08 16:52:24 +0000464 result.SetStatus (eReturnStatusSuccessFinishResult);
465 }
Jim Ingham767af882010-07-07 03:36:20 +0000466 }
467 else
468 {
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000469 if (m_options.show_bp_locs)
Greg Clayton1cee1e62011-04-20 18:52:45 +0000470 {
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000471 SourceManager::FileSP last_file_sp (target->GetSourceManager().GetLastFile ());
Greg Clayton1cee1e62011-04-20 18:52:45 +0000472 if (last_file_sp)
473 {
474 const bool show_inlines = true;
475 m_breakpoint_locations.Reset (last_file_sp->GetFileSpec(), 0, show_inlines);
Greg Clayton13d24fb2012-01-29 20:56:30 +0000476 SearchFilter target_search_filter (target->shared_from_this());
Greg Clayton1cee1e62011-04-20 18:52:45 +0000477 target_search_filter.Search (m_breakpoint_locations);
478 }
479 }
480 else
481 m_breakpoint_locations.Clear();
482
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000483 if (target->GetSourceManager().DisplaySourceLinesWithLineNumbersUsingLastFile(
Jim Ingham767af882010-07-07 03:36:20 +0000484 m_options.start_line, // Line to display
485 0, // Lines before line to display
486 m_options.num_lines, // Lines after line to display
487 "", // Don't mark "line"
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000488 &result.GetOutputStream(),
489 GetBreakpointLocations ()))
Chris Lattner24943d22010-06-08 16:52:24 +0000490 {
Jim Ingham767af882010-07-07 03:36:20 +0000491 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000492 }
Jim Ingham767af882010-07-07 03:36:20 +0000493
Chris Lattner24943d22010-06-08 16:52:24 +0000494 }
495 }
496 else
497 {
Jim Ingham767af882010-07-07 03:36:20 +0000498 const char *filename = m_options.file_name.c_str();
Jim Ingham767af882010-07-07 03:36:20 +0000499
500 bool check_inlines = false;
501 SymbolContextList sc_list;
Jim Ingham338f7532010-08-20 01:17:07 +0000502 size_t num_matches = 0;
503
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000504 if (m_options.modules.size() > 0)
Jim Ingham767af882010-07-07 03:36:20 +0000505 {
Jim Ingham338f7532010-08-20 01:17:07 +0000506 ModuleList matching_modules;
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000507 for (unsigned i = 0, e = m_options.modules.size(); i != e; i++)
Jim Ingham767af882010-07-07 03:36:20 +0000508 {
Greg Clayton444fe992012-02-26 05:51:37 +0000509 FileSpec module_file_spec(m_options.modules[i].c_str(), false);
510 if (module_file_spec)
Jim Ingham767af882010-07-07 03:36:20 +0000511 {
Greg Clayton444fe992012-02-26 05:51:37 +0000512 ModuleSpec module_spec (module_file_spec);
Jim Ingham338f7532010-08-20 01:17:07 +0000513 matching_modules.Clear();
Greg Clayton444fe992012-02-26 05:51:37 +0000514 target->GetImages().FindModules (module_spec, matching_modules);
Jim Ingham338f7532010-08-20 01:17:07 +0000515 num_matches += matching_modules.ResolveSymbolContextForFilePath (filename,
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000516 0,
517 check_inlines,
518 eSymbolContextModule | eSymbolContextCompUnit,
519 sc_list);
Jim Ingham767af882010-07-07 03:36:20 +0000520 }
521 }
522 }
Jim Ingham338f7532010-08-20 01:17:07 +0000523 else
524 {
525 num_matches = target->GetImages().ResolveSymbolContextForFilePath (filename,
526 0,
527 check_inlines,
528 eSymbolContextModule | eSymbolContextCompUnit,
529 sc_list);
530 }
531
532 if (num_matches == 0)
533 {
534 result.AppendErrorWithFormat("Could not find source file \"%s\".\n",
535 m_options.file_name.c_str());
536 result.SetStatus (eReturnStatusFailed);
537 return false;
538 }
539
540 if (num_matches > 1)
541 {
542 SymbolContext sc;
543 bool got_multiple = false;
544 FileSpec *test_cu_spec = NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000545
Chris Lattner0f6fa732010-09-08 22:55:31 +0000546 for (unsigned i = 0; i < num_matches; i++)
Jim Ingham338f7532010-08-20 01:17:07 +0000547 {
548 sc_list.GetContextAtIndex(i, sc);
549 if (sc.comp_unit)
550 {
551 if (test_cu_spec)
552 {
553 if (test_cu_spec != static_cast<FileSpec *> (sc.comp_unit))
554 got_multiple = true;
555 break;
556 }
557 else
558 test_cu_spec = sc.comp_unit;
559 }
560 }
561 if (got_multiple)
562 {
563 result.AppendErrorWithFormat("Multiple source files found matching: \"%s.\"\n",
564 m_options.file_name.c_str());
565 result.SetStatus (eReturnStatusFailed);
566 return false;
567 }
568 }
569
570 SymbolContext sc;
571 if (sc_list.GetContextAtIndex(0, sc))
572 {
573 if (sc.comp_unit)
574 {
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000575 if (m_options.show_bp_locs)
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000576 {
577 const bool show_inlines = true;
578 m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines);
Greg Clayton13d24fb2012-01-29 20:56:30 +0000579 SearchFilter target_search_filter (target->shared_from_this());
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000580 target_search_filter.Search (m_breakpoint_locations);
581 }
582 else
583 m_breakpoint_locations.Clear();
584
Jim Inghamfdf24ef2011-09-08 22:13:49 +0000585 target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
586 m_options.start_line,
587 0,
588 m_options.num_lines,
589 "",
590 &result.GetOutputStream(),
591 GetBreakpointLocations ());
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000592
Jim Ingham338f7532010-08-20 01:17:07 +0000593 result.SetStatus (eReturnStatusSuccessFinishResult);
594 }
595 else
596 {
597 result.AppendErrorWithFormat("No comp unit found for: \"%s.\"\n",
598 m_options.file_name.c_str());
599 result.SetStatus (eReturnStatusFailed);
600 return false;
601 }
602 }
603 }
Jim Ingham767af882010-07-07 03:36:20 +0000604 return result.Succeeded();
Chris Lattner24943d22010-06-08 16:52:24 +0000605 }
Jim Ingham767af882010-07-07 03:36:20 +0000606
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000607 const SymbolContextList *
608 GetBreakpointLocations ()
609 {
610 if (m_breakpoint_locations.GetFileLineMatches().GetSize() > 0)
611 return &m_breakpoint_locations.GetFileLineMatches();
612 return NULL;
613 }
Jim Ingham767af882010-07-07 03:36:20 +0000614 CommandOptions m_options;
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000615 FileLineResolver m_breakpoint_locations;
Jim Ingham767af882010-07-07 03:36:20 +0000616
617};
618
Greg Claytonb3448432011-03-24 21:19:54 +0000619OptionDefinition
Jim Ingham767af882010-07-07 03:36:20 +0000620CommandObjectSourceList::CommandOptions::g_option_table[] =
621{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000622{ LLDB_OPT_SET_ALL, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "The number of source lines to display."},
623{ LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library."},
Greg Clayton52c8b6e2011-04-19 04:19:37 +0000624{ LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', no_argument, NULL, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints."},
Caroline Tice4d6675c2010-10-01 19:59:14 +0000625{ LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."},
626{ LLDB_OPT_SET_1, false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "The line number at which to start the display source."},
627{ LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."},
628{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Jim Ingham767af882010-07-07 03:36:20 +0000629};
630
631#pragma mark CommandObjectMultiwordSource
632
633//-------------------------------------------------------------------------
634// CommandObjectMultiwordSource
635//-------------------------------------------------------------------------
636
637CommandObjectMultiwordSource::CommandObjectMultiwordSource (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000638 CommandObjectMultiword (interpreter,
639 "source",
Caroline Ticec1ad82e2010-09-07 22:38:08 +0000640 "A set of commands for accessing source file information",
Jim Ingham767af882010-07-07 03:36:20 +0000641 "source <subcommand> [<subcommand-options>]")
642{
Greg Clayton238c0a12010-09-18 01:14:36 +0000643 LoadSubCommand ("info", CommandObjectSP (new CommandObjectSourceInfo (interpreter)));
644 LoadSubCommand ("list", CommandObjectSP (new CommandObjectSourceList (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +0000645}
Jim Ingham767af882010-07-07 03:36:20 +0000646
647CommandObjectMultiwordSource::~CommandObjectMultiwordSource ()
648{
649}
650