1 /* Data structures and API for location specs in GDB.
2 Copyright (C) 2013-2022 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"
25 #include "cli/cli-utils.h"
27 #include "cp-support.h"
33 explicit_to_string_internal (bool as_linespec
,
34 const explicit_location_spec
*explicit_loc
);
36 /* Return a xstrdup of STR if not NULL, otherwise return NULL. */
39 maybe_xstrdup (const char *str
)
41 return (str
!= nullptr ? xstrdup (str
) : nullptr);
44 probe_location_spec::probe_location_spec (std::string
&&probe
)
45 : location_spec (PROBE_LOCATION_SPEC
, std::move (probe
))
50 probe_location_spec::clone () const
52 return location_spec_up (new probe_location_spec (*this));
56 probe_location_spec::empty_p () const
61 std::string
probe_location_spec::compute_string () const
63 return std::move (as_string
);
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_
)
72 if (*linespec
!= NULL
)
75 const char *orig
= *linespec
;
77 linespec_lex_to_end (linespec
);
78 p
= remove_trailing_whitespace (orig
, *linespec
);
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. */
85 spec_string
= savestring (orig
, p
- orig
);
89 linespec_location_spec::~linespec_location_spec ()
95 linespec_location_spec::clone () const
97 return location_spec_up (new linespec_location_spec (*this));
101 linespec_location_spec::empty_p () const
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
))
115 linespec_location_spec::compute_string () const
117 if (spec_string
!= nullptr)
119 if (match_type
== symbol_name_match_type::FULL
)
120 return std::string ("-qualified ") + spec_string
;
127 address_location_spec::address_location_spec (CORE_ADDR addr
,
128 const char *addr_string
,
130 : location_spec (ADDRESS_LOCATION_SPEC
),
133 if (addr_string
!= nullptr)
134 as_string
= std::string (addr_string
, addr_string_len
);
138 address_location_spec::clone () const
140 return location_spec_up (new address_location_spec (*this));
144 address_location_spec::empty_p () const
149 address_location_spec::address_location_spec
150 (const address_location_spec
&other
)
151 : location_spec (other
),
152 address (other
.address
)
157 address_location_spec::compute_string () const
159 const char *addr_string
= core_addr_to_string (address
);
160 return std::string ("*") + addr_string
;
163 explicit_location_spec::explicit_location_spec ()
164 : location_spec (EXPLICIT_LOCATION_SPEC
)
168 explicit_location_spec::~explicit_location_spec ()
170 xfree (source_filename
);
171 xfree (function_name
);
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
)
187 explicit_location_spec::clone () const
189 return location_spec_up (new explicit_location_spec (*this));
193 explicit_location_spec::empty_p () const
195 return (source_filename
== nullptr
196 && function_name
== nullptr
197 && label_name
== nullptr
198 && line_offset
.sign
== LINE_OFFSET_UNKNOWN
);
202 explicit_location_spec::compute_string () const
204 return explicit_to_string_internal (false, this);
207 /* See description in location.h. */
210 new_linespec_location_spec (const char **linespec
,
211 symbol_name_match_type match_type
)
213 return location_spec_up (new linespec_location_spec (linespec
,
217 /* See description in location.h. */
219 const linespec_location_spec
*
220 as_linespec_location_spec (const location_spec
*locspec
)
222 gdb_assert (locspec
->type () == LINESPEC_LOCATION_SPEC
);
223 return static_cast<const linespec_location_spec
*> (locspec
);
226 /* See description in location.h. */
229 new_address_location_spec (CORE_ADDR addr
, const char *addr_string
,
232 return location_spec_up (new address_location_spec (addr
, addr_string
,
236 /* See description in location.h. */
238 const address_location_spec
*
239 as_address_location_spec (const location_spec
*locspec
)
241 gdb_assert (locspec
->type () == ADDRESS_LOCATION_SPEC
);
242 return static_cast<const address_location_spec
*> (locspec
);
245 /* See description in location.h. */
248 new_probe_location_spec (std::string
&&probe
)
250 return location_spec_up (new probe_location_spec (std::move (probe
)));
253 /* See description in location.h. */
255 const probe_location_spec
*
256 as_probe_location_spec (const location_spec
*locspec
)
258 gdb_assert (locspec
->type () == PROBE_LOCATION_SPEC
);
259 return static_cast<const probe_location_spec
*> (locspec
);
262 /* See description in location.h. */
264 const explicit_location_spec
*
265 as_explicit_location_spec (const location_spec
*locspec
)
267 gdb_assert (locspec
->type () == EXPLICIT_LOCATION_SPEC
);
268 return static_cast<const explicit_location_spec
*> (locspec
);
271 /* See description in location.h. */
273 explicit_location_spec
*
274 as_explicit_location_spec (location_spec
*locspec
)
276 gdb_assert (locspec
->type () == EXPLICIT_LOCATION_SPEC
);
277 return static_cast<explicit_location_spec
*> (locspec
);
280 /* Return a string representation of the explicit location spec in
283 AS_LINESPEC is true if this string should be a linespec. Otherwise
284 it will be output in explicit form. */
287 explicit_to_string_internal (bool as_linespec
,
288 const explicit_location_spec
*explicit_loc
)
290 bool need_space
= false;
291 char space
= as_linespec
? ':' : ' ';
294 if (explicit_loc
->source_filename
!= NULL
)
297 buf
.puts ("-source ");
298 buf
.puts (explicit_loc
->source_filename
);
302 if (explicit_loc
->function_name
!= NULL
)
306 if (explicit_loc
->func_name_match_type
== symbol_name_match_type::FULL
)
307 buf
.puts ("-qualified ");
309 buf
.puts ("-function ");
310 buf
.puts (explicit_loc
->function_name
);
314 if (explicit_loc
->label_name
!= NULL
)
319 buf
.puts ("-label ");
320 buf
.puts (explicit_loc
->label_name
);
324 if (explicit_loc
->line_offset
.sign
!= LINE_OFFSET_UNKNOWN
)
331 (explicit_loc
->line_offset
.sign
== LINE_OFFSET_NONE
? ""
332 : (explicit_loc
->line_offset
.sign
333 == LINE_OFFSET_PLUS
? "+" : "-")),
334 explicit_loc
->line_offset
.offset
);
337 return buf
.release ();
340 /* See description in location.h. */
343 explicit_location_spec::to_linespec () const
345 return explicit_to_string_internal (true, this);
348 /* See description in location.h. */
351 location_spec_to_string (struct location_spec
*locspec
)
353 return locspec
->to_string ();
356 /* Find an instance of the quote character C in the string S that is
357 outside of all single- and double-quoted strings (i.e., any quoting
361 find_end_quote (const char *s
, char end_quote_char
)
363 /* zero if we're not in quotes;
364 '"' if we're in a double-quoted string;
365 '\'' if we're in a single-quoted string. */
366 char nested_quote_char
= '\0';
368 for (const char *scan
= s
; *scan
!= '\0'; scan
++)
370 if (nested_quote_char
!= '\0')
372 if (*scan
== nested_quote_char
)
373 nested_quote_char
= '\0';
374 else if (scan
[0] == '\\' && *(scan
+ 1) != '\0')
377 else if (*scan
== end_quote_char
&& nested_quote_char
== '\0')
379 else if (*scan
== '"' || *scan
== '\'')
380 nested_quote_char
= *scan
;
386 /* A lexer for explicit location specs. This function will advance
387 INP past any strings that it lexes. Returns a malloc'd copy of the
388 lexed string or NULL if no lexing was done. */
390 static gdb::unique_xmalloc_ptr
<char>
391 explicit_location_spec_lex_one (const char **inp
,
392 const struct language_defn
*language
,
393 explicit_completion_info
*completion_info
)
395 const char *start
= *inp
;
400 /* If quoted, skip to the ending quote. */
401 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
403 if (completion_info
!= NULL
)
404 completion_info
->quoted_arg_start
= start
;
406 const char *end
= find_end_quote (start
+ 1, *start
);
410 if (completion_info
== NULL
)
411 error (_("Unmatched quote, %s."), start
);
413 end
= start
+ strlen (start
);
415 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
419 if (completion_info
!= NULL
)
420 completion_info
->quoted_arg_end
= end
;
422 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
426 /* If the input starts with '-' or '+', the string ends with the next
427 whitespace or comma. */
428 if (*start
== '-' || *start
== '+')
430 while (*inp
[0] != '\0' && *inp
[0] != ',' && !isspace (*inp
[0]))
435 /* Handle numbers first, stopping at the next whitespace or ','. */
436 while (isdigit (*inp
[0]))
438 if (*inp
[0] == '\0' || isspace (*inp
[0]) || *inp
[0] == ',')
439 return gdb::unique_xmalloc_ptr
<char> (savestring (start
,
442 /* Otherwise stop at the next occurrence of whitespace, '\0',
447 && !(isspace ((*inp
)[0])
448 || linespec_lexer_lex_keyword (&(*inp
)[1])))
450 /* Special case: C++ operator,. */
451 if (language
->la_language
== language_cplus
452 && startswith (*inp
, CP_OPERATOR_STR
))
453 (*inp
) += CP_OPERATOR_LEN
;
458 if (*inp
- start
> 0)
459 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
464 /* Return true if COMMA points past "operator". START is the start of
465 the line that COMMAND points to, hence when reading backwards, we
466 must not read any character before START. */
469 is_cp_operator (const char *start
, const char *comma
)
472 && (comma
- start
) >= CP_OPERATOR_LEN
)
474 const char *p
= comma
;
476 while (p
> start
&& isspace (p
[-1]))
478 if (p
- start
>= CP_OPERATOR_LEN
)
480 p
-= CP_OPERATOR_LEN
;
481 if (strncmp (p
, CP_OPERATOR_STR
, CP_OPERATOR_LEN
) == 0
483 || !(isalnum (p
[-1]) || p
[-1] == '_')))
492 /* When scanning the input string looking for the next explicit
493 location spec option/delimiter, we jump to the next option by looking
494 for ",", and "-". Such a character can also appear in C++ symbols
495 like "operator," and "operator-". So when we find such a
496 character, we call this function to check if we found such a
497 symbol, meaning we had a false positive for an option string. In
498 that case, we keep looking for the next delimiter, until we find
499 one that is not a false positive, or we reach end of string. FOUND
500 is the character that scanning found (either '-' or ','), and START
501 is the start of the line that FOUND points to, hence when reading
502 backwards, we must not read any character before START. Returns a
503 pointer to the next non-false-positive delimiter character, or NULL
504 if none was found. */
507 skip_op_false_positives (const char *start
, const char *found
)
509 while (found
!= NULL
&& is_cp_operator (start
, found
))
511 if (found
[0] == '-' && found
[1] == '-')
515 found
= find_toplevel_char (start
, *found
);
521 /* Assuming both FIRST and NEW_TOK point into the same string, return
522 the pointer that is closer to the start of the string. If FIRST is
523 NULL, returns NEW_TOK. If NEW_TOK is NULL, returns FIRST. */
526 first_of (const char *first
, const char *new_tok
)
530 else if (new_tok
!= NULL
&& new_tok
< first
)
536 /* A lexer for functions in explicit location specs. This function will
537 advance INP past a function until the next option, or until end of
538 string. Returns a malloc'd copy of the lexed string or NULL if no
541 static gdb::unique_xmalloc_ptr
<char>
542 explicit_location_spec_lex_one_function
544 const struct language_defn
*language
,
545 explicit_completion_info
*completion_info
)
547 const char *start
= *inp
;
552 /* If quoted, skip to the ending quote. */
553 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
555 char quote_char
= *start
;
557 /* If the input is not an Ada operator, skip to the matching
558 closing quote and return the string. */
559 if (!(language
->la_language
== language_ada
560 && quote_char
== '\"' && is_ada_operator (start
)))
562 if (completion_info
!= NULL
)
563 completion_info
->quoted_arg_start
= start
;
565 const char *end
= find_toplevel_char (start
+ 1, quote_char
);
569 if (completion_info
== NULL
)
570 error (_("Unmatched quote, %s."), start
);
572 end
= start
+ strlen (start
);
574 char *saved
= savestring (start
+ 1, *inp
- start
- 1);
575 return gdb::unique_xmalloc_ptr
<char> (saved
);
578 if (completion_info
!= NULL
)
579 completion_info
->quoted_arg_end
= end
;
581 char *saved
= savestring (start
+ 1, *inp
- start
- 2);
582 return gdb::unique_xmalloc_ptr
<char> (saved
);
586 const char *comma
= find_toplevel_char (start
, ',');
588 /* If we have "-function -myfunction", or perhaps better example,
589 "-function -[BasicClass doIt]" (objc selector), treat
590 "-myfunction" as the function name. I.e., skip the first char if
591 it is an hyphen. Don't skip the first char always, because we
592 may have C++ "operator<", and find_toplevel_char needs to see the
596 ? find_toplevel_char (start
+ 1, '-')
597 : find_toplevel_char (start
, '-'));
599 /* Check for C++ "operator," and "operator-". */
600 comma
= skip_op_false_positives (start
, comma
);
601 hyphen
= skip_op_false_positives (start
, hyphen
);
603 /* Pick the one that appears first. */
604 const char *end
= first_of (hyphen
, comma
);
606 /* See if a linespec keyword appears first. */
607 const char *s
= start
;
608 const char *ws
= find_toplevel_char (start
, ' ');
609 while (ws
!= NULL
&& linespec_lexer_lex_keyword (ws
+ 1) == NULL
)
612 ws
= find_toplevel_char (s
, ' ');
615 end
= first_of (end
, ws
+ 1);
617 /* If we don't have any terminator, then take the whole string. */
619 end
= start
+ strlen (start
);
621 /* Trim whitespace at the end. */
622 while (end
> start
&& end
[-1] == ' ')
627 if (*inp
- start
> 0)
628 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
633 /* See description in location.h. */
636 string_to_explicit_location_spec (const char **argp
,
637 const struct language_defn
*language
,
638 explicit_completion_info
*completion_info
)
640 /* It is assumed that input beginning with '-' and a non-digit
641 character is an explicit location. "-p" is reserved, though,
642 for probe locations. */
646 || !isalpha ((*argp
)[1])
647 || ((*argp
)[0] == '-' && (*argp
)[1] == 'p'))
650 std::unique_ptr
<explicit_location_spec
> locspec
651 (new explicit_location_spec ());
653 /* Process option/argument pairs. dprintf_command
654 requires that processing stop on ','. */
655 while ((*argp
)[0] != '\0' && (*argp
)[0] != ',')
660 /* Clear these on each iteration, since they should be filled
661 with info about the last option. */
662 if (completion_info
!= NULL
)
664 completion_info
->quoted_arg_start
= NULL
;
665 completion_info
->quoted_arg_end
= NULL
;
668 /* If *ARGP starts with a keyword, stop processing
670 if (linespec_lexer_lex_keyword (*argp
) != NULL
)
673 /* Mark the start of the string in case we need to rewind. */
676 if (completion_info
!= NULL
)
677 completion_info
->last_option
= start
;
679 /* Get the option string. */
680 gdb::unique_xmalloc_ptr
<char> opt
681 = explicit_location_spec_lex_one (argp
, language
, NULL
);
683 /* Use the length of the option to allow abbreviations. */
684 len
= strlen (opt
.get ());
686 /* Get the argument string. */
687 *argp
= skip_spaces (*argp
);
689 /* All options have a required argument. Checking for this
690 required argument is deferred until later. */
691 gdb::unique_xmalloc_ptr
<char> oarg
;
692 /* True if we have an argument. This is required because we'll
693 move from OARG before checking whether we have an
695 bool have_oarg
= false;
697 /* True if the option needs an argument. */
698 bool need_oarg
= false;
700 /* Convenience to consistently set both OARG/HAVE_OARG from
702 auto set_oarg
= [&] (gdb::unique_xmalloc_ptr
<char> arg
)
704 if (completion_info
!= NULL
)
706 /* We do this here because the set of options that take
707 arguments matches the set of explicit location
709 completion_info
->saw_explicit_location_spec_option
= true;
711 oarg
= std::move (arg
);
712 have_oarg
= oarg
!= NULL
;
716 if (strncmp (opt
.get (), "-source", len
) == 0)
718 set_oarg (explicit_location_spec_lex_one (argp
, language
,
720 locspec
->source_filename
= oarg
.release ();
722 else if (strncmp (opt
.get (), "-function", len
) == 0)
724 set_oarg (explicit_location_spec_lex_one_function (argp
, language
,
726 locspec
->function_name
= oarg
.release ();
728 else if (strncmp (opt
.get (), "-qualified", len
) == 0)
730 locspec
->func_name_match_type
= symbol_name_match_type::FULL
;
732 else if (strncmp (opt
.get (), "-line", len
) == 0)
734 set_oarg (explicit_location_spec_lex_one (argp
, language
, NULL
));
735 *argp
= skip_spaces (*argp
);
738 locspec
->line_offset
= linespec_parse_line_offset (oarg
.get ());
742 else if (strncmp (opt
.get (), "-label", len
) == 0)
744 set_oarg (explicit_location_spec_lex_one (argp
, language
,
746 locspec
->label_name
= oarg
.release ();
748 /* Only emit an "invalid argument" error for options
749 that look like option strings. */
750 else if (opt
.get ()[0] == '-' && !isdigit (opt
.get ()[1]))
752 if (completion_info
== NULL
)
753 error (_("invalid explicit location argument, \"%s\""), opt
.get ());
757 /* End of the explicit location specification.
758 Stop parsing and return whatever explicit location was
764 *argp
= skip_spaces (*argp
);
766 /* It's a little lame to error after the fact, but in this
767 case, it provides a much better user experience to issue
768 the "invalid argument" error before any missing
770 if (need_oarg
&& !have_oarg
&& completion_info
== NULL
)
771 error (_("missing argument for \"%s\""), opt
.get ());
774 /* One special error check: If a source filename was given
775 without offset, function, or label, issue an error. */
776 if (locspec
->source_filename
!= NULL
777 && locspec
->function_name
== NULL
778 && locspec
->label_name
== NULL
779 && (locspec
->line_offset
.sign
== LINE_OFFSET_UNKNOWN
)
780 && completion_info
== NULL
)
782 error (_("Source filename requires function, label, or "
786 return location_spec_up (locspec
.release ());
789 /* See description in location.h. */
792 string_to_location_spec_basic (const char **stringp
,
793 const struct language_defn
*language
,
794 symbol_name_match_type match_type
)
796 location_spec_up locspec
;
799 /* Try the input as a probe spec. */
801 if (cs
!= NULL
&& probe_linespec_to_static_ops (&cs
) != NULL
)
803 locspec
= new_probe_location_spec (*stringp
);
804 *stringp
+= strlen (*stringp
);
808 /* Try an address location spec. */
809 if (*stringp
!= NULL
&& **stringp
== '*')
811 const char *arg
, *orig
;
814 orig
= arg
= *stringp
;
815 addr
= linespec_expression_to_pc (&arg
);
816 locspec
= new_address_location_spec (addr
, orig
, arg
- orig
);
817 *stringp
+= arg
- orig
;
821 /* Everything else is a linespec. */
822 locspec
= new_linespec_location_spec (stringp
, match_type
);
829 /* See description in location.h. */
832 string_to_location_spec (const char **stringp
,
833 const struct language_defn
*language
,
834 symbol_name_match_type match_type
)
836 const char *arg
, *orig
;
838 /* Try an explicit location spec. */
839 orig
= arg
= *stringp
;
840 location_spec_up locspec
841 = string_to_explicit_location_spec (&arg
, language
, NULL
);
842 if (locspec
!= nullptr)
844 /* It was a valid explicit location. Advance STRINGP to
846 *stringp
+= arg
- orig
;
848 /* If the user really specified a location spec, then we're
850 if (!locspec
->empty_p ())
853 /* Otherwise, the user _only_ specified optional flags like
854 "-qualified", otherwise string_to_explicit_location_spec
855 would have thrown an error. Save the flags for "basic"
856 linespec parsing below and discard the explicit location
858 explicit_location_spec
*xloc
859 = dynamic_cast<explicit_location_spec
*> (locspec
.get ());
860 gdb_assert (xloc
!= nullptr);
861 match_type
= xloc
->func_name_match_type
;
864 /* Everything else is a "basic" linespec, address, or probe location
866 return string_to_location_spec_basic (stringp
, language
, match_type
);
869 /* See description in location.h. */
872 set_location_spec_string (struct location_spec
*locspec
,
873 std::string
&&string
)
875 locspec
->as_string
= std::move (string
);