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