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