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. */
209 enum location_spec_type
210 location_spec_type (const location_spec
*locspec
)
212 return locspec
->type
;
215 /* See description in location.h. */
218 new_linespec_location_spec (const char **linespec
,
219 symbol_name_match_type match_type
)
221 return location_spec_up (new linespec_location_spec (linespec
,
225 /* See description in location.h. */
227 const linespec_location_spec
*
228 as_linespec_location_spec (const location_spec
*locspec
)
230 gdb_assert (locspec
->type
== LINESPEC_LOCATION_SPEC
);
231 return static_cast<const linespec_location_spec
*> (locspec
);
234 /* See description in location.h. */
237 new_address_location_spec (CORE_ADDR addr
, const char *addr_string
,
240 return location_spec_up (new address_location_spec (addr
, addr_string
,
244 /* See description in location.h. */
246 const address_location_spec
*
247 as_address_location_spec (const location_spec
*locspec
)
249 gdb_assert (locspec
->type
== ADDRESS_LOCATION_SPEC
);
250 return static_cast<const address_location_spec
*> (locspec
);
253 /* See description in location.h. */
256 new_probe_location_spec (std::string
&&probe
)
258 return location_spec_up (new probe_location_spec (std::move (probe
)));
261 /* See description in location.h. */
263 const probe_location_spec
*
264 as_probe_location_spec (const location_spec
*locspec
)
266 gdb_assert (locspec
->type
== PROBE_LOCATION_SPEC
);
267 return static_cast<const probe_location_spec
*> (locspec
);
270 /* See description in location.h. */
272 const explicit_location_spec
*
273 as_explicit_location_spec (const location_spec
*locspec
)
275 gdb_assert (locspec
->type
== EXPLICIT_LOCATION_SPEC
);
276 return static_cast<const explicit_location_spec
*> (locspec
);
279 /* See description in location.h. */
281 explicit_location_spec
*
282 as_explicit_location_spec (location_spec
*locspec
)
284 gdb_assert (locspec
->type
== EXPLICIT_LOCATION_SPEC
);
285 return static_cast<explicit_location_spec
*> (locspec
);
288 /* Return a string representation of the explicit location spec in
291 AS_LINESPEC is true if this string should be a linespec. Otherwise
292 it will be output in explicit form. */
295 explicit_to_string_internal (bool as_linespec
,
296 const explicit_location_spec
*explicit_loc
)
298 bool need_space
= false;
299 char space
= as_linespec
? ':' : ' ';
302 if (explicit_loc
->source_filename
!= NULL
)
305 buf
.puts ("-source ");
306 buf
.puts (explicit_loc
->source_filename
);
310 if (explicit_loc
->function_name
!= NULL
)
314 if (explicit_loc
->func_name_match_type
== symbol_name_match_type::FULL
)
315 buf
.puts ("-qualified ");
317 buf
.puts ("-function ");
318 buf
.puts (explicit_loc
->function_name
);
322 if (explicit_loc
->label_name
!= NULL
)
327 buf
.puts ("-label ");
328 buf
.puts (explicit_loc
->label_name
);
332 if (explicit_loc
->line_offset
.sign
!= LINE_OFFSET_UNKNOWN
)
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
);
345 return buf
.release ();
348 /* See description in location.h. */
351 explicit_location_spec::to_linespec () const
353 return explicit_to_string_internal (true, this);
356 /* See description in location.h. */
359 copy_location_spec (const location_spec
*src
)
361 return src
->clone ();
364 /* See description in location.h. */
367 location_spec_to_string (struct location_spec
*locspec
)
369 return locspec
->to_string ();
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
377 find_end_quote (const char *s
, char end_quote_char
)
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';
384 for (const char *scan
= s
; *scan
!= '\0'; scan
++)
386 if (nested_quote_char
!= '\0')
388 if (*scan
== nested_quote_char
)
389 nested_quote_char
= '\0';
390 else if (scan
[0] == '\\' && *(scan
+ 1) != '\0')
393 else if (*scan
== end_quote_char
&& nested_quote_char
== '\0')
395 else if (*scan
== '"' || *scan
== '\'')
396 nested_quote_char
= *scan
;
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. */
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
)
411 const char *start
= *inp
;
416 /* If quoted, skip to the ending quote. */
417 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
419 if (completion_info
!= NULL
)
420 completion_info
->quoted_arg_start
= start
;
422 const char *end
= find_end_quote (start
+ 1, *start
);
426 if (completion_info
== NULL
)
427 error (_("Unmatched quote, %s."), start
);
429 end
= start
+ strlen (start
);
431 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
435 if (completion_info
!= NULL
)
436 completion_info
->quoted_arg_end
= end
;
438 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
442 /* If the input starts with '-' or '+', the string ends with the next
443 whitespace or comma. */
444 if (*start
== '-' || *start
== '+')
446 while (*inp
[0] != '\0' && *inp
[0] != ',' && !isspace (*inp
[0]))
451 /* Handle numbers first, stopping at the next whitespace or ','. */
452 while (isdigit (*inp
[0]))
454 if (*inp
[0] == '\0' || isspace (*inp
[0]) || *inp
[0] == ',')
455 return gdb::unique_xmalloc_ptr
<char> (savestring (start
,
458 /* Otherwise stop at the next occurrence of whitespace, '\0',
463 && !(isspace ((*inp
)[0])
464 || linespec_lexer_lex_keyword (&(*inp
)[1])))
466 /* Special case: C++ operator,. */
467 if (language
->la_language
== language_cplus
468 && startswith (*inp
, CP_OPERATOR_STR
))
469 (*inp
) += CP_OPERATOR_LEN
;
474 if (*inp
- start
> 0)
475 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
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. */
485 is_cp_operator (const char *start
, const char *comma
)
488 && (comma
- start
) >= CP_OPERATOR_LEN
)
490 const char *p
= comma
;
492 while (p
> start
&& isspace (p
[-1]))
494 if (p
- start
>= CP_OPERATOR_LEN
)
496 p
-= CP_OPERATOR_LEN
;
497 if (strncmp (p
, CP_OPERATOR_STR
, CP_OPERATOR_LEN
) == 0
499 || !(isalnum (p
[-1]) || p
[-1] == '_')))
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. */
523 skip_op_false_positives (const char *start
, const char *found
)
525 while (found
!= NULL
&& is_cp_operator (start
, found
))
527 if (found
[0] == '-' && found
[1] == '-')
531 found
= find_toplevel_char (start
, *found
);
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. */
542 first_of (const char *first
, const char *new_tok
)
546 else if (new_tok
!= NULL
&& new_tok
< first
)
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
557 static gdb::unique_xmalloc_ptr
<char>
558 explicit_location_spec_lex_one_function
560 const struct language_defn
*language
,
561 explicit_completion_info
*completion_info
)
563 const char *start
= *inp
;
568 /* If quoted, skip to the ending quote. */
569 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
571 char quote_char
= *start
;
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
)))
578 if (completion_info
!= NULL
)
579 completion_info
->quoted_arg_start
= start
;
581 const char *end
= find_toplevel_char (start
+ 1, quote_char
);
585 if (completion_info
== NULL
)
586 error (_("Unmatched quote, %s."), start
);
588 end
= start
+ strlen (start
);
590 char *saved
= savestring (start
+ 1, *inp
- start
- 1);
591 return gdb::unique_xmalloc_ptr
<char> (saved
);
594 if (completion_info
!= NULL
)
595 completion_info
->quoted_arg_end
= end
;
597 char *saved
= savestring (start
+ 1, *inp
- start
- 2);
598 return gdb::unique_xmalloc_ptr
<char> (saved
);
602 const char *comma
= find_toplevel_char (start
, ',');
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
612 ? find_toplevel_char (start
+ 1, '-')
613 : find_toplevel_char (start
, '-'));
615 /* Check for C++ "operator," and "operator-". */
616 comma
= skip_op_false_positives (start
, comma
);
617 hyphen
= skip_op_false_positives (start
, hyphen
);
619 /* Pick the one that appears first. */
620 const char *end
= first_of (hyphen
, comma
);
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
)
628 ws
= find_toplevel_char (s
, ' ');
631 end
= first_of (end
, ws
+ 1);
633 /* If we don't have any terminator, then take the whole string. */
635 end
= start
+ strlen (start
);
637 /* Trim whitespace at the end. */
638 while (end
> start
&& end
[-1] == ' ')
643 if (*inp
- start
> 0)
644 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
649 /* See description in location.h. */
652 string_to_explicit_location_spec (const char **argp
,
653 const struct language_defn
*language
,
654 explicit_completion_info
*completion_info
)
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. */
662 || !isalpha ((*argp
)[1])
663 || ((*argp
)[0] == '-' && (*argp
)[1] == 'p'))
666 std::unique_ptr
<explicit_location_spec
> locspec
667 (new explicit_location_spec ());
669 /* Process option/argument pairs. dprintf_command
670 requires that processing stop on ','. */
671 while ((*argp
)[0] != '\0' && (*argp
)[0] != ',')
676 /* Clear these on each iteration, since they should be filled
677 with info about the last option. */
678 if (completion_info
!= NULL
)
680 completion_info
->quoted_arg_start
= NULL
;
681 completion_info
->quoted_arg_end
= NULL
;
684 /* If *ARGP starts with a keyword, stop processing
686 if (linespec_lexer_lex_keyword (*argp
) != NULL
)
689 /* Mark the start of the string in case we need to rewind. */
692 if (completion_info
!= NULL
)
693 completion_info
->last_option
= start
;
695 /* Get the option string. */
696 gdb::unique_xmalloc_ptr
<char> opt
697 = explicit_location_spec_lex_one (argp
, language
, NULL
);
699 /* Use the length of the option to allow abbreviations. */
700 len
= strlen (opt
.get ());
702 /* Get the argument string. */
703 *argp
= skip_spaces (*argp
);
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
711 bool have_oarg
= false;
713 /* True if the option needs an argument. */
714 bool need_oarg
= false;
716 /* Convenience to consistently set both OARG/HAVE_OARG from
718 auto set_oarg
= [&] (gdb::unique_xmalloc_ptr
<char> arg
)
720 if (completion_info
!= NULL
)
722 /* We do this here because the set of options that take
723 arguments matches the set of explicit location
725 completion_info
->saw_explicit_location_spec_option
= true;
727 oarg
= std::move (arg
);
728 have_oarg
= oarg
!= NULL
;
732 if (strncmp (opt
.get (), "-source", len
) == 0)
734 set_oarg (explicit_location_spec_lex_one (argp
, language
,
736 locspec
->source_filename
= oarg
.release ();
738 else if (strncmp (opt
.get (), "-function", len
) == 0)
740 set_oarg (explicit_location_spec_lex_one_function (argp
, language
,
742 locspec
->function_name
= oarg
.release ();
744 else if (strncmp (opt
.get (), "-qualified", len
) == 0)
746 locspec
->func_name_match_type
= symbol_name_match_type::FULL
;
748 else if (strncmp (opt
.get (), "-line", len
) == 0)
750 set_oarg (explicit_location_spec_lex_one (argp
, language
, NULL
));
751 *argp
= skip_spaces (*argp
);
754 locspec
->line_offset
= linespec_parse_line_offset (oarg
.get ());
758 else if (strncmp (opt
.get (), "-label", len
) == 0)
760 set_oarg (explicit_location_spec_lex_one (argp
, language
,
762 locspec
->label_name
= oarg
.release ();
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]))
768 if (completion_info
== NULL
)
769 error (_("invalid explicit location argument, \"%s\""), opt
.get ());
773 /* End of the explicit location specification.
774 Stop parsing and return whatever explicit location was
780 *argp
= skip_spaces (*argp
);
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
786 if (need_oarg
&& !have_oarg
&& completion_info
== NULL
)
787 error (_("missing argument for \"%s\""), opt
.get ());
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
)
798 error (_("Source filename requires function, label, or "
802 return location_spec_up (locspec
.release ());
805 /* See description in location.h. */
808 string_to_location_spec_basic (const char **stringp
,
809 const struct language_defn
*language
,
810 symbol_name_match_type match_type
)
812 location_spec_up locspec
;
815 /* Try the input as a probe spec. */
817 if (cs
!= NULL
&& probe_linespec_to_static_ops (&cs
) != NULL
)
819 locspec
= new_probe_location_spec (*stringp
);
820 *stringp
+= strlen (*stringp
);
824 /* Try an address location spec. */
825 if (*stringp
!= NULL
&& **stringp
== '*')
827 const char *arg
, *orig
;
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
;
837 /* Everything else is a linespec. */
838 locspec
= new_linespec_location_spec (stringp
, match_type
);
845 /* See description in location.h. */
848 string_to_location_spec (const char **stringp
,
849 const struct language_defn
*language
,
850 symbol_name_match_type match_type
)
852 const char *arg
, *orig
;
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)
860 /* It was a valid explicit location. Advance STRINGP to
862 *stringp
+= arg
- orig
;
864 /* If the user really specified a location spec, then we're
866 if (!location_spec_empty_p (locspec
.get ()))
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
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
;
880 /* Everything else is a "basic" linespec, address, or probe location
882 return string_to_location_spec_basic (stringp
, language
, match_type
);
885 /* See description in location.h. */
888 location_spec_empty_p (const location_spec
*locspec
)
890 return locspec
->empty_p ();
893 /* See description in location.h. */
896 set_location_spec_string (struct location_spec
*locspec
,
897 std::string
&&string
)
899 locspec
->as_string
= std::move (string
);