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 (m_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 m_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 /* Find an instance of the quote character C in the string S that is
349 outside of all single- and double-quoted strings (i.e., any quoting
353 find_end_quote (const char *s
, char end_quote_char
)
355 /* zero if we're not in quotes;
356 '"' if we're in a double-quoted string;
357 '\'' if we're in a single-quoted string. */
358 char nested_quote_char
= '\0';
360 for (const char *scan
= s
; *scan
!= '\0'; scan
++)
362 if (nested_quote_char
!= '\0')
364 if (*scan
== nested_quote_char
)
365 nested_quote_char
= '\0';
366 else if (scan
[0] == '\\' && *(scan
+ 1) != '\0')
369 else if (*scan
== end_quote_char
&& nested_quote_char
== '\0')
371 else if (*scan
== '"' || *scan
== '\'')
372 nested_quote_char
= *scan
;
378 /* A lexer for explicit location specs. This function will advance
379 INP past any strings that it lexes. Returns a malloc'd copy of the
380 lexed string or NULL if no lexing was done. */
382 static gdb::unique_xmalloc_ptr
<char>
383 explicit_location_spec_lex_one (const char **inp
,
384 const struct language_defn
*language
,
385 explicit_completion_info
*completion_info
)
387 const char *start
= *inp
;
392 /* If quoted, skip to the ending quote. */
393 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
395 if (completion_info
!= NULL
)
396 completion_info
->quoted_arg_start
= start
;
398 const char *end
= find_end_quote (start
+ 1, *start
);
402 if (completion_info
== NULL
)
403 error (_("Unmatched quote, %s."), start
);
405 end
= start
+ strlen (start
);
407 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
411 if (completion_info
!= NULL
)
412 completion_info
->quoted_arg_end
= end
;
414 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
418 /* If the input starts with '-' or '+', the string ends with the next
419 whitespace or comma. */
420 if (*start
== '-' || *start
== '+')
422 while (*inp
[0] != '\0' && *inp
[0] != ',' && !isspace (*inp
[0]))
427 /* Handle numbers first, stopping at the next whitespace or ','. */
428 while (isdigit (*inp
[0]))
430 if (*inp
[0] == '\0' || isspace (*inp
[0]) || *inp
[0] == ',')
431 return gdb::unique_xmalloc_ptr
<char> (savestring (start
,
434 /* Otherwise stop at the next occurrence of whitespace, '\0',
439 && !(isspace ((*inp
)[0])
440 || linespec_lexer_lex_keyword (&(*inp
)[1])))
442 /* Special case: C++ operator,. */
443 if (language
->la_language
== language_cplus
444 && startswith (*inp
, CP_OPERATOR_STR
))
445 (*inp
) += CP_OPERATOR_LEN
;
450 if (*inp
- start
> 0)
451 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
456 /* Return true if COMMA points past "operator". START is the start of
457 the line that COMMAND points to, hence when reading backwards, we
458 must not read any character before START. */
461 is_cp_operator (const char *start
, const char *comma
)
464 && (comma
- start
) >= CP_OPERATOR_LEN
)
466 const char *p
= comma
;
468 while (p
> start
&& isspace (p
[-1]))
470 if (p
- start
>= CP_OPERATOR_LEN
)
472 p
-= CP_OPERATOR_LEN
;
473 if (strncmp (p
, CP_OPERATOR_STR
, CP_OPERATOR_LEN
) == 0
475 || !(isalnum (p
[-1]) || p
[-1] == '_')))
484 /* When scanning the input string looking for the next explicit
485 location spec option/delimiter, we jump to the next option by looking
486 for ",", and "-". Such a character can also appear in C++ symbols
487 like "operator," and "operator-". So when we find such a
488 character, we call this function to check if we found such a
489 symbol, meaning we had a false positive for an option string. In
490 that case, we keep looking for the next delimiter, until we find
491 one that is not a false positive, or we reach end of string. FOUND
492 is the character that scanning found (either '-' or ','), and START
493 is the start of the line that FOUND points to, hence when reading
494 backwards, we must not read any character before START. Returns a
495 pointer to the next non-false-positive delimiter character, or NULL
496 if none was found. */
499 skip_op_false_positives (const char *start
, const char *found
)
501 while (found
!= NULL
&& is_cp_operator (start
, found
))
503 if (found
[0] == '-' && found
[1] == '-')
507 found
= find_toplevel_char (start
, *found
);
513 /* Assuming both FIRST and NEW_TOK point into the same string, return
514 the pointer that is closer to the start of the string. If FIRST is
515 NULL, returns NEW_TOK. If NEW_TOK is NULL, returns FIRST. */
518 first_of (const char *first
, const char *new_tok
)
522 else if (new_tok
!= NULL
&& new_tok
< first
)
528 /* A lexer for functions in explicit location specs. This function will
529 advance INP past a function until the next option, or until end of
530 string. Returns a malloc'd copy of the lexed string or NULL if no
533 static gdb::unique_xmalloc_ptr
<char>
534 explicit_location_spec_lex_one_function
536 const struct language_defn
*language
,
537 explicit_completion_info
*completion_info
)
539 const char *start
= *inp
;
544 /* If quoted, skip to the ending quote. */
545 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
547 char quote_char
= *start
;
549 /* If the input is not an Ada operator, skip to the matching
550 closing quote and return the string. */
551 if (!(language
->la_language
== language_ada
552 && quote_char
== '\"' && is_ada_operator (start
)))
554 if (completion_info
!= NULL
)
555 completion_info
->quoted_arg_start
= start
;
557 const char *end
= find_toplevel_char (start
+ 1, quote_char
);
561 if (completion_info
== NULL
)
562 error (_("Unmatched quote, %s."), start
);
564 end
= start
+ strlen (start
);
566 char *saved
= savestring (start
+ 1, *inp
- start
- 1);
567 return gdb::unique_xmalloc_ptr
<char> (saved
);
570 if (completion_info
!= NULL
)
571 completion_info
->quoted_arg_end
= end
;
573 char *saved
= savestring (start
+ 1, *inp
- start
- 2);
574 return gdb::unique_xmalloc_ptr
<char> (saved
);
578 const char *comma
= find_toplevel_char (start
, ',');
580 /* If we have "-function -myfunction", or perhaps better example,
581 "-function -[BasicClass doIt]" (objc selector), treat
582 "-myfunction" as the function name. I.e., skip the first char if
583 it is an hyphen. Don't skip the first char always, because we
584 may have C++ "operator<", and find_toplevel_char needs to see the
588 ? find_toplevel_char (start
+ 1, '-')
589 : find_toplevel_char (start
, '-'));
591 /* Check for C++ "operator," and "operator-". */
592 comma
= skip_op_false_positives (start
, comma
);
593 hyphen
= skip_op_false_positives (start
, hyphen
);
595 /* Pick the one that appears first. */
596 const char *end
= first_of (hyphen
, comma
);
598 /* See if a linespec keyword appears first. */
599 const char *s
= start
;
600 const char *ws
= find_toplevel_char (start
, ' ');
601 while (ws
!= NULL
&& linespec_lexer_lex_keyword (ws
+ 1) == NULL
)
604 ws
= find_toplevel_char (s
, ' ');
607 end
= first_of (end
, ws
+ 1);
609 /* If we don't have any terminator, then take the whole string. */
611 end
= start
+ strlen (start
);
613 /* Trim whitespace at the end. */
614 while (end
> start
&& end
[-1] == ' ')
619 if (*inp
- start
> 0)
620 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
625 /* See description in location.h. */
628 string_to_explicit_location_spec (const char **argp
,
629 const struct language_defn
*language
,
630 explicit_completion_info
*completion_info
)
632 /* It is assumed that input beginning with '-' and a non-digit
633 character is an explicit location. "-p" is reserved, though,
634 for probe locations. */
638 || !isalpha ((*argp
)[1])
639 || ((*argp
)[0] == '-' && (*argp
)[1] == 'p'))
642 std::unique_ptr
<explicit_location_spec
> locspec
643 (new explicit_location_spec ());
645 /* Process option/argument pairs. dprintf_command
646 requires that processing stop on ','. */
647 while ((*argp
)[0] != '\0' && (*argp
)[0] != ',')
652 /* Clear these on each iteration, since they should be filled
653 with info about the last option. */
654 if (completion_info
!= NULL
)
656 completion_info
->quoted_arg_start
= NULL
;
657 completion_info
->quoted_arg_end
= NULL
;
660 /* If *ARGP starts with a keyword, stop processing
662 if (linespec_lexer_lex_keyword (*argp
) != NULL
)
665 /* Mark the start of the string in case we need to rewind. */
668 if (completion_info
!= NULL
)
669 completion_info
->last_option
= start
;
671 /* Get the option string. */
672 gdb::unique_xmalloc_ptr
<char> opt
673 = explicit_location_spec_lex_one (argp
, language
, NULL
);
675 /* Use the length of the option to allow abbreviations. */
676 len
= strlen (opt
.get ());
678 /* Get the argument string. */
679 *argp
= skip_spaces (*argp
);
681 /* All options have a required argument. Checking for this
682 required argument is deferred until later. */
683 gdb::unique_xmalloc_ptr
<char> oarg
;
684 /* True if we have an argument. This is required because we'll
685 move from OARG before checking whether we have an
687 bool have_oarg
= false;
689 /* True if the option needs an argument. */
690 bool need_oarg
= false;
692 /* Convenience to consistently set both OARG/HAVE_OARG from
694 auto set_oarg
= [&] (gdb::unique_xmalloc_ptr
<char> arg
)
696 if (completion_info
!= NULL
)
698 /* We do this here because the set of options that take
699 arguments matches the set of explicit location
701 completion_info
->saw_explicit_location_spec_option
= true;
703 oarg
= std::move (arg
);
704 have_oarg
= oarg
!= NULL
;
708 if (strncmp (opt
.get (), "-source", len
) == 0)
710 set_oarg (explicit_location_spec_lex_one (argp
, language
,
712 locspec
->source_filename
= oarg
.release ();
714 else if (strncmp (opt
.get (), "-function", len
) == 0)
716 set_oarg (explicit_location_spec_lex_one_function (argp
, language
,
718 locspec
->function_name
= oarg
.release ();
720 else if (strncmp (opt
.get (), "-qualified", len
) == 0)
722 locspec
->func_name_match_type
= symbol_name_match_type::FULL
;
724 else if (strncmp (opt
.get (), "-line", len
) == 0)
726 set_oarg (explicit_location_spec_lex_one (argp
, language
, NULL
));
727 *argp
= skip_spaces (*argp
);
730 locspec
->line_offset
= linespec_parse_line_offset (oarg
.get ());
734 else if (strncmp (opt
.get (), "-label", len
) == 0)
736 set_oarg (explicit_location_spec_lex_one (argp
, language
,
738 locspec
->label_name
= oarg
.release ();
740 /* Only emit an "invalid argument" error for options
741 that look like option strings. */
742 else if (opt
.get ()[0] == '-' && !isdigit (opt
.get ()[1]))
744 if (completion_info
== NULL
)
745 error (_("invalid explicit location argument, \"%s\""), opt
.get ());
749 /* End of the explicit location specification.
750 Stop parsing and return whatever explicit location was
756 *argp
= skip_spaces (*argp
);
758 /* It's a little lame to error after the fact, but in this
759 case, it provides a much better user experience to issue
760 the "invalid argument" error before any missing
762 if (need_oarg
&& !have_oarg
&& completion_info
== NULL
)
763 error (_("missing argument for \"%s\""), opt
.get ());
766 /* One special error check: If a source filename was given
767 without offset, function, or label, issue an error. */
768 if (locspec
->source_filename
!= NULL
769 && locspec
->function_name
== NULL
770 && locspec
->label_name
== NULL
771 && (locspec
->line_offset
.sign
== LINE_OFFSET_UNKNOWN
)
772 && completion_info
== NULL
)
774 error (_("Source filename requires function, label, or "
778 return location_spec_up (locspec
.release ());
781 /* See description in location.h. */
784 string_to_location_spec_basic (const char **stringp
,
785 const struct language_defn
*language
,
786 symbol_name_match_type match_type
)
788 location_spec_up locspec
;
791 /* Try the input as a probe spec. */
793 if (cs
!= NULL
&& probe_linespec_to_static_ops (&cs
) != NULL
)
795 locspec
= new_probe_location_spec (*stringp
);
796 *stringp
+= strlen (*stringp
);
800 /* Try an address location spec. */
801 if (*stringp
!= NULL
&& **stringp
== '*')
803 const char *arg
, *orig
;
806 orig
= arg
= *stringp
;
807 addr
= linespec_expression_to_pc (&arg
);
808 locspec
= new_address_location_spec (addr
, orig
, arg
- orig
);
809 *stringp
+= arg
- orig
;
813 /* Everything else is a linespec. */
814 locspec
= new_linespec_location_spec (stringp
, match_type
);
821 /* See description in location.h. */
824 string_to_location_spec (const char **stringp
,
825 const struct language_defn
*language
,
826 symbol_name_match_type match_type
)
828 const char *arg
, *orig
;
830 /* Try an explicit location spec. */
831 orig
= arg
= *stringp
;
832 location_spec_up locspec
833 = string_to_explicit_location_spec (&arg
, language
, NULL
);
834 if (locspec
!= nullptr)
836 /* It was a valid explicit location. Advance STRINGP to
838 *stringp
+= arg
- orig
;
840 /* If the user really specified a location spec, then we're
842 if (!locspec
->empty_p ())
845 /* Otherwise, the user _only_ specified optional flags like
846 "-qualified", otherwise string_to_explicit_location_spec
847 would have thrown an error. Save the flags for "basic"
848 linespec parsing below and discard the explicit location
850 explicit_location_spec
*xloc
851 = dynamic_cast<explicit_location_spec
*> (locspec
.get ());
852 gdb_assert (xloc
!= nullptr);
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
);