]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/location.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / location.c
CommitLineData
264f9890 1/* Data structures and API for location specs in GDB.
1d506c26 2 Copyright (C) 2013-2024 Free Software Foundation, Inc.
c7c1b3e9
KS
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#include "defs.h"
268a13a5 20#include "gdbsupport/gdb_assert.h"
5f48d886 21#include "gdbsupport/gdb-checked-static-cast.h"
c7c1b3e9
KS
22#include "location.h"
23#include "symtab.h"
24#include "language.h"
25#include "linespec.h"
26#include "cli/cli-utils.h"
27#include "probe.h"
8090b426 28#include "cp-support.h"
c7c1b3e9
KS
29
30#include <ctype.h>
31#include <string.h>
32
40d97ee2
PA
33static std::string
34 explicit_to_string_internal (bool as_linespec,
35 const explicit_location_spec *explicit_loc);
36
37/* Return a xstrdup of STR if not NULL, otherwise return NULL. */
2b0c285e 38
40d97ee2
PA
39static char *
40maybe_xstrdup (const char *str)
41{
42 return (str != nullptr ? xstrdup (str) : nullptr);
43}
44
45probe_location_spec::probe_location_spec (std::string &&probe)
46 : location_spec (PROBE_LOCATION_SPEC, std::move (probe))
47{
48}
c7c1b3e9 49
40d97ee2
PA
50location_spec_up
51probe_location_spec::clone () const
c7c1b3e9 52{
40d97ee2
PA
53 return location_spec_up (new probe_location_spec (*this));
54}
55
56bool
57probe_location_spec::empty_p () const
2b0c285e 58{
40d97ee2
PA
59 return false;
60}
61
62std::string probe_location_spec::compute_string () const
63{
dac9773e 64 return std::move (m_as_string);
40d97ee2 65}
2b0c285e
TT
66
67/* A "normal" linespec. */
40d97ee2
PA
68linespec_location_spec::linespec_location_spec
69 (const char **linespec, symbol_name_match_type match_type_)
70 : location_spec (LINESPEC_LOCATION_SPEC),
71 match_type (match_type_)
2b0c285e 72{
40d97ee2
PA
73 if (*linespec != NULL)
74 {
75 const char *p;
76 const char *orig = *linespec;
77
78 linespec_lex_to_end (linespec);
79 p = remove_trailing_whitespace (orig, *linespec);
80
81 /* If there is no valid linespec then this will leave the
82 spec_string as nullptr. This behaviour is relied on in the
83 breakpoint setting code, where spec_string being nullptr means
84 to use the default breakpoint location. */
85 if ((p - orig) > 0)
e7cdec66 86 spec_string.reset (savestring (orig, p - orig));
40d97ee2
PA
87 }
88}
89
40d97ee2
PA
90location_spec_up
91linespec_location_spec::clone () const
2b0c285e 92{
40d97ee2
PA
93 return location_spec_up (new linespec_location_spec (*this));
94}
c7c1b3e9 95
40d97ee2
PA
96bool
97linespec_location_spec::empty_p () const
98{
99 return false;
100}
c7c1b3e9 101
40d97ee2
PA
102linespec_location_spec::linespec_location_spec
103 (const linespec_location_spec &other)
104 : location_spec (other),
105 match_type (other.match_type),
e7cdec66 106 spec_string (maybe_xstrdup (other.spec_string.get ()))
c7c1b3e9 107{
40d97ee2
PA
108}
109
110std::string
111linespec_location_spec::compute_string () const
112{
113 if (spec_string != nullptr)
114 {
115 if (match_type == symbol_name_match_type::FULL)
e7cdec66 116 return std::string ("-qualified ") + spec_string.get ();
40d97ee2 117 else
e7cdec66 118 return spec_string.get ();
40d97ee2
PA
119 }
120 return {};
121}
122
123address_location_spec::address_location_spec (CORE_ADDR addr,
124 const char *addr_string,
125 int addr_string_len)
126 : location_spec (ADDRESS_LOCATION_SPEC),
127 address (addr)
128{
129 if (addr_string != nullptr)
dac9773e 130 m_as_string = std::string (addr_string, addr_string_len);
40d97ee2
PA
131}
132
133location_spec_up
134address_location_spec::clone () const
135{
136 return location_spec_up (new address_location_spec (*this));
137}
138
139bool
140address_location_spec::empty_p () const
141{
142 return false;
143}
144
145address_location_spec::address_location_spec
146 (const address_location_spec &other)
147 : location_spec (other),
148 address (other.address)
149{
150}
151
152std::string
153address_location_spec::compute_string () const
154{
155 const char *addr_string = core_addr_to_string (address);
156 return std::string ("*") + addr_string;
157}
158
fde84194
TT
159explicit_location_spec::explicit_location_spec (const char *function_name)
160 : location_spec (EXPLICIT_LOCATION_SPEC),
161 function_name (maybe_xstrdup (function_name))
40d97ee2
PA
162{
163}
164
40d97ee2
PA
165explicit_location_spec::explicit_location_spec
166 (const explicit_location_spec &other)
167 : location_spec (other),
fde84194
TT
168 source_filename (maybe_xstrdup (other.source_filename.get ())),
169 function_name (maybe_xstrdup (other.function_name.get ())),
40d97ee2 170 func_name_match_type (other.func_name_match_type),
fde84194 171 label_name (maybe_xstrdup (other.label_name.get ())),
40d97ee2
PA
172 line_offset (other.line_offset)
173{
174}
175
176location_spec_up
177explicit_location_spec::clone () const
178{
179 return location_spec_up (new explicit_location_spec (*this));
180}
181
182bool
183explicit_location_spec::empty_p () const
184{
185 return (source_filename == nullptr
186 && function_name == nullptr
187 && label_name == nullptr
188 && line_offset.sign == LINE_OFFSET_UNKNOWN);
189}
190
191std::string
192explicit_location_spec::compute_string () const
193{
194 return explicit_to_string_internal (false, this);
c7c1b3e9
KS
195}
196
197/* See description in location.h. */
198
264f9890
PA
199location_spec_up
200new_linespec_location_spec (const char **linespec,
201 symbol_name_match_type match_type)
c7c1b3e9 202{
264f9890
PA
203 return location_spec_up (new linespec_location_spec (linespec,
204 match_type));
c7c1b3e9
KS
205}
206
207/* See description in location.h. */
208
40d97ee2
PA
209const linespec_location_spec *
210as_linespec_location_spec (const location_spec *locspec)
c7c1b3e9 211{
7464aeaa 212 gdb_assert (locspec->type () == LINESPEC_LOCATION_SPEC);
98ed24fb 213 return gdb::checked_static_cast<const linespec_location_spec *> (locspec);
c7c1b3e9
KS
214}
215
216/* See description in location.h. */
217
264f9890
PA
218location_spec_up
219new_address_location_spec (CORE_ADDR addr, const char *addr_string,
220 int addr_string_len)
a06efdd6 221{
264f9890
PA
222 return location_spec_up (new address_location_spec (addr, addr_string,
223 addr_string_len));
a06efdd6
KS
224}
225
226/* See description in location.h. */
227
40d97ee2
PA
228const address_location_spec *
229as_address_location_spec (const location_spec *locspec)
a06efdd6 230{
7464aeaa 231 gdb_assert (locspec->type () == ADDRESS_LOCATION_SPEC);
98ed24fb 232 return gdb::checked_static_cast<const address_location_spec *> (locspec);
305e13e6
JB
233}
234
235/* See description in location.h. */
236
264f9890
PA
237location_spec_up
238new_probe_location_spec (std::string &&probe)
5b56227b 239{
264f9890 240 return location_spec_up (new probe_location_spec (std::move (probe)));
5b56227b
KS
241}
242
243/* See description in location.h. */
244
40d97ee2
PA
245const probe_location_spec *
246as_probe_location_spec (const location_spec *locspec)
5b56227b 247{
7464aeaa 248 gdb_assert (locspec->type () == PROBE_LOCATION_SPEC);
98ed24fb 249 return gdb::checked_static_cast<const probe_location_spec *> (locspec);
00e52e53
KS
250}
251
252/* See description in location.h. */
253
40d97ee2
PA
254const explicit_location_spec *
255as_explicit_location_spec (const location_spec *locspec)
00e52e53 256{
7464aeaa 257 gdb_assert (locspec->type () == EXPLICIT_LOCATION_SPEC);
98ed24fb 258 return gdb::checked_static_cast<const explicit_location_spec *> (locspec);
00e52e53
KS
259}
260
261/* See description in location.h. */
262
40d97ee2
PA
263explicit_location_spec *
264as_explicit_location_spec (location_spec *locspec)
00e52e53 265{
7464aeaa 266 gdb_assert (locspec->type () == EXPLICIT_LOCATION_SPEC);
98ed24fb 267 return gdb::checked_static_cast<explicit_location_spec *> (locspec);
00e52e53
KS
268}
269
264f9890
PA
270/* Return a string representation of the explicit location spec in
271 EXPLICIT_LOCSPEC.
00e52e53 272
264f9890
PA
273 AS_LINESPEC is true if this string should be a linespec. Otherwise
274 it will be output in explicit form. */
00e52e53 275
85e428a6 276static std::string
7910e2de 277explicit_to_string_internal (bool as_linespec,
40d97ee2 278 const explicit_location_spec *explicit_loc)
00e52e53 279{
7910e2de 280 bool need_space = false;
d7e74731
PA
281 char space = as_linespec ? ':' : ' ';
282 string_file buf;
00e52e53 283
67994074 284 if (explicit_loc->source_filename != NULL)
00e52e53
KS
285 {
286 if (!as_linespec)
d7e74731 287 buf.puts ("-source ");
fde84194 288 buf.puts (explicit_loc->source_filename.get ());
7910e2de 289 need_space = true;
00e52e53
KS
290 }
291
67994074 292 if (explicit_loc->function_name != NULL)
00e52e53
KS
293 {
294 if (need_space)
d7e74731 295 buf.putc (space);
a20714ff
PA
296 if (explicit_loc->func_name_match_type == symbol_name_match_type::FULL)
297 buf.puts ("-qualified ");
00e52e53 298 if (!as_linespec)
d7e74731 299 buf.puts ("-function ");
fde84194 300 buf.puts (explicit_loc->function_name.get ());
7910e2de 301 need_space = true;
00e52e53
KS
302 }
303
67994074 304 if (explicit_loc->label_name != NULL)
00e52e53
KS
305 {
306 if (need_space)
d7e74731 307 buf.putc (space);
00e52e53 308 if (!as_linespec)
d7e74731 309 buf.puts ("-label ");
fde84194 310 buf.puts (explicit_loc->label_name.get ());
7910e2de 311 need_space = true;
00e52e53
KS
312 }
313
67994074 314 if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN)
00e52e53
KS
315 {
316 if (need_space)
d7e74731 317 buf.putc (space);
00e52e53 318 if (!as_linespec)
d7e74731
PA
319 buf.puts ("-line ");
320 buf.printf ("%s%d",
321 (explicit_loc->line_offset.sign == LINE_OFFSET_NONE ? ""
322 : (explicit_loc->line_offset.sign
323 == LINE_OFFSET_PLUS ? "+" : "-")),
324 explicit_loc->line_offset.offset);
00e52e53
KS
325 }
326
5d10a204 327 return buf.release ();
00e52e53
KS
328}
329
330/* See description in location.h. */
331
85e428a6 332std::string
40d97ee2 333explicit_location_spec::to_linespec () const
00e52e53 334{
40d97ee2 335 return explicit_to_string_internal (true, this);
00e52e53
KS
336}
337
c6756f62
PA
338/* Find an instance of the quote character C in the string S that is
339 outside of all single- and double-quoted strings (i.e., any quoting
340 other than C). */
341
342static const char *
343find_end_quote (const char *s, char end_quote_char)
344{
345 /* zero if we're not in quotes;
346 '"' if we're in a double-quoted string;
347 '\'' if we're in a single-quoted string. */
348 char nested_quote_char = '\0';
349
350 for (const char *scan = s; *scan != '\0'; scan++)
351 {
352 if (nested_quote_char != '\0')
353 {
354 if (*scan == nested_quote_char)
355 nested_quote_char = '\0';
356 else if (scan[0] == '\\' && *(scan + 1) != '\0')
357 scan++;
358 }
359 else if (*scan == end_quote_char && nested_quote_char == '\0')
360 return scan;
361 else if (*scan == '"' || *scan == '\'')
362 nested_quote_char = *scan;
363 }
364
365 return 0;
366}
367
264f9890
PA
368/* A lexer for explicit location specs. This function will advance
369 INP past any strings that it lexes. Returns a malloc'd copy of the
87f0e720
KS
370 lexed string or NULL if no lexing was done. */
371
4b217cc7 372static gdb::unique_xmalloc_ptr<char>
264f9890
PA
373explicit_location_spec_lex_one (const char **inp,
374 const struct language_defn *language,
375 explicit_completion_info *completion_info)
87f0e720
KS
376{
377 const char *start = *inp;
378
379 if (*start == '\0')
380 return NULL;
381
382 /* If quoted, skip to the ending quote. */
383 if (strchr (get_gdb_linespec_parser_quote_characters (), *start))
384 {
c6756f62
PA
385 if (completion_info != NULL)
386 completion_info->quoted_arg_start = start;
87f0e720 387
c6756f62 388 const char *end = find_end_quote (start + 1, *start);
87f0e720 389
c6756f62
PA
390 if (end == NULL)
391 {
392 if (completion_info == NULL)
87f0e720 393 error (_("Unmatched quote, %s."), start);
c6756f62
PA
394
395 end = start + strlen (start);
396 *inp = end;
4b217cc7 397 return gdb::unique_xmalloc_ptr<char> (savestring (start + 1,
c6756f62 398 *inp - start - 1));
87f0e720 399 }
c6756f62
PA
400
401 if (completion_info != NULL)
402 completion_info->quoted_arg_end = end;
403 *inp = end + 1;
404 return gdb::unique_xmalloc_ptr<char> (savestring (start + 1,
405 *inp - start - 2));
87f0e720
KS
406 }
407
408 /* If the input starts with '-' or '+', the string ends with the next
409 whitespace or comma. */
410 if (*start == '-' || *start == '+')
411 {
412 while (*inp[0] != '\0' && *inp[0] != ',' && !isspace (*inp[0]))
413 ++(*inp);
414 }
415 else
416 {
417 /* Handle numbers first, stopping at the next whitespace or ','. */
418 while (isdigit (*inp[0]))
419 ++(*inp);
420 if (*inp[0] == '\0' || isspace (*inp[0]) || *inp[0] == ',')
4b217cc7
TT
421 return gdb::unique_xmalloc_ptr<char> (savestring (start,
422 *inp - start));
87f0e720
KS
423
424 /* Otherwise stop at the next occurrence of whitespace, '\0',
425 keyword, or ','. */
426 *inp = start;
427 while ((*inp)[0]
428 && (*inp)[0] != ','
429 && !(isspace ((*inp)[0])
430 || linespec_lexer_lex_keyword (&(*inp)[1])))
431 {
432 /* Special case: C++ operator,. */
433 if (language->la_language == language_cplus
8090b426
PA
434 && startswith (*inp, CP_OPERATOR_STR))
435 (*inp) += CP_OPERATOR_LEN;
87f0e720
KS
436 ++(*inp);
437 }
438 }
439
440 if (*inp - start > 0)
4b217cc7 441 return gdb::unique_xmalloc_ptr<char> (savestring (start, *inp - start));
87f0e720
KS
442
443 return NULL;
444}
445
c6756f62
PA
446/* Return true if COMMA points past "operator". START is the start of
447 the line that COMMAND points to, hence when reading backwards, we
448 must not read any character before START. */
449
450static bool
451is_cp_operator (const char *start, const char *comma)
452{
453 if (comma != NULL
454 && (comma - start) >= CP_OPERATOR_LEN)
455 {
456 const char *p = comma;
457
458 while (p > start && isspace (p[-1]))
459 p--;
460 if (p - start >= CP_OPERATOR_LEN)
461 {
462 p -= CP_OPERATOR_LEN;
463 if (strncmp (p, CP_OPERATOR_STR, CP_OPERATOR_LEN) == 0
464 && (p == start
465 || !(isalnum (p[-1]) || p[-1] == '_')))
466 {
467 return true;
468 }
469 }
470 }
471 return false;
472}
473
474/* When scanning the input string looking for the next explicit
264f9890 475 location spec option/delimiter, we jump to the next option by looking
c6756f62
PA
476 for ",", and "-". Such a character can also appear in C++ symbols
477 like "operator," and "operator-". So when we find such a
478 character, we call this function to check if we found such a
479 symbol, meaning we had a false positive for an option string. In
480 that case, we keep looking for the next delimiter, until we find
481 one that is not a false positive, or we reach end of string. FOUND
482 is the character that scanning found (either '-' or ','), and START
483 is the start of the line that FOUND points to, hence when reading
484 backwards, we must not read any character before START. Returns a
485 pointer to the next non-false-positive delimiter character, or NULL
486 if none was found. */
487
488static const char *
489skip_op_false_positives (const char *start, const char *found)
490{
491 while (found != NULL && is_cp_operator (start, found))
492 {
493 if (found[0] == '-' && found[1] == '-')
494 start = found + 2;
495 else
496 start = found + 1;
497 found = find_toplevel_char (start, *found);
498 }
499
500 return found;
501}
502
503/* Assuming both FIRST and NEW_TOK point into the same string, return
504 the pointer that is closer to the start of the string. If FIRST is
505 NULL, returns NEW_TOK. If NEW_TOK is NULL, returns FIRST. */
506
507static const char *
508first_of (const char *first, const char *new_tok)
509{
510 if (first == NULL)
511 return new_tok;
512 else if (new_tok != NULL && new_tok < first)
513 return new_tok;
514 else
515 return first;
516}
517
264f9890 518/* A lexer for functions in explicit location specs. This function will
c6756f62
PA
519 advance INP past a function until the next option, or until end of
520 string. Returns a malloc'd copy of the lexed string or NULL if no
521 lexing was done. */
522
523static gdb::unique_xmalloc_ptr<char>
264f9890
PA
524explicit_location_spec_lex_one_function
525 (const char **inp,
526 const struct language_defn *language,
527 explicit_completion_info *completion_info)
c6756f62
PA
528{
529 const char *start = *inp;
530
531 if (*start == '\0')
532 return NULL;
533
534 /* If quoted, skip to the ending quote. */
535 if (strchr (get_gdb_linespec_parser_quote_characters (), *start))
536 {
537 char quote_char = *start;
538
539 /* If the input is not an Ada operator, skip to the matching
540 closing quote and return the string. */
541 if (!(language->la_language == language_ada
542 && quote_char == '\"' && is_ada_operator (start)))
543 {
544 if (completion_info != NULL)
545 completion_info->quoted_arg_start = start;
546
547 const char *end = find_toplevel_char (start + 1, quote_char);
548
549 if (end == NULL)
550 {
551 if (completion_info == NULL)
552 error (_("Unmatched quote, %s."), start);
553
554 end = start + strlen (start);
555 *inp = end;
556 char *saved = savestring (start + 1, *inp - start - 1);
557 return gdb::unique_xmalloc_ptr<char> (saved);
558 }
559
560 if (completion_info != NULL)
561 completion_info->quoted_arg_end = end;
562 *inp = end + 1;
563 char *saved = savestring (start + 1, *inp - start - 2);
564 return gdb::unique_xmalloc_ptr<char> (saved);
565 }
566 }
567
568 const char *comma = find_toplevel_char (start, ',');
569
570 /* If we have "-function -myfunction", or perhaps better example,
571 "-function -[BasicClass doIt]" (objc selector), treat
572 "-myfunction" as the function name. I.e., skip the first char if
573 it is an hyphen. Don't skip the first char always, because we
574 may have C++ "operator<", and find_toplevel_char needs to see the
575 'o' in that case. */
576 const char *hyphen
577 = (*start == '-'
578 ? find_toplevel_char (start + 1, '-')
579 : find_toplevel_char (start, '-'));
580
581 /* Check for C++ "operator," and "operator-". */
582 comma = skip_op_false_positives (start, comma);
583 hyphen = skip_op_false_positives (start, hyphen);
584
585 /* Pick the one that appears first. */
586 const char *end = first_of (hyphen, comma);
587
588 /* See if a linespec keyword appears first. */
589 const char *s = start;
590 const char *ws = find_toplevel_char (start, ' ');
591 while (ws != NULL && linespec_lexer_lex_keyword (ws + 1) == NULL)
592 {
593 s = ws + 1;
594 ws = find_toplevel_char (s, ' ');
595 }
596 if (ws != NULL)
597 end = first_of (end, ws + 1);
598
599 /* If we don't have any terminator, then take the whole string. */
600 if (end == NULL)
601 end = start + strlen (start);
602
603 /* Trim whitespace at the end. */
604 while (end > start && end[-1] == ' ')
605 end--;
606
607 *inp = end;
608
609 if (*inp - start > 0)
610 return gdb::unique_xmalloc_ptr<char> (savestring (start, *inp - start));
611
612 return NULL;
613}
614
87f0e720
KS
615/* See description in location.h. */
616
264f9890
PA
617location_spec_up
618string_to_explicit_location_spec (const char **argp,
619 const struct language_defn *language,
620 explicit_completion_info *completion_info)
87f0e720 621{
87f0e720 622 /* It is assumed that input beginning with '-' and a non-digit
eeb1af43
KS
623 character is an explicit location. "-p" is reserved, though,
624 for probe locations. */
87f0e720 625 if (argp == NULL
e742d386 626 || *argp == NULL
87f0e720 627 || *argp[0] != '-'
eeb1af43
KS
628 || !isalpha ((*argp)[1])
629 || ((*argp)[0] == '-' && (*argp)[1] == 'p'))
87f0e720
KS
630 return NULL;
631
264f9890 632 std::unique_ptr<explicit_location_spec> locspec
40d97ee2 633 (new explicit_location_spec ());
87f0e720
KS
634
635 /* Process option/argument pairs. dprintf_command
636 requires that processing stop on ','. */
637 while ((*argp)[0] != '\0' && (*argp)[0] != ',')
638 {
639 int len;
87f0e720 640 const char *start;
87f0e720 641
c6756f62
PA
642 /* Clear these on each iteration, since they should be filled
643 with info about the last option. */
644 if (completion_info != NULL)
645 {
646 completion_info->quoted_arg_start = NULL;
647 completion_info->quoted_arg_end = NULL;
648 }
649
87f0e720
KS
650 /* If *ARGP starts with a keyword, stop processing
651 options. */
652 if (linespec_lexer_lex_keyword (*argp) != NULL)
653 break;
654
655 /* Mark the start of the string in case we need to rewind. */
656 start = *argp;
657
c6756f62
PA
658 if (completion_info != NULL)
659 completion_info->last_option = start;
660
87f0e720 661 /* Get the option string. */
4b217cc7 662 gdb::unique_xmalloc_ptr<char> opt
264f9890 663 = explicit_location_spec_lex_one (argp, language, NULL);
87f0e720 664
c6756f62
PA
665 /* Use the length of the option to allow abbreviations. */
666 len = strlen (opt.get ());
87f0e720
KS
667
668 /* Get the argument string. */
f1735a53 669 *argp = skip_spaces (*argp);
87f0e720 670
c6756f62
PA
671 /* All options have a required argument. Checking for this
672 required argument is deferred until later. */
673 gdb::unique_xmalloc_ptr<char> oarg;
674 /* True if we have an argument. This is required because we'll
675 move from OARG before checking whether we have an
676 argument. */
677 bool have_oarg = false;
678
a20714ff
PA
679 /* True if the option needs an argument. */
680 bool need_oarg = false;
681
c6756f62
PA
682 /* Convenience to consistently set both OARG/HAVE_OARG from
683 ARG. */
684 auto set_oarg = [&] (gdb::unique_xmalloc_ptr<char> arg)
685 {
a20714ff
PA
686 if (completion_info != NULL)
687 {
688 /* We do this here because the set of options that take
689 arguments matches the set of explicit location
690 options. */
264f9890 691 completion_info->saw_explicit_location_spec_option = true;
a20714ff 692 }
c6756f62
PA
693 oarg = std::move (arg);
694 have_oarg = oarg != NULL;
a20714ff 695 need_oarg = true;
c6756f62 696 };
87f0e720 697
4b217cc7 698 if (strncmp (opt.get (), "-source", len) == 0)
c6756f62 699 {
264f9890
PA
700 set_oarg (explicit_location_spec_lex_one (argp, language,
701 completion_info));
fde84194 702 locspec->source_filename = std::move (oarg);
c6756f62 703 }
4b217cc7 704 else if (strncmp (opt.get (), "-function", len) == 0)
c6756f62 705 {
264f9890
PA
706 set_oarg (explicit_location_spec_lex_one_function (argp, language,
707 completion_info));
fde84194 708 locspec->function_name = std::move (oarg);
c6756f62 709 }
a20714ff
PA
710 else if (strncmp (opt.get (), "-qualified", len) == 0)
711 {
40d97ee2 712 locspec->func_name_match_type = symbol_name_match_type::FULL;
a20714ff 713 }
4b217cc7 714 else if (strncmp (opt.get (), "-line", len) == 0)
87f0e720 715 {
264f9890 716 set_oarg (explicit_location_spec_lex_one (argp, language, NULL));
f1735a53 717 *argp = skip_spaces (*argp);
4b217cc7 718 if (have_oarg)
c6756f62 719 {
40d97ee2 720 locspec->line_offset = linespec_parse_line_offset (oarg.get ());
c6756f62
PA
721 continue;
722 }
87f0e720 723 }
4b217cc7 724 else if (strncmp (opt.get (), "-label", len) == 0)
c6756f62 725 {
264f9890
PA
726 set_oarg (explicit_location_spec_lex_one (argp, language,
727 completion_info));
fde84194 728 locspec->label_name = std::move (oarg);
c6756f62 729 }
87f0e720
KS
730 /* Only emit an "invalid argument" error for options
731 that look like option strings. */
4b217cc7 732 else if (opt.get ()[0] == '-' && !isdigit (opt.get ()[1]))
87f0e720 733 {
c6756f62 734 if (completion_info == NULL)
4b217cc7 735 error (_("invalid explicit location argument, \"%s\""), opt.get ());
87f0e720
KS
736 }
737 else
738 {
739 /* End of the explicit location specification.
740 Stop parsing and return whatever explicit location was
741 parsed. */
742 *argp = start;
fa6eb693 743 break;
87f0e720
KS
744 }
745
f1735a53 746 *argp = skip_spaces (*argp);
c6756f62 747
87f0e720
KS
748 /* It's a little lame to error after the fact, but in this
749 case, it provides a much better user experience to issue
750 the "invalid argument" error before any missing
751 argument error. */
a20714ff 752 if (need_oarg && !have_oarg && completion_info == NULL)
4b217cc7 753 error (_("missing argument for \"%s\""), opt.get ());
87f0e720
KS
754 }
755
756 /* One special error check: If a source filename was given
757 without offset, function, or label, issue an error. */
40d97ee2
PA
758 if (locspec->source_filename != NULL
759 && locspec->function_name == NULL
760 && locspec->label_name == NULL
761 && (locspec->line_offset.sign == LINE_OFFSET_UNKNOWN)
c6756f62 762 && completion_info == NULL)
87f0e720
KS
763 {
764 error (_("Source filename requires function, label, or "
765 "line offset."));
766 }
767
264f9890 768 return location_spec_up (locspec.release ());
87f0e720
KS
769}
770
c7c1b3e9
KS
771/* See description in location.h. */
772
264f9890
PA
773location_spec_up
774string_to_location_spec_basic (const char **stringp,
775 const struct language_defn *language,
776 symbol_name_match_type match_type)
c7c1b3e9 777{
264f9890 778 location_spec_up locspec;
870f88f7 779 const char *cs;
c7c1b3e9 780
eeb1af43
KS
781 /* Try the input as a probe spec. */
782 cs = *stringp;
935676c9 783 if (cs != NULL && probe_linespec_to_static_ops (&cs) != NULL)
a06efdd6 784 {
264f9890 785 locspec = new_probe_location_spec (*stringp);
eeb1af43 786 *stringp += strlen (*stringp);
a06efdd6
KS
787 }
788 else
789 {
264f9890 790 /* Try an address location spec. */
eeb1af43 791 if (*stringp != NULL && **stringp == '*')
5b56227b 792 {
87f0e720 793 const char *arg, *orig;
eeb1af43 794 CORE_ADDR addr;
87f0e720 795
87f0e720 796 orig = arg = *stringp;
eeb1af43 797 addr = linespec_expression_to_pc (&arg);
264f9890 798 locspec = new_address_location_spec (addr, orig, arg - orig);
eeb1af43
KS
799 *stringp += arg - orig;
800 }
801 else
802 {
803 /* Everything else is a linespec. */
264f9890 804 locspec = new_linespec_location_spec (stringp, match_type);
5b56227b 805 }
a06efdd6
KS
806 }
807
264f9890 808 return locspec;
eeb1af43
KS
809}
810
811/* See description in location.h. */
812
264f9890
PA
813location_spec_up
814string_to_location_spec (const char **stringp,
815 const struct language_defn *language,
816 symbol_name_match_type match_type)
eeb1af43 817{
eeb1af43
KS
818 const char *arg, *orig;
819
264f9890 820 /* Try an explicit location spec. */
eeb1af43 821 orig = arg = *stringp;
264f9890
PA
822 location_spec_up locspec
823 = string_to_explicit_location_spec (&arg, language, NULL);
824 if (locspec != nullptr)
eeb1af43
KS
825 {
826 /* It was a valid explicit location. Advance STRINGP to
827 the end of input. */
828 *stringp += arg - orig;
a20714ff 829
264f9890
PA
830 /* If the user really specified a location spec, then we're
831 done. */
238dc9af 832 if (!locspec->empty_p ())
264f9890 833 return locspec;
a20714ff
PA
834
835 /* Otherwise, the user _only_ specified optional flags like
264f9890
PA
836 "-qualified", otherwise string_to_explicit_location_spec
837 would have thrown an error. Save the flags for "basic"
838 linespec parsing below and discard the explicit location
839 spec. */
840 explicit_location_spec *xloc
5f48d886 841 = gdb::checked_static_cast<explicit_location_spec *> (locspec.get ());
40d97ee2 842 match_type = xloc->func_name_match_type;
eeb1af43
KS
843 }
844
264f9890
PA
845 /* Everything else is a "basic" linespec, address, or probe location
846 spec. */
847 return string_to_location_spec_basic (stringp, language, match_type);
c7c1b3e9 848}