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"
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
= savestring (orig
, p
- orig
);
90 linespec_location_spec::~linespec_location_spec ()
96 linespec_location_spec::clone () const
98 return location_spec_up (new linespec_location_spec (*this));
102 linespec_location_spec::empty_p () const
107 linespec_location_spec::linespec_location_spec
108 (const linespec_location_spec
&other
)
109 : location_spec (other
),
110 match_type (other
.match_type
),
111 spec_string (maybe_xstrdup (other
.spec_string
))
116 linespec_location_spec::compute_string () const
118 if (spec_string
!= nullptr)
120 if (match_type
== symbol_name_match_type::FULL
)
121 return std::string ("-qualified ") + spec_string
;
128 address_location_spec::address_location_spec (CORE_ADDR addr
,
129 const char *addr_string
,
131 : location_spec (ADDRESS_LOCATION_SPEC
),
134 if (addr_string
!= nullptr)
135 m_as_string
= std::string (addr_string
, addr_string_len
);
139 address_location_spec::clone () const
141 return location_spec_up (new address_location_spec (*this));
145 address_location_spec::empty_p () const
150 address_location_spec::address_location_spec
151 (const address_location_spec
&other
)
152 : location_spec (other
),
153 address (other
.address
)
158 address_location_spec::compute_string () const
160 const char *addr_string
= core_addr_to_string (address
);
161 return std::string ("*") + addr_string
;
164 explicit_location_spec::explicit_location_spec ()
165 : location_spec (EXPLICIT_LOCATION_SPEC
)
169 explicit_location_spec::~explicit_location_spec ()
171 xfree (source_filename
);
172 xfree (function_name
);
176 explicit_location_spec::explicit_location_spec
177 (const explicit_location_spec
&other
)
178 : location_spec (other
),
179 source_filename (maybe_xstrdup (other
.source_filename
)),
180 function_name (maybe_xstrdup (other
.function_name
)),
181 func_name_match_type (other
.func_name_match_type
),
182 label_name (maybe_xstrdup (other
.label_name
)),
183 line_offset (other
.line_offset
)
188 explicit_location_spec::clone () const
190 return location_spec_up (new explicit_location_spec (*this));
194 explicit_location_spec::empty_p () const
196 return (source_filename
== nullptr
197 && function_name
== nullptr
198 && label_name
== nullptr
199 && line_offset
.sign
== LINE_OFFSET_UNKNOWN
);
203 explicit_location_spec::compute_string () const
205 return explicit_to_string_internal (false, this);
208 /* See description in location.h. */
211 new_linespec_location_spec (const char **linespec
,
212 symbol_name_match_type match_type
)
214 return location_spec_up (new linespec_location_spec (linespec
,
218 /* See description in location.h. */
220 const linespec_location_spec
*
221 as_linespec_location_spec (const location_spec
*locspec
)
223 gdb_assert (locspec
->type () == LINESPEC_LOCATION_SPEC
);
224 return static_cast<const linespec_location_spec
*> (locspec
);
227 /* See description in location.h. */
230 new_address_location_spec (CORE_ADDR addr
, const char *addr_string
,
233 return location_spec_up (new address_location_spec (addr
, addr_string
,
237 /* See description in location.h. */
239 const address_location_spec
*
240 as_address_location_spec (const location_spec
*locspec
)
242 gdb_assert (locspec
->type () == ADDRESS_LOCATION_SPEC
);
243 return static_cast<const address_location_spec
*> (locspec
);
246 /* See description in location.h. */
249 new_probe_location_spec (std::string
&&probe
)
251 return location_spec_up (new probe_location_spec (std::move (probe
)));
254 /* See description in location.h. */
256 const probe_location_spec
*
257 as_probe_location_spec (const location_spec
*locspec
)
259 gdb_assert (locspec
->type () == PROBE_LOCATION_SPEC
);
260 return static_cast<const probe_location_spec
*> (locspec
);
263 /* See description in location.h. */
265 const explicit_location_spec
*
266 as_explicit_location_spec (const location_spec
*locspec
)
268 gdb_assert (locspec
->type () == EXPLICIT_LOCATION_SPEC
);
269 return static_cast<const explicit_location_spec
*> (locspec
);
272 /* See description in location.h. */
274 explicit_location_spec
*
275 as_explicit_location_spec (location_spec
*locspec
)
277 gdb_assert (locspec
->type () == EXPLICIT_LOCATION_SPEC
);
278 return static_cast<explicit_location_spec
*> (locspec
);
281 /* Return a string representation of the explicit location spec in
284 AS_LINESPEC is true if this string should be a linespec. Otherwise
285 it will be output in explicit form. */
288 explicit_to_string_internal (bool as_linespec
,
289 const explicit_location_spec
*explicit_loc
)
291 bool need_space
= false;
292 char space
= as_linespec
? ':' : ' ';
295 if (explicit_loc
->source_filename
!= NULL
)
298 buf
.puts ("-source ");
299 buf
.puts (explicit_loc
->source_filename
);
303 if (explicit_loc
->function_name
!= NULL
)
307 if (explicit_loc
->func_name_match_type
== symbol_name_match_type::FULL
)
308 buf
.puts ("-qualified ");
310 buf
.puts ("-function ");
311 buf
.puts (explicit_loc
->function_name
);
315 if (explicit_loc
->label_name
!= NULL
)
320 buf
.puts ("-label ");
321 buf
.puts (explicit_loc
->label_name
);
325 if (explicit_loc
->line_offset
.sign
!= LINE_OFFSET_UNKNOWN
)
332 (explicit_loc
->line_offset
.sign
== LINE_OFFSET_NONE
? ""
333 : (explicit_loc
->line_offset
.sign
334 == LINE_OFFSET_PLUS
? "+" : "-")),
335 explicit_loc
->line_offset
.offset
);
338 return buf
.release ();
341 /* See description in location.h. */
344 explicit_location_spec::to_linespec () const
346 return explicit_to_string_internal (true, this);
349 /* Find an instance of the quote character C in the string S that is
350 outside of all single- and double-quoted strings (i.e., any quoting
354 find_end_quote (const char *s
, char end_quote_char
)
356 /* zero if we're not in quotes;
357 '"' if we're in a double-quoted string;
358 '\'' if we're in a single-quoted string. */
359 char nested_quote_char
= '\0';
361 for (const char *scan
= s
; *scan
!= '\0'; scan
++)
363 if (nested_quote_char
!= '\0')
365 if (*scan
== nested_quote_char
)
366 nested_quote_char
= '\0';
367 else if (scan
[0] == '\\' && *(scan
+ 1) != '\0')
370 else if (*scan
== end_quote_char
&& nested_quote_char
== '\0')
372 else if (*scan
== '"' || *scan
== '\'')
373 nested_quote_char
= *scan
;
379 /* A lexer for explicit location specs. This function will advance
380 INP past any strings that it lexes. Returns a malloc'd copy of the
381 lexed string or NULL if no lexing was done. */
383 static gdb::unique_xmalloc_ptr
<char>
384 explicit_location_spec_lex_one (const char **inp
,
385 const struct language_defn
*language
,
386 explicit_completion_info
*completion_info
)
388 const char *start
= *inp
;
393 /* If quoted, skip to the ending quote. */
394 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
396 if (completion_info
!= NULL
)
397 completion_info
->quoted_arg_start
= start
;
399 const char *end
= find_end_quote (start
+ 1, *start
);
403 if (completion_info
== NULL
)
404 error (_("Unmatched quote, %s."), start
);
406 end
= start
+ strlen (start
);
408 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
412 if (completion_info
!= NULL
)
413 completion_info
->quoted_arg_end
= end
;
415 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
419 /* If the input starts with '-' or '+', the string ends with the next
420 whitespace or comma. */
421 if (*start
== '-' || *start
== '+')
423 while (*inp
[0] != '\0' && *inp
[0] != ',' && !isspace (*inp
[0]))
428 /* Handle numbers first, stopping at the next whitespace or ','. */
429 while (isdigit (*inp
[0]))
431 if (*inp
[0] == '\0' || isspace (*inp
[0]) || *inp
[0] == ',')
432 return gdb::unique_xmalloc_ptr
<char> (savestring (start
,
435 /* Otherwise stop at the next occurrence of whitespace, '\0',
440 && !(isspace ((*inp
)[0])
441 || linespec_lexer_lex_keyword (&(*inp
)[1])))
443 /* Special case: C++ operator,. */
444 if (language
->la_language
== language_cplus
445 && startswith (*inp
, CP_OPERATOR_STR
))
446 (*inp
) += CP_OPERATOR_LEN
;
451 if (*inp
- start
> 0)
452 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
457 /* Return true if COMMA points past "operator". START is the start of
458 the line that COMMAND points to, hence when reading backwards, we
459 must not read any character before START. */
462 is_cp_operator (const char *start
, const char *comma
)
465 && (comma
- start
) >= CP_OPERATOR_LEN
)
467 const char *p
= comma
;
469 while (p
> start
&& isspace (p
[-1]))
471 if (p
- start
>= CP_OPERATOR_LEN
)
473 p
-= CP_OPERATOR_LEN
;
474 if (strncmp (p
, CP_OPERATOR_STR
, CP_OPERATOR_LEN
) == 0
476 || !(isalnum (p
[-1]) || p
[-1] == '_')))
485 /* When scanning the input string looking for the next explicit
486 location spec option/delimiter, we jump to the next option by looking
487 for ",", and "-". Such a character can also appear in C++ symbols
488 like "operator," and "operator-". So when we find such a
489 character, we call this function to check if we found such a
490 symbol, meaning we had a false positive for an option string. In
491 that case, we keep looking for the next delimiter, until we find
492 one that is not a false positive, or we reach end of string. FOUND
493 is the character that scanning found (either '-' or ','), and START
494 is the start of the line that FOUND points to, hence when reading
495 backwards, we must not read any character before START. Returns a
496 pointer to the next non-false-positive delimiter character, or NULL
497 if none was found. */
500 skip_op_false_positives (const char *start
, const char *found
)
502 while (found
!= NULL
&& is_cp_operator (start
, found
))
504 if (found
[0] == '-' && found
[1] == '-')
508 found
= find_toplevel_char (start
, *found
);
514 /* Assuming both FIRST and NEW_TOK point into the same string, return
515 the pointer that is closer to the start of the string. If FIRST is
516 NULL, returns NEW_TOK. If NEW_TOK is NULL, returns FIRST. */
519 first_of (const char *first
, const char *new_tok
)
523 else if (new_tok
!= NULL
&& new_tok
< first
)
529 /* A lexer for functions in explicit location specs. This function will
530 advance INP past a function until the next option, or until end of
531 string. Returns a malloc'd copy of the lexed string or NULL if no
534 static gdb::unique_xmalloc_ptr
<char>
535 explicit_location_spec_lex_one_function
537 const struct language_defn
*language
,
538 explicit_completion_info
*completion_info
)
540 const char *start
= *inp
;
545 /* If quoted, skip to the ending quote. */
546 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
548 char quote_char
= *start
;
550 /* If the input is not an Ada operator, skip to the matching
551 closing quote and return the string. */
552 if (!(language
->la_language
== language_ada
553 && quote_char
== '\"' && is_ada_operator (start
)))
555 if (completion_info
!= NULL
)
556 completion_info
->quoted_arg_start
= start
;
558 const char *end
= find_toplevel_char (start
+ 1, quote_char
);
562 if (completion_info
== NULL
)
563 error (_("Unmatched quote, %s."), start
);
565 end
= start
+ strlen (start
);
567 char *saved
= savestring (start
+ 1, *inp
- start
- 1);
568 return gdb::unique_xmalloc_ptr
<char> (saved
);
571 if (completion_info
!= NULL
)
572 completion_info
->quoted_arg_end
= end
;
574 char *saved
= savestring (start
+ 1, *inp
- start
- 2);
575 return gdb::unique_xmalloc_ptr
<char> (saved
);
579 const char *comma
= find_toplevel_char (start
, ',');
581 /* If we have "-function -myfunction", or perhaps better example,
582 "-function -[BasicClass doIt]" (objc selector), treat
583 "-myfunction" as the function name. I.e., skip the first char if
584 it is an hyphen. Don't skip the first char always, because we
585 may have C++ "operator<", and find_toplevel_char needs to see the
589 ? find_toplevel_char (start
+ 1, '-')
590 : find_toplevel_char (start
, '-'));
592 /* Check for C++ "operator," and "operator-". */
593 comma
= skip_op_false_positives (start
, comma
);
594 hyphen
= skip_op_false_positives (start
, hyphen
);
596 /* Pick the one that appears first. */
597 const char *end
= first_of (hyphen
, comma
);
599 /* See if a linespec keyword appears first. */
600 const char *s
= start
;
601 const char *ws
= find_toplevel_char (start
, ' ');
602 while (ws
!= NULL
&& linespec_lexer_lex_keyword (ws
+ 1) == NULL
)
605 ws
= find_toplevel_char (s
, ' ');
608 end
= first_of (end
, ws
+ 1);
610 /* If we don't have any terminator, then take the whole string. */
612 end
= start
+ strlen (start
);
614 /* Trim whitespace at the end. */
615 while (end
> start
&& end
[-1] == ' ')
620 if (*inp
- start
> 0)
621 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
626 /* See description in location.h. */
629 string_to_explicit_location_spec (const char **argp
,
630 const struct language_defn
*language
,
631 explicit_completion_info
*completion_info
)
633 /* It is assumed that input beginning with '-' and a non-digit
634 character is an explicit location. "-p" is reserved, though,
635 for probe locations. */
639 || !isalpha ((*argp
)[1])
640 || ((*argp
)[0] == '-' && (*argp
)[1] == 'p'))
643 std::unique_ptr
<explicit_location_spec
> locspec
644 (new explicit_location_spec ());
646 /* Process option/argument pairs. dprintf_command
647 requires that processing stop on ','. */
648 while ((*argp
)[0] != '\0' && (*argp
)[0] != ',')
653 /* Clear these on each iteration, since they should be filled
654 with info about the last option. */
655 if (completion_info
!= NULL
)
657 completion_info
->quoted_arg_start
= NULL
;
658 completion_info
->quoted_arg_end
= NULL
;
661 /* If *ARGP starts with a keyword, stop processing
663 if (linespec_lexer_lex_keyword (*argp
) != NULL
)
666 /* Mark the start of the string in case we need to rewind. */
669 if (completion_info
!= NULL
)
670 completion_info
->last_option
= start
;
672 /* Get the option string. */
673 gdb::unique_xmalloc_ptr
<char> opt
674 = explicit_location_spec_lex_one (argp
, language
, NULL
);
676 /* Use the length of the option to allow abbreviations. */
677 len
= strlen (opt
.get ());
679 /* Get the argument string. */
680 *argp
= skip_spaces (*argp
);
682 /* All options have a required argument. Checking for this
683 required argument is deferred until later. */
684 gdb::unique_xmalloc_ptr
<char> oarg
;
685 /* True if we have an argument. This is required because we'll
686 move from OARG before checking whether we have an
688 bool have_oarg
= false;
690 /* True if the option needs an argument. */
691 bool need_oarg
= false;
693 /* Convenience to consistently set both OARG/HAVE_OARG from
695 auto set_oarg
= [&] (gdb::unique_xmalloc_ptr
<char> arg
)
697 if (completion_info
!= NULL
)
699 /* We do this here because the set of options that take
700 arguments matches the set of explicit location
702 completion_info
->saw_explicit_location_spec_option
= true;
704 oarg
= std::move (arg
);
705 have_oarg
= oarg
!= NULL
;
709 if (strncmp (opt
.get (), "-source", len
) == 0)
711 set_oarg (explicit_location_spec_lex_one (argp
, language
,
713 locspec
->source_filename
= oarg
.release ();
715 else if (strncmp (opt
.get (), "-function", len
) == 0)
717 set_oarg (explicit_location_spec_lex_one_function (argp
, language
,
719 locspec
->function_name
= oarg
.release ();
721 else if (strncmp (opt
.get (), "-qualified", len
) == 0)
723 locspec
->func_name_match_type
= symbol_name_match_type::FULL
;
725 else if (strncmp (opt
.get (), "-line", len
) == 0)
727 set_oarg (explicit_location_spec_lex_one (argp
, language
, NULL
));
728 *argp
= skip_spaces (*argp
);
731 locspec
->line_offset
= linespec_parse_line_offset (oarg
.get ());
735 else if (strncmp (opt
.get (), "-label", len
) == 0)
737 set_oarg (explicit_location_spec_lex_one (argp
, language
,
739 locspec
->label_name
= oarg
.release ();
741 /* Only emit an "invalid argument" error for options
742 that look like option strings. */
743 else if (opt
.get ()[0] == '-' && !isdigit (opt
.get ()[1]))
745 if (completion_info
== NULL
)
746 error (_("invalid explicit location argument, \"%s\""), opt
.get ());
750 /* End of the explicit location specification.
751 Stop parsing and return whatever explicit location was
757 *argp
= skip_spaces (*argp
);
759 /* It's a little lame to error after the fact, but in this
760 case, it provides a much better user experience to issue
761 the "invalid argument" error before any missing
763 if (need_oarg
&& !have_oarg
&& completion_info
== NULL
)
764 error (_("missing argument for \"%s\""), opt
.get ());
767 /* One special error check: If a source filename was given
768 without offset, function, or label, issue an error. */
769 if (locspec
->source_filename
!= NULL
770 && locspec
->function_name
== NULL
771 && locspec
->label_name
== NULL
772 && (locspec
->line_offset
.sign
== LINE_OFFSET_UNKNOWN
)
773 && completion_info
== NULL
)
775 error (_("Source filename requires function, label, or "
779 return location_spec_up (locspec
.release ());
782 /* See description in location.h. */
785 string_to_location_spec_basic (const char **stringp
,
786 const struct language_defn
*language
,
787 symbol_name_match_type match_type
)
789 location_spec_up locspec
;
792 /* Try the input as a probe spec. */
794 if (cs
!= NULL
&& probe_linespec_to_static_ops (&cs
) != NULL
)
796 locspec
= new_probe_location_spec (*stringp
);
797 *stringp
+= strlen (*stringp
);
801 /* Try an address location spec. */
802 if (*stringp
!= NULL
&& **stringp
== '*')
804 const char *arg
, *orig
;
807 orig
= arg
= *stringp
;
808 addr
= linespec_expression_to_pc (&arg
);
809 locspec
= new_address_location_spec (addr
, orig
, arg
- orig
);
810 *stringp
+= arg
- orig
;
814 /* Everything else is a linespec. */
815 locspec
= new_linespec_location_spec (stringp
, match_type
);
822 /* See description in location.h. */
825 string_to_location_spec (const char **stringp
,
826 const struct language_defn
*language
,
827 symbol_name_match_type match_type
)
829 const char *arg
, *orig
;
831 /* Try an explicit location spec. */
832 orig
= arg
= *stringp
;
833 location_spec_up locspec
834 = string_to_explicit_location_spec (&arg
, language
, NULL
);
835 if (locspec
!= nullptr)
837 /* It was a valid explicit location. Advance STRINGP to
839 *stringp
+= arg
- orig
;
841 /* If the user really specified a location spec, then we're
843 if (!locspec
->empty_p ())
846 /* Otherwise, the user _only_ specified optional flags like
847 "-qualified", otherwise string_to_explicit_location_spec
848 would have thrown an error. Save the flags for "basic"
849 linespec parsing below and discard the explicit location
851 explicit_location_spec
*xloc
852 = gdb::checked_static_cast
<explicit_location_spec
*> (locspec
.get ());
853 match_type
= xloc
->func_name_match_type
;
856 /* Everything else is a "basic" linespec, address, or probe location
858 return string_to_location_spec_basic (stringp
, language
, match_type
);