1 /* Data structures and API for location specs in GDB.
2    Copyright (C) 2013-2024 Free Software Foundation, Inc.
3 
4    This file is part of GDB.
5 
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.
10 
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.
15 
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/>.  */
18 
19 #include "gdbsupport/gdb_assert.h"
20 #include "gdbsupport/gdb-checked-static-cast.h"
21 #include "location.h"
22 #include "symtab.h"
23 #include "language.h"
24 #include "linespec.h"
25 #include "cli/cli-utils.h"
26 #include "probe.h"
27 #include "cp-support.h"
28 
29 #include <ctype.h>
30 #include <string.h>
31 
32 static std::string
33   explicit_to_string_internal (bool as_linespec,
34                                      const explicit_location_spec *explicit_loc);
35 
36 /* Return a xstrdup of STR if not NULL, otherwise return NULL.  */
37 
38 static char *
maybe_xstrdup(const char * str)39 maybe_xstrdup (const char *str)
40 {
41   return (str != nullptr ? xstrdup (str) : nullptr);
42 }
43 
probe_location_spec(std::string && probe)44 probe_location_spec::probe_location_spec (std::string &&probe)
45   : location_spec (PROBE_LOCATION_SPEC, std::move (probe))
46 {
47 }
48 
49 location_spec_up
clone()50 probe_location_spec::clone () const
51 {
52   return location_spec_up (new probe_location_spec (*this));
53 }
54 
55 bool
empty_p()56 probe_location_spec::empty_p () const
57 {
58   return false;
59 }
60 
compute_string()61 std::string probe_location_spec::compute_string () const
62 {
63   return std::move (m_as_string);
64 }
65 
66 /* A "normal" linespec.  */
linespec_location_spec(const char ** linespec,symbol_name_match_type match_type_)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_)
71 {
72   if (*linespec != NULL)
73     {
74       const char *p;
75       const char *orig = *linespec;
76 
77       linespec_lex_to_end (linespec);
78       p = remove_trailing_whitespace (orig, *linespec);
79 
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.  */
84       if ((p - orig) > 0)
85           spec_string.reset (savestring (orig, p - orig));
86     }
87 }
88 
89 location_spec_up
clone()90 linespec_location_spec::clone () const
91 {
92   return location_spec_up (new linespec_location_spec (*this));
93 }
94 
95 bool
empty_p()96 linespec_location_spec::empty_p () const
97 {
98   return false;
99 }
100 
linespec_location_spec(const linespec_location_spec & other)101 linespec_location_spec::linespec_location_spec
102   (const linespec_location_spec &other)
103   : location_spec (other),
104     match_type (other.match_type),
105     spec_string (maybe_xstrdup (other.spec_string.get ()))
106 {
107 }
108 
109 std::string
compute_string()110 linespec_location_spec::compute_string () const
111 {
112   if (spec_string != nullptr)
113     {
114       if (match_type == symbol_name_match_type::FULL)
115           return std::string ("-qualified ") + spec_string.get ();
116       else
117           return spec_string.get ();
118     }
119   return {};
120 }
121 
address_location_spec(CORE_ADDR addr,const char * addr_string,int addr_string_len)122 address_location_spec::address_location_spec (CORE_ADDR addr,
123                                                         const char *addr_string,
124                                                         int addr_string_len)
125   : location_spec (ADDRESS_LOCATION_SPEC),
126     address (addr)
127 {
128   if (addr_string != nullptr)
129     m_as_string = std::string (addr_string, addr_string_len);
130 }
131 
132 location_spec_up
clone()133 address_location_spec::clone () const
134 {
135   return location_spec_up (new address_location_spec (*this));
136 }
137 
138 bool
empty_p()139 address_location_spec::empty_p () const
140 {
141   return false;
142 }
143 
address_location_spec(const address_location_spec & other)144 address_location_spec::address_location_spec
145   (const address_location_spec &other)
146   : location_spec (other),
147     address (other.address)
148 {
149 }
150 
151 std::string
compute_string()152 address_location_spec::compute_string () const
153 {
154   const char *addr_string = core_addr_to_string (address);
155   return std::string ("*") + addr_string;
156 }
157 
explicit_location_spec(const char * function_name)158 explicit_location_spec::explicit_location_spec (const char *function_name)
159   : location_spec (EXPLICIT_LOCATION_SPEC),
160     function_name (maybe_xstrdup (function_name))
161 {
162 }
163 
explicit_location_spec(const explicit_location_spec & other)164 explicit_location_spec::explicit_location_spec
165   (const explicit_location_spec &other)
166   : location_spec (other),
167     source_filename (maybe_xstrdup (other.source_filename.get ())),
168     function_name (maybe_xstrdup (other.function_name.get ())),
169     func_name_match_type (other.func_name_match_type),
170     label_name (maybe_xstrdup (other.label_name.get ())),
171     line_offset (other.line_offset)
172 {
173 }
174 
175 location_spec_up
clone()176 explicit_location_spec::clone () const
177 {
178   return location_spec_up (new explicit_location_spec (*this));
179 }
180 
181 bool
empty_p()182 explicit_location_spec::empty_p () const
183 {
184   return (source_filename == nullptr
185             && function_name == nullptr
186             && label_name == nullptr
187             && line_offset.sign == LINE_OFFSET_UNKNOWN);
188 }
189 
190 std::string
compute_string()191 explicit_location_spec::compute_string () const
192 {
193   return explicit_to_string_internal (false, this);
194 }
195 
196 /* See description in location.h.  */
197 
198 location_spec_up
new_linespec_location_spec(const char ** linespec,symbol_name_match_type match_type)199 new_linespec_location_spec (const char **linespec,
200                                   symbol_name_match_type match_type)
201 {
202   return location_spec_up (new linespec_location_spec (linespec,
203                                                                    match_type));
204 }
205 
206 /* See description in location.h.  */
207 
208 const linespec_location_spec *
as_linespec_location_spec(const location_spec * locspec)209 as_linespec_location_spec (const location_spec *locspec)
210 {
211   gdb_assert (locspec->type () == LINESPEC_LOCATION_SPEC);
212   return gdb::checked_static_cast<const linespec_location_spec *> (locspec);
213 }
214 
215 /* See description in location.h.  */
216 
217 location_spec_up
new_address_location_spec(CORE_ADDR addr,const char * addr_string,int addr_string_len)218 new_address_location_spec (CORE_ADDR addr, const char *addr_string,
219                                  int addr_string_len)
220 {
221   return location_spec_up (new address_location_spec (addr, addr_string,
222                                                                   addr_string_len));
223 }
224 
225 /* See description in location.h.  */
226 
227 const address_location_spec *
as_address_location_spec(const location_spec * locspec)228 as_address_location_spec (const location_spec *locspec)
229 {
230   gdb_assert (locspec->type () == ADDRESS_LOCATION_SPEC);
231   return gdb::checked_static_cast<const address_location_spec *> (locspec);
232 }
233 
234 /* See description in location.h.  */
235 
236 location_spec_up
new_probe_location_spec(std::string && probe)237 new_probe_location_spec (std::string &&probe)
238 {
239   return location_spec_up (new probe_location_spec (std::move (probe)));
240 }
241 
242 /* See description in location.h.  */
243 
244 const probe_location_spec *
as_probe_location_spec(const location_spec * locspec)245 as_probe_location_spec (const location_spec *locspec)
246 {
247   gdb_assert (locspec->type () == PROBE_LOCATION_SPEC);
248   return gdb::checked_static_cast<const probe_location_spec *> (locspec);
249 }
250 
251 /* See description in location.h.  */
252 
253 const explicit_location_spec *
as_explicit_location_spec(const location_spec * locspec)254 as_explicit_location_spec (const location_spec *locspec)
255 {
256   gdb_assert (locspec->type () == EXPLICIT_LOCATION_SPEC);
257   return gdb::checked_static_cast<const explicit_location_spec *> (locspec);
258 }
259 
260 /* See description in location.h.  */
261 
262 explicit_location_spec *
as_explicit_location_spec(location_spec * locspec)263 as_explicit_location_spec (location_spec *locspec)
264 {
265   gdb_assert (locspec->type () == EXPLICIT_LOCATION_SPEC);
266   return gdb::checked_static_cast<explicit_location_spec *> (locspec);
267 }
268 
269 /* Return a string representation of the explicit location spec in
270    EXPLICIT_LOCSPEC.
271 
272    AS_LINESPEC is true if this string should be a linespec.  Otherwise
273    it will be output in explicit form.  */
274 
275 static std::string
explicit_to_string_internal(bool as_linespec,const explicit_location_spec * explicit_loc)276 explicit_to_string_internal (bool as_linespec,
277                                    const explicit_location_spec *explicit_loc)
278 {
279   bool need_space = false;
280   char space = as_linespec ? ':' : ' ';
281   string_file buf;
282 
283   if (explicit_loc->source_filename != NULL)
284     {
285       if (!as_linespec)
286           buf.puts ("-source ");
287       buf.puts (explicit_loc->source_filename.get ());
288       need_space = true;
289     }
290 
291   if (explicit_loc->function_name != NULL)
292     {
293       if (need_space)
294           buf.putc (space);
295       if (explicit_loc->func_name_match_type == symbol_name_match_type::FULL)
296           buf.puts ("-qualified ");
297       if (!as_linespec)
298           buf.puts ("-function ");
299       buf.puts (explicit_loc->function_name.get ());
300       need_space = true;
301     }
302 
303   if (explicit_loc->label_name != NULL)
304     {
305       if (need_space)
306           buf.putc (space);
307       if (!as_linespec)
308           buf.puts ("-label ");
309       buf.puts (explicit_loc->label_name.get ());
310       need_space = true;
311     }
312 
313   if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN)
314     {
315       if (need_space)
316           buf.putc (space);
317       if (!as_linespec)
318           buf.puts ("-line ");
319       buf.printf ("%s%d",
320                       (explicit_loc->line_offset.sign == LINE_OFFSET_NONE ? ""
321                        : (explicit_loc->line_offset.sign
322                           == LINE_OFFSET_PLUS ? "+" : "-")),
323                       explicit_loc->line_offset.offset);
324     }
325 
326   return buf.release ();
327 }
328 
329 /* See description in location.h.  */
330 
331 std::string
to_linespec()332 explicit_location_spec::to_linespec () const
333 {
334   return explicit_to_string_internal (true, this);
335 }
336 
337 /* Find an instance of the quote character C in the string S that is
338    outside of all single- and double-quoted strings (i.e., any quoting
339    other than C).  */
340 
341 static const char *
find_end_quote(const char * s,char end_quote_char)342 find_end_quote (const char *s, char end_quote_char)
343 {
344   /* zero if we're not in quotes;
345      '"' if we're in a double-quoted string;
346      '\'' if we're in a single-quoted string.  */
347   char nested_quote_char = '\0';
348 
349   for (const char *scan = s; *scan != '\0'; scan++)
350     {
351       if (nested_quote_char != '\0')
352           {
353             if (*scan == nested_quote_char)
354               nested_quote_char = '\0';
355             else if (scan[0] == '\\' && *(scan + 1) != '\0')
356               scan++;
357           }
358       else if (*scan == end_quote_char && nested_quote_char == '\0')
359           return scan;
360       else if (*scan == '"' || *scan == '\'')
361           nested_quote_char = *scan;
362     }
363 
364   return 0;
365 }
366 
367 /* A lexer for explicit location specs.  This function will advance
368    INP past any strings that it lexes.  Returns a malloc'd copy of the
369    lexed string or NULL if no lexing was done.  */
370 
371 static gdb::unique_xmalloc_ptr<char>
explicit_location_spec_lex_one(const char ** inp,const struct language_defn * language,explicit_completion_info * completion_info)372 explicit_location_spec_lex_one (const char **inp,
373                                         const struct language_defn *language,
374                                         explicit_completion_info *completion_info)
375 {
376   const char *start = *inp;
377 
378   if (*start == '\0')
379     return NULL;
380 
381   /* If quoted, skip to the ending quote.  */
382   if (strchr (get_gdb_linespec_parser_quote_characters (), *start))
383     {
384       if (completion_info != NULL)
385           completion_info->quoted_arg_start = start;
386 
387       const char *end = find_end_quote (start + 1, *start);
388 
389       if (end == NULL)
390           {
391             if (completion_info == NULL)
392               error (_("Unmatched quote, %s."), start);
393 
394             end = start + strlen (start);
395             *inp = end;
396             return gdb::unique_xmalloc_ptr<char> (savestring (start + 1,
397                                                                           *inp - start - 1));
398           }
399 
400       if (completion_info != NULL)
401           completion_info->quoted_arg_end = end;
402       *inp = end + 1;
403       return gdb::unique_xmalloc_ptr<char> (savestring (start + 1,
404                                                                       *inp - start - 2));
405     }
406 
407   /* If the input starts with '-' or '+', the string ends with the next
408      whitespace or comma.  */
409   if (*start == '-' || *start == '+')
410     {
411       while (*inp[0] != '\0' && *inp[0] != ',' && !isspace (*inp[0]))
412           ++(*inp);
413     }
414   else
415     {
416       /* Handle numbers first, stopping at the next whitespace or ','.  */
417       while (isdigit (*inp[0]))
418           ++(*inp);
419       if (*inp[0] == '\0' || isspace (*inp[0]) || *inp[0] == ',')
420           return gdb::unique_xmalloc_ptr<char> (savestring (start,
421                                                                         *inp - start));
422 
423       /* Otherwise stop at the next occurrence of whitespace, '\0',
424            keyword, or ','.  */
425       *inp = start;
426       while ((*inp)[0]
427                && (*inp)[0] != ','
428                && !(isspace ((*inp)[0])
429                       || linespec_lexer_lex_keyword (&(*inp)[1])))
430           {
431             /* Special case: C++ operator,.  */
432             if (language->la_language == language_cplus
433                 && startswith (*inp, CP_OPERATOR_STR))
434               (*inp) += CP_OPERATOR_LEN;
435             ++(*inp);
436           }
437     }
438 
439   if (*inp - start > 0)
440     return gdb::unique_xmalloc_ptr<char> (savestring (start, *inp - start));
441 
442   return NULL;
443 }
444 
445 /* Return true if COMMA points past "operator".  START is the start of
446    the line that COMMAND points to, hence when reading backwards, we
447    must not read any character before START.  */
448 
449 static bool
is_cp_operator(const char * start,const char * comma)450 is_cp_operator (const char *start, const char *comma)
451 {
452   if (comma != NULL
453       && (comma - start) >= CP_OPERATOR_LEN)
454     {
455       const char *p = comma;
456 
457       while (p > start && isspace (p[-1]))
458           p--;
459       if (p - start >= CP_OPERATOR_LEN)
460           {
461             p -= CP_OPERATOR_LEN;
462             if (strncmp (p, CP_OPERATOR_STR, CP_OPERATOR_LEN) == 0
463                 && (p == start
464                       || !(isalnum (p[-1]) || p[-1] == '_')))
465               {
466                 return true;
467               }
468           }
469     }
470   return false;
471 }
472 
473 /* When scanning the input string looking for the next explicit
474    location spec option/delimiter, we jump to the next option by looking
475    for ",", and "-".  Such a character can also appear in C++ symbols
476    like "operator," and "operator-".  So when we find such a
477    character, we call this function to check if we found such a
478    symbol, meaning we had a false positive for an option string.  In
479    that case, we keep looking for the next delimiter, until we find
480    one that is not a false positive, or we reach end of string.  FOUND
481    is the character that scanning found (either '-' or ','), and START
482    is the start of the line that FOUND points to, hence when reading
483    backwards, we must not read any character before START.  Returns a
484    pointer to the next non-false-positive delimiter character, or NULL
485    if none was found.  */
486 
487 static const char *
skip_op_false_positives(const char * start,const char * found)488 skip_op_false_positives (const char *start, const char *found)
489 {
490   while (found != NULL && is_cp_operator (start, found))
491     {
492       if (found[0] == '-' && found[1] == '-')
493           start = found + 2;
494       else
495           start = found + 1;
496       found = find_toplevel_char (start, *found);
497     }
498 
499   return found;
500 }
501 
502 /* Assuming both FIRST and NEW_TOK point into the same string, return
503    the pointer that is closer to the start of the string.  If FIRST is
504    NULL, returns NEW_TOK.  If NEW_TOK is NULL, returns FIRST.  */
505 
506 static const char *
first_of(const char * first,const char * new_tok)507 first_of (const char *first, const char *new_tok)
508 {
509   if (first == NULL)
510     return new_tok;
511   else if (new_tok != NULL && new_tok < first)
512     return new_tok;
513   else
514     return first;
515 }
516 
517 /* A lexer for functions in explicit location specs.  This function will
518    advance INP past a function until the next option, or until end of
519    string.  Returns a malloc'd copy of the lexed string or NULL if no
520    lexing was done.  */
521 
522 static gdb::unique_xmalloc_ptr<char>
explicit_location_spec_lex_one_function(const char ** inp,const struct language_defn * language,explicit_completion_info * completion_info)523 explicit_location_spec_lex_one_function
524   (const char **inp,
525    const struct language_defn *language,
526    explicit_completion_info *completion_info)
527 {
528   const char *start = *inp;
529 
530   if (*start == '\0')
531     return NULL;
532 
533   /* If quoted, skip to the ending quote.  */
534   if (strchr (get_gdb_linespec_parser_quote_characters (), *start))
535     {
536       char quote_char = *start;
537 
538       /* If the input is not an Ada operator, skip to the matching
539            closing quote and return the string.  */
540       if (!(language->la_language == language_ada
541               && quote_char == '\"' && is_ada_operator (start)))
542           {
543             if (completion_info != NULL)
544               completion_info->quoted_arg_start = start;
545 
546             const char *end = find_toplevel_char (start + 1, quote_char);
547 
548             if (end == NULL)
549               {
550                 if (completion_info == NULL)
551                     error (_("Unmatched quote, %s."), start);
552 
553                 end = start + strlen (start);
554                 *inp = end;
555                 char *saved = savestring (start + 1, *inp - start - 1);
556                 return gdb::unique_xmalloc_ptr<char> (saved);
557               }
558 
559             if (completion_info != NULL)
560               completion_info->quoted_arg_end = end;
561             *inp = end + 1;
562             char *saved = savestring (start + 1, *inp - start - 2);
563             return gdb::unique_xmalloc_ptr<char> (saved);
564           }
565     }
566 
567   const char *comma = find_toplevel_char (start, ',');
568 
569   /* If we have "-function -myfunction", or perhaps better example,
570      "-function -[BasicClass doIt]" (objc selector), treat
571      "-myfunction" as the function name.  I.e., skip the first char if
572      it is an hyphen.  Don't skip the first char always, because we
573      may have C++ "operator<", and find_toplevel_char needs to see the
574      'o' in that case.  */
575   const char *hyphen
576     = (*start == '-'
577        ? find_toplevel_char (start + 1, '-')
578        : find_toplevel_char (start, '-'));
579 
580   /* Check for C++ "operator," and "operator-".  */
581   comma = skip_op_false_positives (start, comma);
582   hyphen = skip_op_false_positives (start, hyphen);
583 
584   /* Pick the one that appears first.  */
585   const char *end = first_of (hyphen, comma);
586 
587   /* See if a linespec keyword appears first.  */
588   const char *s = start;
589   const char *ws = find_toplevel_char (start, ' ');
590   while (ws != NULL && linespec_lexer_lex_keyword (ws + 1) == NULL)
591     {
592       s = ws + 1;
593       ws = find_toplevel_char (s, ' ');
594     }
595   if (ws != NULL)
596     end = first_of (end, ws + 1);
597 
598   /* If we don't have any terminator, then take the whole string.  */
599   if (end == NULL)
600     end = start + strlen (start);
601 
602   /* Trim whitespace at the end.  */
603   while (end > start && end[-1] == ' ')
604     end--;
605 
606   *inp = end;
607 
608   if (*inp - start > 0)
609     return gdb::unique_xmalloc_ptr<char> (savestring (start, *inp - start));
610 
611   return NULL;
612 }
613 
614 /* See description in location.h.  */
615 
616 location_spec_up
string_to_explicit_location_spec(const char ** argp,const struct language_defn * language,explicit_completion_info * completion_info)617 string_to_explicit_location_spec (const char **argp,
618                                           const struct language_defn *language,
619                                           explicit_completion_info *completion_info)
620 {
621   /* It is assumed that input beginning with '-' and a non-digit
622      character is an explicit location.  "-p" is reserved, though,
623      for probe locations.  */
624   if (argp == NULL
625       || *argp == NULL
626       || *argp[0] != '-'
627       || !isalpha ((*argp)[1])
628       || ((*argp)[0] == '-' && (*argp)[1] == 'p'))
629     return NULL;
630 
631   std::unique_ptr<explicit_location_spec> locspec
632     (new explicit_location_spec ());
633 
634   /* Process option/argument pairs.  dprintf_command
635      requires that processing stop on ','.  */
636   while ((*argp)[0] != '\0' && (*argp)[0] != ',')
637     {
638       int len;
639       const char *start;
640 
641       /* Clear these on each iteration, since they should be filled
642            with info about the last option.  */
643       if (completion_info != NULL)
644           {
645             completion_info->quoted_arg_start = NULL;
646             completion_info->quoted_arg_end = NULL;
647           }
648 
649       /* If *ARGP starts with a keyword, stop processing
650            options.  */
651       if (linespec_lexer_lex_keyword (*argp) != NULL)
652           break;
653 
654       /* Mark the start of the string in case we need to rewind.  */
655       start = *argp;
656 
657       if (completion_info != NULL)
658           completion_info->last_option = start;
659 
660       /* Get the option string.  */
661       gdb::unique_xmalloc_ptr<char> opt
662           = explicit_location_spec_lex_one (argp, language, NULL);
663 
664       /* Use the length of the option to allow abbreviations.  */
665       len = strlen (opt.get ());
666 
667       /* Get the argument string.  */
668       *argp = skip_spaces (*argp);
669 
670       /* All options have a required argument.  Checking for this
671            required argument is deferred until later.  */
672       gdb::unique_xmalloc_ptr<char> oarg;
673       /* True if we have an argument.  This is required because we'll
674            move from OARG before checking whether we have an
675            argument.  */
676       bool have_oarg = false;
677 
678       /* True if the option needs an argument.  */
679       bool need_oarg = false;
680 
681       /* Convenience to consistently set both OARG/HAVE_OARG from
682            ARG.  */
683       auto set_oarg = [&] (gdb::unique_xmalloc_ptr<char> arg)
684           {
685             if (completion_info != NULL)
686               {
687                 /* We do this here because the set of options that take
688                      arguments matches the set of explicit location
689                      options.  */
690                 completion_info->saw_explicit_location_spec_option = true;
691               }
692             oarg = std::move (arg);
693             have_oarg = oarg != NULL;
694             need_oarg = true;
695           };
696 
697       if (strncmp (opt.get (), "-source", len) == 0)
698           {
699             set_oarg (explicit_location_spec_lex_one (argp, language,
700                                                                 completion_info));
701             locspec->source_filename = std::move (oarg);
702           }
703       else if (strncmp (opt.get (), "-function", len) == 0)
704           {
705             set_oarg (explicit_location_spec_lex_one_function (argp, language,
706                                                                            completion_info));
707             locspec->function_name = std::move (oarg);
708           }
709       else if (strncmp (opt.get (), "-qualified", len) == 0)
710           {
711             locspec->func_name_match_type = symbol_name_match_type::FULL;
712           }
713       else if (strncmp (opt.get (), "-line", len) == 0)
714           {
715             set_oarg (explicit_location_spec_lex_one (argp, language, NULL));
716             *argp = skip_spaces (*argp);
717             if (have_oarg)
718               {
719                 locspec->line_offset = linespec_parse_line_offset (oarg.get ());
720                 continue;
721               }
722           }
723       else if (strncmp (opt.get (), "-label", len) == 0)
724           {
725             set_oarg (explicit_location_spec_lex_one (argp, language,
726                                                                 completion_info));
727             locspec->label_name = std::move (oarg);
728           }
729       /* Only emit an "invalid argument" error for options
730            that look like option strings.  */
731       else if (opt.get ()[0] == '-' && !isdigit (opt.get ()[1]))
732           {
733             if (completion_info == NULL)
734               error (_("invalid explicit location argument, \"%s\""), opt.get ());
735           }
736       else
737           {
738             /* End of the explicit location specification.
739                Stop parsing and return whatever explicit location was
740                parsed.  */
741             *argp = start;
742             break;
743           }
744 
745       *argp = skip_spaces (*argp);
746 
747       /* It's a little lame to error after the fact, but in this
748            case, it provides a much better user experience to issue
749            the "invalid argument" error before any missing
750            argument error.  */
751       if (need_oarg && !have_oarg && completion_info == NULL)
752           error (_("missing argument for \"%s\""), opt.get ());
753     }
754 
755   /* One special error check:  If a source filename was given
756      without offset, function, or label, issue an error.  */
757   if (locspec->source_filename != NULL
758       && locspec->function_name == NULL
759       && locspec->label_name == NULL
760       && (locspec->line_offset.sign == LINE_OFFSET_UNKNOWN)
761       && completion_info == NULL)
762     {
763       error (_("Source filename requires function, label, or "
764                  "line offset."));
765     }
766 
767   return location_spec_up (locspec.release ());
768 }
769 
770 /* See description in location.h.  */
771 
772 location_spec_up
string_to_location_spec_basic(const char ** stringp,const struct language_defn * language,symbol_name_match_type match_type)773 string_to_location_spec_basic (const char **stringp,
774                                      const struct language_defn *language,
775                                      symbol_name_match_type match_type)
776 {
777   location_spec_up locspec;
778   const char *cs;
779 
780   /* Try the input as a probe spec.  */
781   cs = *stringp;
782   if (cs != NULL && probe_linespec_to_static_ops (&cs) != NULL)
783     {
784       locspec = new_probe_location_spec (*stringp);
785       *stringp += strlen (*stringp);
786     }
787   else
788     {
789       /* Try an address location spec.  */
790       if (*stringp != NULL && **stringp == '*')
791           {
792             const char *arg, *orig;
793             CORE_ADDR addr;
794 
795             orig = arg = *stringp;
796             addr = linespec_expression_to_pc (&arg);
797             locspec = new_address_location_spec (addr, orig, arg - orig);
798             *stringp += arg - orig;
799           }
800       else
801           {
802             /* Everything else is a linespec.  */
803             locspec = new_linespec_location_spec (stringp, match_type);
804           }
805     }
806 
807   return locspec;
808 }
809 
810 /* See description in location.h.  */
811 
812 location_spec_up
string_to_location_spec(const char ** stringp,const struct language_defn * language,symbol_name_match_type match_type)813 string_to_location_spec (const char **stringp,
814                                const struct language_defn *language,
815                                symbol_name_match_type match_type)
816 {
817   const char *arg, *orig;
818 
819   /* Try an explicit location spec.  */
820   orig = arg = *stringp;
821   location_spec_up locspec
822     = string_to_explicit_location_spec (&arg, language, NULL);
823   if (locspec != nullptr)
824     {
825       /* It was a valid explicit location.  Advance STRINGP to
826            the end of input.  */
827       *stringp += arg - orig;
828 
829       /* If the user really specified a location spec, then we're
830            done.  */
831       if (!locspec->empty_p ())
832           return locspec;
833 
834       /* Otherwise, the user _only_ specified optional flags like
835            "-qualified", otherwise string_to_explicit_location_spec
836            would have thrown an error.  Save the flags for "basic"
837            linespec parsing below and discard the explicit location
838            spec.  */
839       explicit_location_spec *xloc
840           = gdb::checked_static_cast<explicit_location_spec *> (locspec.get ());
841       match_type = xloc->func_name_match_type;
842     }
843 
844   /* Everything else is a "basic" linespec, address, or probe location
845      spec.  */
846   return string_to_location_spec_basic (stringp, language, match_type);
847 }
848