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