Explicit locations: introduce new struct event_location-based API
[external/binutils.git] / gdb / location.c
1 /* Data structures and API for event locations in GDB.
2    Copyright (C) 2013-2015 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 "defs.h"
20 #include "gdb_assert.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
28 #include <ctype.h>
29 #include <string.h>
30
31 /* An event location used to set a stop event in the inferior.
32    This structure is an amalgam of the various ways
33    to specify where a stop event should be set.  */
34
35 struct event_location
36 {
37   /* The type of this breakpoint specification.  */
38   enum event_location_type type;
39 #define EL_TYPE(PTR) (PTR)->type
40
41   union
42   {
43     /* A generic "this is a string specification" for a location.
44        This representation is used by both "normal" linespecs and
45        probes.  */
46     char *addr_string;
47 #define EL_LINESPEC(PTR) ((PTR)->u.addr_string)
48   } u;
49
50   /* Cached string representation of this location.  This is used, e.g., to
51      save stop event locations to file.  Malloc'd.  */
52   char *as_string;
53 #define EL_STRING(PTR) ((PTR)->as_string)
54 };
55
56 /* See description in location.h.  */
57
58 enum event_location_type
59 event_location_type (const struct event_location *location)
60 {
61   return EL_TYPE (location);
62 }
63
64 /* See description in location.h.  */
65
66 struct event_location *
67 new_linespec_location (char **linespec)
68 {
69   struct event_location *location;
70
71   location = XCNEW (struct event_location);
72   EL_TYPE (location) = LINESPEC_LOCATION;
73   if (*linespec != NULL)
74     {
75       char *p;
76       char *orig = *linespec;
77
78       linespec_lex_to_end (linespec);
79       p = remove_trailing_whitespace (orig, *linespec);
80       if ((p - orig) > 0)
81         EL_LINESPEC (location) = savestring (orig, p - orig);
82     }
83   return location;
84 }
85
86 /* See description in location.h.  */
87
88 const char *
89 get_linespec_location (const struct event_location *location)
90 {
91   gdb_assert (EL_TYPE (location) == LINESPEC_LOCATION);
92   return EL_LINESPEC (location);
93 }
94
95 /* See description in location.h.  */
96
97 struct event_location *
98 copy_event_location (const struct event_location *src)
99 {
100   struct event_location *dst;
101
102   dst = XCNEW (struct event_location);
103   EL_TYPE (dst) = EL_TYPE (src);
104   if (EL_STRING (src) != NULL)
105     EL_STRING (dst) = xstrdup (EL_STRING (src));
106
107   switch (EL_TYPE (src))
108     {
109     case LINESPEC_LOCATION:
110       if (EL_LINESPEC (src) != NULL)
111         EL_LINESPEC (dst) = xstrdup (EL_LINESPEC (src));
112       break;
113
114     default:
115       gdb_assert_not_reached ("unknown event location type");
116     }
117
118   return dst;
119 }
120
121 /* A cleanup function for struct event_location.  */
122
123 static void
124 delete_event_location_cleanup (void *data)
125 {
126   struct event_location *location = (struct event_location *) data;
127
128   delete_event_location (location);
129 }
130
131 /* See description in location.h.  */
132
133 struct cleanup *
134 make_cleanup_delete_event_location (struct event_location *location)
135 {
136   return make_cleanup (delete_event_location_cleanup, location);
137 }
138
139 /* See description in location.h.  */
140
141 void
142 delete_event_location (struct event_location *location)
143 {
144   if (location != NULL)
145     {
146       xfree (EL_STRING (location));
147
148       switch (EL_TYPE (location))
149         {
150         case LINESPEC_LOCATION:
151           xfree (EL_LINESPEC (location));
152           break;
153
154         default:
155           gdb_assert_not_reached ("unknown event location type");
156         }
157
158       xfree (location);
159     }
160 }
161
162 /* See description in location.h.  */
163
164 const char *
165 event_location_to_string (struct event_location *location)
166 {
167   if (EL_STRING (location) == NULL)
168     {
169       switch (EL_TYPE (location))
170         {
171         case LINESPEC_LOCATION:
172           if (EL_LINESPEC (location) != NULL)
173             EL_STRING (location) = xstrdup (EL_LINESPEC (location));
174           break;
175
176         default:
177           gdb_assert_not_reached ("unknown event location type");
178         }
179     }
180
181   return EL_STRING (location);
182 }
183
184 /* See description in location.h.  */
185
186 struct event_location *
187 string_to_event_location (char **stringp,
188                           const struct language_defn *language)
189 {
190   struct event_location *location;
191
192   location = new_linespec_location (stringp);
193   return location;
194 }
195
196 /* See description in location.h.  */
197
198 int
199 event_location_empty_p (const struct event_location *location)
200 {
201   switch (EL_TYPE (location))
202     {
203     case LINESPEC_LOCATION:
204       /* Linespecs are never "empty."  (NULL is a valid linespec)  */
205       return 0;
206
207     default:
208       gdb_assert_not_reached ("unknown event location type");
209     }
210 }
211
212 /* See description in location.h.  */
213
214 void
215 set_event_location_string (struct event_location *location,
216                            const char *string)
217 {
218   xfree (EL_STRING (location));
219   EL_STRING (location) = string == NULL ?  NULL : xstrdup (string);
220 }