1 /* Data structures and API for location specs in GDB.
2 Copyright (C) 2013-2024 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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/>. */
20 #include "gdbsupport/gdb_assert.h"
21 #include "gdbsupport/gdb-checked-static-cast.h"
26 #include "cli/cli-utils.h"
28 #include "cp-support.h"
34 explicit_to_string_internal (bool as_linespec
,
35 const explicit_location_spec
*explicit_loc
);
37 /* Return a xstrdup of STR if not NULL, otherwise return NULL. */
40 maybe_xstrdup (const char *str
)
42 return (str
!= nullptr ? xstrdup (str
) : nullptr);
45 probe_location_spec::probe_location_spec (std::string
&&probe
)
46 : location_spec (PROBE_LOCATION_SPEC
, std::move (probe
))
51 probe_location_spec::clone () const
53 return location_spec_up (new probe_location_spec (*this));
57 probe_location_spec::empty_p () const
62 std::string
probe_location_spec::compute_string () const
64 return std::move (m_as_string
);
67 /* A "normal" linespec. */
68 linespec_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_
)
73 if (*linespec
!= NULL
)
76 const char *orig
= *linespec
;
78 linespec_lex_to_end (linespec
);
79 p
= remove_trailing_whitespace (orig
, *linespec
);
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. */
86 spec_string
.reset (savestring (orig
, p
- orig
));
91 linespec_location_spec::clone () const
93 return location_spec_up (new linespec_location_spec (*this));
97 linespec_location_spec::empty_p () const
102 linespec_location_spec::linespec_location_spec
103 (const linespec_location_spec
&other
)
104 : location_spec (other
),
105 match_type (other
.match_type
),
106 spec_string (maybe_xstrdup (other
.spec_string
.get ()))
111 linespec_location_spec::compute_string () const
113 if (spec_string
!= nullptr)
115 if (match_type
== symbol_name_match_type::FULL
)
116 return std::string ("-qualified ") + spec_string
.get ();
118 return spec_string
.get ();
123 address_location_spec::address_location_spec (CORE_ADDR addr
,
124 const char *addr_string
,
126 : location_spec (ADDRESS_LOCATION_SPEC
),
129 if (addr_string
!= nullptr)
130 m_as_string
= std::string (addr_string
, addr_string_len
);
134 address_location_spec::clone () const
136 return location_spec_up (new address_location_spec (*this));
140 address_location_spec::empty_p () const
145 address_location_spec::address_location_spec
146 (const address_location_spec
&other
)
147 : location_spec (other
),
148 address (other
.address
)
153 address_location_spec::compute_string () const
155 const char *addr_string
= core_addr_to_string (address
);
156 return std::string ("*") + addr_string
;
159 explicit_location_spec::explicit_location_spec (const char *function_name
)
160 : location_spec (EXPLICIT_LOCATION_SPEC
),
161 function_name (maybe_xstrdup (function_name
))
165 explicit_location_spec::explicit_location_spec
166 (const explicit_location_spec
&other
)
167 : location_spec (other
),
168 source_filename (maybe_xstrdup (other
.source_filename
.get ())),
169 function_name (maybe_xstrdup (other
.function_name
.get ())),
170 func_name_match_type (other
.func_name_match_type
),
171 label_name (maybe_xstrdup (other
.label_name
.get ())),
172 line_offset (other
.line_offset
)
177 explicit_location_spec::clone () const
179 return location_spec_up (new explicit_location_spec (*this));
183 explicit_location_spec::empty_p () const
185 return (source_filename
== nullptr
186 && function_name
== nullptr
187 && label_name
== nullptr
188 && line_offset
.sign
== LINE_OFFSET_UNKNOWN
);
192 explicit_location_spec::compute_string () const
194 return explicit_to_string_internal (false, this);
197 /* See description in location.h. */
200 new_linespec_location_spec (const char **linespec
,
201 symbol_name_match_type match_type
)
203 return location_spec_up (new linespec_location_spec (linespec
,
207 /* See description in location.h. */
209 const linespec_location_spec
*
210 as_linespec_location_spec (const location_spec
*locspec
)
212 gdb_assert (locspec
->type () == LINESPEC_LOCATION_SPEC
);
213 return gdb::checked_static_cast
<const linespec_location_spec
*> (locspec
);
216 /* See description in location.h. */
219 new_address_location_spec (CORE_ADDR addr
, const char *addr_string
,
222 return location_spec_up (new address_location_spec (addr
, addr_string
,
226 /* See description in location.h. */
228 const address_location_spec
*
229 as_address_location_spec (const location_spec
*locspec
)
231 gdb_assert (locspec
->type () == ADDRESS_LOCATION_SPEC
);
232 return gdb::checked_static_cast
<const address_location_spec
*> (locspec
);
235 /* See description in location.h. */
238 new_probe_location_spec (std::string
&&probe
)
240 return location_spec_up (new probe_location_spec (std::move (probe
)));
243 /* See description in location.h. */
245 const probe_location_spec
*
246 as_probe_location_spec (const location_spec
*locspec
)
248 gdb_assert (locspec
->type () == PROBE_LOCATION_SPEC
);
249 return gdb::checked_static_cast
<const probe_location_spec
*> (locspec
);
252 /* See description in location.h. */
254 const explicit_location_spec
*
255 as_explicit_location_spec (const location_spec
*locspec
)
257 gdb_assert (locspec
->type () == EXPLICIT_LOCATION_SPEC
);
258 return gdb::checked_static_cast
<const explicit_location_spec
*> (locspec
);
261 /* See description in location.h. */
263 explicit_location_spec
*
264 as_explicit_location_spec (location_spec
*locspec
)
266 gdb_assert (locspec
->type () == EXPLICIT_LOCATION_SPEC
);
267 return gdb::checked_static_cast
<explicit_location_spec
*> (locspec
);
270 /* Return a string representation of the explicit location spec in
273 AS_LINESPEC is true if this string should be a linespec. Otherwise
274 it will be output in explicit form. */
277 explicit_to_string_internal (bool as_linespec
,
278 const explicit_location_spec
*explicit_loc
)
280 bool need_space
= false;
281 char space
= as_linespec
? ':' : ' ';
284 if (explicit_loc
->source_filename
!= NULL
)
287 buf
.puts ("-source ");
288 buf
.puts (explicit_loc
->source_filename
.get ());
292 if (explicit_loc
->function_name
!= NULL
)
296 if (explicit_loc
->func_name_match_type
== symbol_name_match_type::FULL
)
297 buf
.puts ("-qualified ");
299 buf
.puts ("-function ");
300 buf
.puts (explicit_loc
->function_name
.get ());
304 if (explicit_loc
->label_name
!= NULL
)
309 buf
.puts ("-label ");
310 buf
.puts (explicit_loc
->label_name
.get ());
314 if (explicit_loc
->line_offset
.sign
!= LINE_OFFSET_UNKNOWN
)
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
);
327 return buf
.release ();
330 /* See description in location.h. */
333 explicit_location_spec::to_linespec () const
335 return explicit_to_string_internal (true, this);
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
343 find_end_quote (const char *s
, char end_quote_char
)
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';
350 for (const char *scan
= s
; *scan
!= '\0'; scan
++)
352 if (nested_quote_char
!= '\0')
354 if (*scan
== nested_quote_char
)
355 nested_quote_char
= '\0';
356 else if (scan
[0] == '\\' && *(scan
+ 1) != '\0')
359 else if (*scan
== end_quote_char
&& nested_quote_char
== '\0')
361 else if (*scan
== '"' || *scan
== '\'')
362 nested_quote_char
= *scan
;
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
370 lexed string or NULL if no lexing was done. */
372 static gdb::unique_xmalloc_ptr
<char>
373 explicit_location_spec_lex_one (const char **inp
,
374 const struct language_defn
*language
,
375 explicit_completion_info
*completion_info
)
377 const char *start
= *inp
;
382 /* If quoted, skip to the ending quote. */
383 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
385 if (completion_info
!= NULL
)
386 completion_info
->quoted_arg_start
= start
;
388 const char *end
= find_end_quote (start
+ 1, *start
);
392 if (completion_info
== NULL
)
393 error (_("Unmatched quote, %s."), start
);
395 end
= start
+ strlen (start
);
397 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
401 if (completion_info
!= NULL
)
402 completion_info
->quoted_arg_end
= end
;
404 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
408 /* If the input starts with '-' or '+', the string ends with the next
409 whitespace or comma. */
410 if (*start
== '-' || *start
== '+')
412 while (*inp
[0] != '\0' && *inp
[0] != ',' && !isspace (*inp
[0]))
417 /* Handle numbers first, stopping at the next whitespace or ','. */
418 while (isdigit (*inp
[0]))
420 if (*inp
[0] == '\0' || isspace (*inp
[0]) || *inp
[0] == ',')
421 return gdb::unique_xmalloc_ptr
<char> (savestring (start
,
424 /* Otherwise stop at the next occurrence of whitespace, '\0',
429 && !(isspace ((*inp
)[0])
430 || linespec_lexer_lex_keyword (&(*inp
)[1])))
432 /* Special case: C++ operator,. */
433 if (language
->la_language
== language_cplus
434 && startswith (*inp
, CP_OPERATOR_STR
))
435 (*inp
) += CP_OPERATOR_LEN
;
440 if (*inp
- start
> 0)
441 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
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. */
451 is_cp_operator (const char *start
, const char *comma
)
454 && (comma
- start
) >= CP_OPERATOR_LEN
)
456 const char *p
= comma
;
458 while (p
> start
&& isspace (p
[-1]))
460 if (p
- start
>= CP_OPERATOR_LEN
)
462 p
-= CP_OPERATOR_LEN
;
463 if (strncmp (p
, CP_OPERATOR_STR
, CP_OPERATOR_LEN
) == 0
465 || !(isalnum (p
[-1]) || p
[-1] == '_')))
474 /* When scanning the input string looking for the next explicit
475 location spec option/delimiter, we jump to the next option by looking
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. */
489 skip_op_false_positives (const char *start
, const char *found
)
491 while (found
!= NULL
&& is_cp_operator (start
, found
))
493 if (found
[0] == '-' && found
[1] == '-')
497 found
= find_toplevel_char (start
, *found
);
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. */
508 first_of (const char *first
, const char *new_tok
)
512 else if (new_tok
!= NULL
&& new_tok
< first
)
518 /* A lexer for functions in explicit location specs. This function will
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
523 static gdb::unique_xmalloc_ptr
<char>
524 explicit_location_spec_lex_one_function
526 const struct language_defn
*language
,
527 explicit_completion_info
*completion_info
)
529 const char *start
= *inp
;
534 /* If quoted, skip to the ending quote. */
535 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
537 char quote_char
= *start
;
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
)))
544 if (completion_info
!= NULL
)
545 completion_info
->quoted_arg_start
= start
;
547 const char *end
= find_toplevel_char (start
+ 1, quote_char
);
551 if (completion_info
== NULL
)
552 error (_("Unmatched quote, %s."), start
);
554 end
= start
+ strlen (start
);
556 char *saved
= savestring (start
+ 1, *inp
- start
- 1);
557 return gdb::unique_xmalloc_ptr
<char> (saved
);
560 if (completion_info
!= NULL
)
561 completion_info
->quoted_arg_end
= end
;
563 char *saved
= savestring (start
+ 1, *inp
- start
- 2);
564 return gdb::unique_xmalloc_ptr
<char> (saved
);
568 const char *comma
= find_toplevel_char (start
, ',');
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
578 ? find_toplevel_char (start
+ 1, '-')
579 : find_toplevel_char (start
, '-'));
581 /* Check for C++ "operator," and "operator-". */
582 comma
= skip_op_false_positives (start
, comma
);
583 hyphen
= skip_op_false_positives (start
, hyphen
);
585 /* Pick the one that appears first. */
586 const char *end
= first_of (hyphen
, comma
);
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
)
594 ws
= find_toplevel_char (s
, ' ');
597 end
= first_of (end
, ws
+ 1);
599 /* If we don't have any terminator, then take the whole string. */
601 end
= start
+ strlen (start
);
603 /* Trim whitespace at the end. */
604 while (end
> start
&& end
[-1] == ' ')
609 if (*inp
- start
> 0)
610 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
615 /* See description in location.h. */
618 string_to_explicit_location_spec (const char **argp
,
619 const struct language_defn
*language
,
620 explicit_completion_info
*completion_info
)
622 /* It is assumed that input beginning with '-' and a non-digit
623 character is an explicit location. "-p" is reserved, though,
624 for probe locations. */
628 || !isalpha ((*argp
)[1])
629 || ((*argp
)[0] == '-' && (*argp
)[1] == 'p'))
632 std::unique_ptr
<explicit_location_spec
> locspec
633 (new explicit_location_spec ());
635 /* Process option/argument pairs. dprintf_command
636 requires that processing stop on ','. */
637 while ((*argp
)[0] != '\0' && (*argp
)[0] != ',')
642 /* Clear these on each iteration, since they should be filled
643 with info about the last option. */
644 if (completion_info
!= NULL
)
646 completion_info
->quoted_arg_start
= NULL
;
647 completion_info
->quoted_arg_end
= NULL
;
650 /* If *ARGP starts with a keyword, stop processing
652 if (linespec_lexer_lex_keyword (*argp
) != NULL
)
655 /* Mark the start of the string in case we need to rewind. */
658 if (completion_info
!= NULL
)
659 completion_info
->last_option
= start
;
661 /* Get the option string. */
662 gdb::unique_xmalloc_ptr
<char> opt
663 = explicit_location_spec_lex_one (argp
, language
, NULL
);
665 /* Use the length of the option to allow abbreviations. */
666 len
= strlen (opt
.get ());
668 /* Get the argument string. */
669 *argp
= skip_spaces (*argp
);
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
677 bool have_oarg
= false;
679 /* True if the option needs an argument. */
680 bool need_oarg
= false;
682 /* Convenience to consistently set both OARG/HAVE_OARG from
684 auto set_oarg
= [&] (gdb::unique_xmalloc_ptr
<char> arg
)
686 if (completion_info
!= NULL
)
688 /* We do this here because the set of options that take
689 arguments matches the set of explicit location
691 completion_info
->saw_explicit_location_spec_option
= true;
693 oarg
= std::move (arg
);
694 have_oarg
= oarg
!= NULL
;
698 if (strncmp (opt
.get (), "-source", len
) == 0)
700 set_oarg (explicit_location_spec_lex_one (argp
, language
,
702 locspec
->source_filename
= std::move (oarg
);
704 else if (strncmp (opt
.get (), "-function", len
) == 0)
706 set_oarg (explicit_location_spec_lex_one_function (argp
, language
,
708 locspec
->function_name
= std::move (oarg
);
710 else if (strncmp (opt
.get (), "-qualified", len
) == 0)
712 locspec
->func_name_match_type
= symbol_name_match_type::FULL
;
714 else if (strncmp (opt
.get (), "-line", len
) == 0)
716 set_oarg (explicit_location_spec_lex_one (argp
, language
, NULL
));
717 *argp
= skip_spaces (*argp
);
720 locspec
->line_offset
= linespec_parse_line_offset (oarg
.get ());
724 else if (strncmp (opt
.get (), "-label", len
) == 0)
726 set_oarg (explicit_location_spec_lex_one (argp
, language
,
728 locspec
->label_name
= std::move (oarg
);
730 /* Only emit an "invalid argument" error for options
731 that look like option strings. */
732 else if (opt
.get ()[0] == '-' && !isdigit (opt
.get ()[1]))
734 if (completion_info
== NULL
)
735 error (_("invalid explicit location argument, \"%s\""), opt
.get ());
739 /* End of the explicit location specification.
740 Stop parsing and return whatever explicit location was
746 *argp
= skip_spaces (*argp
);
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
752 if (need_oarg
&& !have_oarg
&& completion_info
== NULL
)
753 error (_("missing argument for \"%s\""), opt
.get ());
756 /* One special error check: If a source filename was given
757 without offset, function, or label, issue an error. */
758 if (locspec
->source_filename
!= NULL
759 && locspec
->function_name
== NULL
760 && locspec
->label_name
== NULL
761 && (locspec
->line_offset
.sign
== LINE_OFFSET_UNKNOWN
)
762 && completion_info
== NULL
)
764 error (_("Source filename requires function, label, or "
768 return location_spec_up (locspec
.release ());
771 /* See description in location.h. */
774 string_to_location_spec_basic (const char **stringp
,
775 const struct language_defn
*language
,
776 symbol_name_match_type match_type
)
778 location_spec_up locspec
;
781 /* Try the input as a probe spec. */
783 if (cs
!= NULL
&& probe_linespec_to_static_ops (&cs
) != NULL
)
785 locspec
= new_probe_location_spec (*stringp
);
786 *stringp
+= strlen (*stringp
);
790 /* Try an address location spec. */
791 if (*stringp
!= NULL
&& **stringp
== '*')
793 const char *arg
, *orig
;
796 orig
= arg
= *stringp
;
797 addr
= linespec_expression_to_pc (&arg
);
798 locspec
= new_address_location_spec (addr
, orig
, arg
- orig
);
799 *stringp
+= arg
- orig
;
803 /* Everything else is a linespec. */
804 locspec
= new_linespec_location_spec (stringp
, match_type
);
811 /* See description in location.h. */
814 string_to_location_spec (const char **stringp
,
815 const struct language_defn
*language
,
816 symbol_name_match_type match_type
)
818 const char *arg
, *orig
;
820 /* Try an explicit location spec. */
821 orig
= arg
= *stringp
;
822 location_spec_up locspec
823 = string_to_explicit_location_spec (&arg
, language
, NULL
);
824 if (locspec
!= nullptr)
826 /* It was a valid explicit location. Advance STRINGP to
828 *stringp
+= arg
- orig
;
830 /* If the user really specified a location spec, then we're
832 if (!locspec
->empty_p ())
835 /* Otherwise, the user _only_ specified optional flags like
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
840 explicit_location_spec
*xloc
841 = gdb::checked_static_cast
<explicit_location_spec
*> (locspec
.get ());
842 match_type
= xloc
->func_name_match_type
;
845 /* Everything else is a "basic" linespec, address, or probe location
847 return string_to_location_spec_basic (stringp
, language
, match_type
);