Skip to content

Commit bc0a9a1

Browse files
committed
Add an option (-y) to "break set" and "source list" that uses the same
file:line:column form that we use to print out locations. Since we print them this way it makes sense we also accept that form. Differential Revision: https://reviews.llvm.org/D83975
1 parent b79dff0 commit bc0a9a1

23 files changed

+436
-13
lines changed

lldb/include/lldb/Interpreter/OptionValue.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class OptionValue {
3131
eTypeChar,
3232
eTypeDictionary,
3333
eTypeEnum,
34+
eTypeFileLineColumn,
3435
eTypeFileSpec,
3536
eTypeFileSpecList,
3637
eTypeFormat,
@@ -135,6 +136,8 @@ class OptionValue {
135136
return eTypeDictionary;
136137
case 1u << eTypeEnum:
137138
return eTypeEnum;
139+
case 1u << eTypeFileLineColumn:
140+
return eTypeFileLineColumn;
138141
case 1u << eTypeFileSpec:
139142
return eTypeFileSpec;
140143
case 1u << eTypeFileSpecList:
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//===-- OptionValueFileColonLine.h -----------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H
10+
#define LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H
11+
12+
#include "lldb/Interpreter/OptionValue.h"
13+
14+
#include "lldb/Utility/FileSpec.h"
15+
#include "llvm/Support/Chrono.h"
16+
17+
namespace lldb_private {
18+
19+
class OptionValueFileColonLine : public OptionValue {
20+
public:
21+
OptionValueFileColonLine();
22+
OptionValueFileColonLine(const llvm::StringRef input);
23+
24+
~OptionValueFileColonLine() override {}
25+
26+
OptionValue::Type GetType() const override { return eTypeFileLineColumn; }
27+
28+
void DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
29+
uint32_t dump_mask) override;
30+
31+
Status
32+
SetValueFromString(llvm::StringRef value,
33+
VarSetOperationType op = eVarSetOperationAssign) override;
34+
Status
35+
SetValueFromString(const char *,
36+
VarSetOperationType = eVarSetOperationAssign) = delete;
37+
38+
bool Clear() override {
39+
m_file_spec.Clear();
40+
m_line_number = LLDB_INVALID_LINE_NUMBER;
41+
m_column_number = 0;
42+
}
43+
44+
lldb::OptionValueSP DeepCopy() const override;
45+
46+
void AutoComplete(CommandInterpreter &interpreter,
47+
CompletionRequest &request) override;
48+
49+
FileSpec &GetFileSpec() { return m_file_spec; }
50+
uint32_t GetLineNumber() { return m_line_number; }
51+
uint32_t GetColumnNumber() { return m_column_number; }
52+
53+
void SetCompletionMask(uint32_t mask) { m_completion_mask = mask; }
54+
55+
protected:
56+
FileSpec m_file_spec;
57+
uint32_t m_line_number;
58+
uint32_t m_column_number;
59+
uint32_t m_completion_mask;
60+
};
61+
62+
} // namespace lldb_private
63+
64+
#endif // LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H

lldb/include/lldb/Interpreter/OptionValues.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "lldb/Interpreter/OptionValueChar.h"
1818
#include "lldb/Interpreter/OptionValueDictionary.h"
1919
#include "lldb/Interpreter/OptionValueEnumeration.h"
20+
#include "lldb/Interpreter/OptionValueFileColonLine.h"
2021
#include "lldb/Interpreter/OptionValueFileSpec.h"
2122
#include "lldb/Interpreter/OptionValueFileSpecList.h"
2223
#include "lldb/Interpreter/OptionValueFormat.h"

lldb/include/lldb/lldb-defines.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
#define LLDB_INVALID_SIGNAL_NUMBER INT32_MAX
9696
#define LLDB_INVALID_OFFSET UINT64_MAX // Must match max of lldb::offset_t
9797
#define LLDB_INVALID_LINE_NUMBER UINT32_MAX
98+
#define LLDB_INVALID_COLUMN_NUMBER 0
9899
#define LLDB_INVALID_QUEUE_ID 0
99100

100101
/// CPU Type definitions
@@ -119,6 +120,7 @@
119120
#define LLDB_OPT_SET_9 (1U << 8)
120121
#define LLDB_OPT_SET_10 (1U << 9)
121122
#define LLDB_OPT_SET_11 (1U << 10)
123+
#define LLDB_OPT_SET_12 (1U << 11)
122124
#define LLDB_OPT_SET_FROM_TO(A, B) \
123125
(((1U << (B)) - 1) ^ (((1U << (A)) - 1) >> 1))
124126

lldb/include/lldb/lldb-enumerations.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ enum CommandArgumentType {
526526
eArgTypeExpression,
527527
eArgTypeExpressionPath,
528528
eArgTypeExprFormat,
529+
eArgTypeFileLineColumn,
529530
eArgTypeFilename,
530531
eArgTypeFormat,
531532
eArgTypeFrameIndex,

lldb/packages/Python/lldbsuite/test/lldbutil.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,29 @@ def run_break_set_by_source_regexp(
502502

503503
return get_bpno_from_match(break_results)
504504

505+
def run_break_set_by_file_colon_line(
506+
test,
507+
specifier,
508+
path,
509+
line_number,
510+
column_number = 0,
511+
extra_options=None,
512+
num_expected_locations=-1):
513+
command = 'breakpoint set -y "%s"'%(specifier)
514+
if extra_options:
515+
command += " " + extra_options
516+
517+
print("About to run: '%s'", command)
518+
break_results = run_break_set_command(test, command)
519+
check_breakpoint_result(
520+
test,
521+
break_results,
522+
num_locations = num_expected_locations,
523+
file_name = path,
524+
line_number = line_number,
525+
column_number = column_number)
526+
527+
return get_bpno_from_match(break_results)
505528

506529
def run_break_set_command(test, command):
507530
"""Run the command passed in - it must be some break set variant - and analyze the result.
@@ -515,6 +538,7 @@ def run_break_set_command(test, command):
515538
If there is only one location, the dictionary MAY contain:
516539
file - source file name
517540
line_no - source line number
541+
column - source column number
518542
symbol - symbol name
519543
inline_symbol - inlined symbol name
520544
offset - offset from the original symbol
@@ -566,6 +590,7 @@ def check_breakpoint_result(
566590
break_results,
567591
file_name=None,
568592
line_number=-1,
593+
column_number=0,
569594
symbol_name=None,
570595
symbol_match_exact=True,
571596
module_name=None,
@@ -605,6 +630,17 @@ def check_breakpoint_result(
605630
(line_number,
606631
out_line_number))
607632

633+
if column_number != 0:
634+
out_column_number = 0
635+
if 'column' in break_results:
636+
out_column_number = break_results['column']
637+
638+
test.assertTrue(
639+
column_number == out_column_number,
640+
"Breakpoint column number %s doesn't match resultant column %s." %
641+
(column_number,
642+
out_column_number))
643+
608644
if symbol_name:
609645
out_symbol_name = ""
610646
# Look first for the inlined symbol name, otherwise use the symbol

lldb/source/Commands/CommandObjectBreakpoint.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "lldb/Interpreter/OptionArgParser.h"
1818
#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
1919
#include "lldb/Interpreter/OptionValueBoolean.h"
20+
#include "lldb/Interpreter/OptionValueFileColonLine.h"
2021
#include "lldb/Interpreter/OptionValueString.h"
2122
#include "lldb/Interpreter/OptionValueUInt64.h"
2223
#include "lldb/Interpreter/Options.h"
@@ -443,7 +444,22 @@ class CommandObjectBreakpointSet : public CommandObjectParsed {
443444
case 'X':
444445
m_source_regex_func_names.insert(std::string(option_arg));
445446
break;
446-
447+
448+
case 'y':
449+
{
450+
OptionValueFileColonLine value;
451+
Status fcl_err = value.SetValueFromString(option_arg);
452+
if (!fcl_err.Success()) {
453+
error.SetErrorStringWithFormat(
454+
"Invalid value for file:line specifier: %s",
455+
fcl_err.AsCString());
456+
} else {
457+
m_filenames.AppendIfUnique(value.GetFileSpec());
458+
m_line_num = value.GetLineNumber();
459+
m_column = value.GetColumnNumber();
460+
}
461+
} break;
462+
447463
default:
448464
llvm_unreachable("Unimplemented option");
449465
}

lldb/source/Commands/CommandObjectSource.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "lldb/Host/OptionParser.h"
1717
#include "lldb/Interpreter/CommandReturnObject.h"
1818
#include "lldb/Interpreter/OptionArgParser.h"
19+
#include "lldb/Interpreter/OptionValueFileColonLine.h"
1920
#include "lldb/Interpreter/Options.h"
2021
#include "lldb/Symbol/CompileUnit.h"
2122
#include "lldb/Symbol/Function.h"
@@ -667,6 +668,22 @@ class CommandObjectSourceList : public CommandObjectParsed {
667668
case 'r':
668669
reverse = true;
669670
break;
671+
case 'y':
672+
{
673+
OptionValueFileColonLine value;
674+
Status fcl_err = value.SetValueFromString(option_arg);
675+
if (!fcl_err.Success()) {
676+
error.SetErrorStringWithFormat(
677+
"Invalid value for file:line specifier: %s",
678+
fcl_err.AsCString());
679+
} else {
680+
file_name = value.GetFileSpec().GetPath();
681+
start_line = value.GetLineNumber();
682+
// I don't see anything useful to do with a column number, but I don't
683+
// want to complain since someone may well have cut and pasted a
684+
// listing from somewhere that included a column.
685+
}
686+
} break;
670687
default:
671688
llvm_unreachable("Unimplemented option");
672689
}

lldb/source/Commands/Options.td

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ let Command = "breakpoint dummy" in {
105105

106106
let Command = "breakpoint set" in {
107107
def breakpoint_set_shlib : Option<"shlib", "s">, Arg<"ShlibName">,
108-
Completion<"Module">, Groups<[1,2,3,4,5,6,7,8,9,11]>, // *not* in group 10
108+
Completion<"Module">, Groups<[1,2,3,4,5,6,7,8,9,11,12]>, // *not* in group 10
109109
Desc<"Set the breakpoint only in this shared library. Can repeat this "
110110
"option multiple times to specify multiple shared libraries.">;
111111
def breakpoint_set_hardware : Option<"hardware", "H">,
@@ -186,21 +186,24 @@ let Command = "breakpoint set" in {
186186
"expression (note: currently only implemented for setting breakpoints on "
187187
"identifiers). If not set the target.language setting is used.">;
188188
def breakpoint_set_skip_prologue : Option<"skip-prologue", "K">,
189-
Arg<"Boolean">, Groups<[1,3,4,5,6,7,8]>,
189+
Arg<"Boolean">, Groups<[1,3,4,5,6,7,8,12]>,
190190
Desc<"sKip the prologue if the breakpoint is at the beginning of a "
191191
"function. If not set the target.skip-prologue setting is used.">;
192192
def breakpoint_set_breakpoint_name : Option<"breakpoint-name", "N">,
193193
Arg<"BreakpointName">,
194194
Desc<"Adds this to the list of names for this breakpoint.">;
195195
def breakpoint_set_address_slide : Option<"address-slide", "R">,
196-
Arg<"Address">, Groups<[1,3,4,5,6,7,8]>,
196+
Arg<"Address">, Groups<[1,3,4,5,6,7,8,12]>,
197197
Desc<"Add the specified offset to whatever address(es) the breakpoint "
198198
"resolves to. At present this applies the offset directly as given, and "
199199
"doesn't try to align it to instruction boundaries.">;
200200
def breakpoint_set_move_to_nearest_code : Option<"move-to-nearest-code", "m">,
201-
Groups<[1, 9]>, Arg<"Boolean">,
201+
Groups<[1,9,12]>, Arg<"Boolean">,
202202
Desc<"Move breakpoints to nearest code. If not set the "
203203
"target.move-to-nearest-codesetting is used.">;
204+
def breakpoint_set_file_colon_line : Option<"joint-specifier", "y">, Group<12>, Arg<"FileLineColumn">,
205+
Required, Completion<"SourceFile">,
206+
Desc<"A specifier in the form filename:line[:column] for setting file & line breakpoints.">;
204207
/* Don't add this option till it actually does something useful...
205208
def breakpoint_set_exception_typename : Option<"exception-typename", "O">,
206209
Arg<"TypeName">, Desc<"The breakpoint will only stop if an "
@@ -729,7 +732,7 @@ let Command = "source info" in {
729732
let Command = "source list" in {
730733
def source_list_count : Option<"count", "c">, Arg<"Count">,
731734
Desc<"The number of source lines to display.">;
732-
def source_list_shlib : Option<"shlib", "s">, Groups<[1,2]>, Arg<"ShlibName">,
735+
def source_list_shlib : Option<"shlib", "s">, Groups<[1,2,5]>, Arg<"ShlibName">,
733736
Completion<"Module">,
734737
Desc<"Look up the source file in the given shared library.">;
735738
def source_list_show_breakpoints : Option<"show-breakpoints", "b">,
@@ -747,6 +750,10 @@ let Command = "source list" in {
747750
" information for the corresponding file and line.">;
748751
def source_list_reverse : Option<"reverse", "r">, Group<4>, Desc<"Reverse the"
749752
" listing to look backwards from the last displayed block of source.">;
753+
def source_list_file_colon_line : Option<"joint-specifier", "y">, Group<5>,
754+
Arg<"FileLineColumn">, Completion<"SourceFile">,
755+
Desc<"A specifier in the form filename:line[:column] from which to display"
756+
" source.">;
750757
}
751758

752759
let Command = "target dependents" in {

lldb/source/Interpreter/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ add_lldb_library(lldbInterpreter
3535
OptionValueChar.cpp
3636
OptionValueDictionary.cpp
3737
OptionValueEnumeration.cpp
38+
OptionValueFileColonLine.cpp
3839
OptionValueFileSpec.cpp
3940
OptionValueFileSpecList.cpp
4041
OptionValueFormat.cpp

lldb/source/Interpreter/CommandObject.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,7 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
10641064
{ eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a list." },
10651065
{ eArgTypeLanguage, "source-language", CommandCompletions::eNoCompletion, { LanguageTypeHelpTextCallback, true }, nullptr },
10661066
{ eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { nullptr, false }, "Line number in a source file." },
1067+
{ eArgTypeFileLineColumn, "linespec", CommandCompletions::eNoCompletion, { nullptr, false }, "A source specifier in the form file:line[:column]" },
10671068
{ eArgTypeLogCategory, "log-category", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a category within a log channel, e.g. all (try \"log list\" to see a list of all channels and their categories." },
10681069
{ eArgTypeLogChannel, "log-channel", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a log channel, e.g. process.gdb-remote (try \"log list\" to see a list of all channels and their categories)." },
10691070
{ eArgTypeMethod, "method", CommandCompletions::eNoCompletion, { nullptr, false }, "A C++ method name." },

lldb/source/Interpreter/OptionValue.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@ const char *OptionValue::GetBuiltinTypeAsCString(Type t) {
471471
return "dictionary";
472472
case eTypeEnum:
473473
return "enum";
474+
case eTypeFileLineColumn:
475+
return "file:line:column specifier";
474476
case eTypeFileSpec:
475477
return "file";
476478
case eTypeFileSpecList:

lldb/source/Interpreter/OptionValueArray.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ void OptionValueArray::DumpValue(const ExecutionContext *exe_ctx, Stream &strm,
5252
case eTypeChar:
5353
case eTypeEnum:
5454
case eTypeFileSpec:
55+
case eTypeFileLineColumn:
5556
case eTypeFormat:
5657
case eTypeSInt64:
5758
case eTypeString:

lldb/source/Interpreter/OptionValueDictionary.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ void OptionValueDictionary::DumpValue(const ExecutionContext *exe_ctx,
6262
case eTypeBoolean:
6363
case eTypeChar:
6464
case eTypeEnum:
65+
case eTypeFileLineColumn:
6566
case eTypeFileSpec:
6667
case eTypeFormat:
6768
case eTypeSInt64:

0 commit comments

Comments
 (0)