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 location_spec_to_string (struct location_spec
*locspec
)
361 return locspec
->to_string ();
364 /* Find an instance of the quote character C in the string S that is
365 outside of all single- and double-quoted strings (i.e., any quoting
369 find_end_quote (const char *s
, char end_quote_char
)
371 /* zero if we're not in quotes;
372 '"' if we're in a double-quoted string;
373 '\'' if we're in a single-quoted string. */
374 char nested_quote_char
= '\0';
376 for (const char *scan
= s
; *scan
!= '\0'; scan
++)
378 if (nested_quote_char
!= '\0')
380 if (*scan
== nested_quote_char
)
381 nested_quote_char
= '\0';
382 else if (scan
[0] == '\\' && *(scan
+ 1) != '\0')
385 else if (*scan
== end_quote_char
&& nested_quote_char
== '\0')
387 else if (*scan
== '"' || *scan
== '\'')
388 nested_quote_char
= *scan
;
394 /* A lexer for explicit location specs. This function will advance
395 INP past any strings that it lexes. Returns a malloc'd copy of the
396 lexed string or NULL if no lexing was done. */
398 static gdb::unique_xmalloc_ptr
<char>
399 explicit_location_spec_lex_one (const char **inp
,
400 const struct language_defn
*language
,
401 explicit_completion_info
*completion_info
)
403 const char *start
= *inp
;
408 /* If quoted, skip to the ending quote. */
409 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
411 if (completion_info
!= NULL
)
412 completion_info
->quoted_arg_start
= start
;
414 const char *end
= find_end_quote (start
+ 1, *start
);
418 if (completion_info
== NULL
)
419 error (_("Unmatched quote, %s."), start
);
421 end
= start
+ strlen (start
);
423 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
427 if (completion_info
!= NULL
)
428 completion_info
->quoted_arg_end
= end
;
430 return gdb::unique_xmalloc_ptr
<char> (savestring (start
+ 1,
434 /* If the input starts with '-' or '+', the string ends with the next
435 whitespace or comma. */
436 if (*start
== '-' || *start
== '+')
438 while (*inp
[0] != '\0' && *inp
[0] != ',' && !isspace (*inp
[0]))
443 /* Handle numbers first, stopping at the next whitespace or ','. */
444 while (isdigit (*inp
[0]))
446 if (*inp
[0] == '\0' || isspace (*inp
[0]) || *inp
[0] == ',')
447 return gdb::unique_xmalloc_ptr
<char> (savestring (start
,
450 /* Otherwise stop at the next occurrence of whitespace, '\0',
455 && !(isspace ((*inp
)[0])
456 || linespec_lexer_lex_keyword (&(*inp
)[1])))
458 /* Special case: C++ operator,. */
459 if (language
->la_language
== language_cplus
460 && startswith (*inp
, CP_OPERATOR_STR
))
461 (*inp
) += CP_OPERATOR_LEN
;
466 if (*inp
- start
> 0)
467 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
472 /* Return true if COMMA points past "operator". START is the start of
473 the line that COMMAND points to, hence when reading backwards, we
474 must not read any character before START. */
477 is_cp_operator (const char *start
, const char *comma
)
480 && (comma
- start
) >= CP_OPERATOR_LEN
)
482 const char *p
= comma
;
484 while (p
> start
&& isspace (p
[-1]))
486 if (p
- start
>= CP_OPERATOR_LEN
)
488 p
-= CP_OPERATOR_LEN
;
489 if (strncmp (p
, CP_OPERATOR_STR
, CP_OPERATOR_LEN
) == 0
491 || !(isalnum (p
[-1]) || p
[-1] == '_')))
500 /* When scanning the input string looking for the next explicit
501 location spec option/delimiter, we jump to the next option by looking
502 for ",", and "-". Such a character can also appear in C++ symbols
503 like "operator," and "operator-". So when we find such a
504 character, we call this function to check if we found such a
505 symbol, meaning we had a false positive for an option string. In
506 that case, we keep looking for the next delimiter, until we find
507 one that is not a false positive, or we reach end of string. FOUND
508 is the character that scanning found (either '-' or ','), and START
509 is the start of the line that FOUND points to, hence when reading
510 backwards, we must not read any character before START. Returns a
511 pointer to the next non-false-positive delimiter character, or NULL
512 if none was found. */
515 skip_op_false_positives (const char *start
, const char *found
)
517 while (found
!= NULL
&& is_cp_operator (start
, found
))
519 if (found
[0] == '-' && found
[1] == '-')
523 found
= find_toplevel_char (start
, *found
);
529 /* Assuming both FIRST and NEW_TOK point into the same string, return
530 the pointer that is closer to the start of the string. If FIRST is
531 NULL, returns NEW_TOK. If NEW_TOK is NULL, returns FIRST. */
534 first_of (const char *first
, const char *new_tok
)
538 else if (new_tok
!= NULL
&& new_tok
< first
)
544 /* A lexer for functions in explicit location specs. This function will
545 advance INP past a function until the next option, or until end of
546 string. Returns a malloc'd copy of the lexed string or NULL if no
549 static gdb::unique_xmalloc_ptr
<char>
550 explicit_location_spec_lex_one_function
552 const struct language_defn
*language
,
553 explicit_completion_info
*completion_info
)
555 const char *start
= *inp
;
560 /* If quoted, skip to the ending quote. */
561 if (strchr (get_gdb_linespec_parser_quote_characters (), *start
))
563 char quote_char
= *start
;
565 /* If the input is not an Ada operator, skip to the matching
566 closing quote and return the string. */
567 if (!(language
->la_language
== language_ada
568 && quote_char
== '\"' && is_ada_operator (start
)))
570 if (completion_info
!= NULL
)
571 completion_info
->quoted_arg_start
= start
;
573 const char *end
= find_toplevel_char (start
+ 1, quote_char
);
577 if (completion_info
== NULL
)
578 error (_("Unmatched quote, %s."), start
);
580 end
= start
+ strlen (start
);
582 char *saved
= savestring (start
+ 1, *inp
- start
- 1);
583 return gdb::unique_xmalloc_ptr
<char> (saved
);
586 if (completion_info
!= NULL
)
587 completion_info
->quoted_arg_end
= end
;
589 char *saved
= savestring (start
+ 1, *inp
- start
- 2);
590 return gdb::unique_xmalloc_ptr
<char> (saved
);
594 const char *comma
= find_toplevel_char (start
, ',');
596 /* If we have "-function -myfunction", or perhaps better example,
597 "-function -[BasicClass doIt]" (objc selector), treat
598 "-myfunction" as the function name. I.e., skip the first char if
599 it is an hyphen. Don't skip the first char always, because we
600 may have C++ "operator<", and find_toplevel_char needs to see the
604 ? find_toplevel_char (start
+ 1, '-')
605 : find_toplevel_char (start
, '-'));
607 /* Check for C++ "operator," and "operator-". */
608 comma
= skip_op_false_positives (start
, comma
);
609 hyphen
= skip_op_false_positives (start
, hyphen
);
611 /* Pick the one that appears first. */
612 const char *end
= first_of (hyphen
, comma
);
614 /* See if a linespec keyword appears first. */
615 const char *s
= start
;
616 const char *ws
= find_toplevel_char (start
, ' ');
617 while (ws
!= NULL
&& linespec_lexer_lex_keyword (ws
+ 1) == NULL
)
620 ws
= find_toplevel_char (s
, ' ');
623 end
= first_of (end
, ws
+ 1);
625 /* If we don't have any terminator, then take the whole string. */
627 end
= start
+ strlen (start
);
629 /* Trim whitespace at the end. */
630 while (end
> start
&& end
[-1] == ' ')
635 if (*inp
- start
> 0)
636 return gdb::unique_xmalloc_ptr
<char> (savestring (start
, *inp
- start
));
641 /* See description in location.h. */
644 string_to_explicit_location_spec (const char **argp
,
645 const struct language_defn
*language
,
646 explicit_completion_info
*completion_info
)
648 /* It is assumed that input beginning with '-' and a non-digit
649 character is an explicit location. "-p" is reserved, though,
650 for probe locations. */
654 || !isalpha ((*argp
)[1])
655 || ((*argp
)[0] == '-' && (*argp
)[1] == 'p'))
658 std::unique_ptr
<explicit_location_spec
> locspec
659 (new explicit_location_spec ());
661 /* Process option/argument pairs. dprintf_command
662 requires that processing stop on ','. */
663 while ((*argp
)[0] != '\0' && (*argp
)[0] != ',')
668 /* Clear these on each iteration, since they should be filled
669 with info about the last option. */
670 if (completion_info
!= NULL
)
672 completion_info
->quoted_arg_start
= NULL
;
673 completion_info
->quoted_arg_end
= NULL
;
676 /* If *ARGP starts with a keyword, stop processing
678 if (linespec_lexer_lex_keyword (*argp
) != NULL
)
681 /* Mark the start of the string in case we need to rewind. */
684 if (completion_info
!= NULL
)
685 completion_info
->last_option
= start
;
687 /* Get the option string. */
688 gdb::unique_xmalloc_ptr
<char> opt
689 = explicit_location_spec_lex_one (argp
, language
, NULL
);
691 /* Use the length of the option to allow abbreviations. */
692 len
= strlen (opt
.get ());
694 /* Get the argument string. */
695 *argp
= skip_spaces (*argp
);
697 /* All options have a required argument. Checking for this
698 required argument is deferred until later. */
699 gdb::unique_xmalloc_ptr
<char> oarg
;
700 /* True if we have an argument. This is required because we'll
701 move from OARG before checking whether we have an
703 bool have_oarg
= false;
705 /* True if the option needs an argument. */
706 bool need_oarg
= false;
708 /* Convenience to consistently set both OARG/HAVE_OARG from
710 auto set_oarg
= [&] (gdb::unique_xmalloc_ptr
<char> arg
)
712 if (completion_info
!= NULL
)
714 /* We do this here because the set of options that take
715 arguments matches the set of explicit location
717 completion_info
->saw_explicit_location_spec_option
= true;
719 oarg
= std::move (arg
);
720 have_oarg
= oarg
!= NULL
;
724 if (strncmp (opt
.get (), "-source", len
) == 0)
726 set_oarg (explicit_location_spec_lex_one (argp
, language
,
728 locspec
->source_filename
= oarg
.release ();
730 else if (strncmp (opt
.get (), "-function", len
) == 0)
732 set_oarg (explicit_location_spec_lex_one_function (argp
, language
,
734 locspec
->function_name
= oarg
.release ();
736 else if (strncmp (opt
.get (), "-qualified", len
) == 0)
738 locspec
->func_name_match_type
= symbol_name_match_type::FULL
;
740 else if (strncmp (opt
.get (), "-line", len
) == 0)
742 set_oarg (explicit_location_spec_lex_one (argp
, language
, NULL
));
743 *argp
= skip_spaces (*argp
);
746 locspec
->line_offset
= linespec_parse_line_offset (oarg
.get ());
750 else if (strncmp (opt
.get (), "-label", len
) == 0)
752 set_oarg (explicit_location_spec_lex_one (argp
, language
,
754 locspec
->label_name
= oarg
.release ();
756 /* Only emit an "invalid argument" error for options
757 that look like option strings. */
758 else if (opt
.get ()[0] == '-' && !isdigit (opt
.get ()[1]))
760 if (completion_info
== NULL
)
761 error (_("invalid explicit location argument, \"%s\""), opt
.get ());
765 /* End of the explicit location specification.
766 Stop parsing and return whatever explicit location was
772 *argp
= skip_spaces (*argp
);
774 /* It's a little lame to error after the fact, but in this
775 case, it provides a much better user experience to issue
776 the "invalid argument" error before any missing
778 if (need_oarg
&& !have_oarg
&& completion_info
== NULL
)
779 error (_("missing argument for \"%s\""), opt
.get ());
782 /* One special error check: If a source filename was given
783 without offset, function, or label, issue an error. */
784 if (locspec
->source_filename
!= NULL
785 && locspec
->function_name
== NULL
786 && locspec
->label_name
== NULL
787 && (locspec
->line_offset
.sign
== LINE_OFFSET_UNKNOWN
)
788 && completion_info
== NULL
)
790 error (_("Source filename requires function, label, or "
794 return location_spec_up (locspec
.release ());
797 /* See description in location.h. */
800 string_to_location_spec_basic (const char **stringp
,
801 const struct language_defn
*language
,
802 symbol_name_match_type match_type
)
804 location_spec_up locspec
;
807 /* Try the input as a probe spec. */
809 if (cs
!= NULL
&& probe_linespec_to_static_ops (&cs
) != NULL
)
811 locspec
= new_probe_location_spec (*stringp
);
812 *stringp
+= strlen (*stringp
);
816 /* Try an address location spec. */
817 if (*stringp
!= NULL
&& **stringp
== '*')
819 const char *arg
, *orig
;
822 orig
= arg
= *stringp
;
823 addr
= linespec_expression_to_pc (&arg
);
824 locspec
= new_address_location_spec (addr
, orig
, arg
- orig
);
825 *stringp
+= arg
- orig
;
829 /* Everything else is a linespec. */
830 locspec
= new_linespec_location_spec (stringp
, match_type
);
837 /* See description in location.h. */
840 string_to_location_spec (const char **stringp
,
841 const struct language_defn
*language
,
842 symbol_name_match_type match_type
)
844 const char *arg
, *orig
;
846 /* Try an explicit location spec. */
847 orig
= arg
= *stringp
;
848 location_spec_up locspec
849 = string_to_explicit_location_spec (&arg
, language
, NULL
);
850 if (locspec
!= nullptr)
852 /* It was a valid explicit location. Advance STRINGP to
854 *stringp
+= arg
- orig
;
856 /* If the user really specified a location spec, then we're
858 if (!location_spec_empty_p (locspec
.get ()))
861 /* Otherwise, the user _only_ specified optional flags like
862 "-qualified", otherwise string_to_explicit_location_spec
863 would have thrown an error. Save the flags for "basic"
864 linespec parsing below and discard the explicit location
866 explicit_location_spec
*xloc
867 = dynamic_cast<explicit_location_spec
*> (locspec
.get ());
868 gdb_assert (xloc
!= nullptr);
869 match_type
= xloc
->func_name_match_type
;
872 /* Everything else is a "basic" linespec, address, or probe location
874 return string_to_location_spec_basic (stringp
, language
, match_type
);
877 /* See description in location.h. */
880 location_spec_empty_p (const location_spec
*locspec
)
882 return locspec
->empty_p ();
885 /* See description in location.h. */
888 set_location_spec_string (struct location_spec
*locspec
,
889 std::string
&&string
)
891 locspec
->as_string
= std::move (string
);