1 /* Marshalling and unmarshalling of C++-specific types.
2    Copyright (C) 2014-2021 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #ifndef CC1_PLUGIN_MARSHALL_CXX_HH
21 #define CC1_PLUGIN_MARSHALL_CXX_HH
22 
23 #include "marshall.hh"
24 #include "gcc-cp-interface.h"
25 
26 namespace cc1_plugin
27 {
28   status
unmarshall(connection * conn,enum gcc_cp_symbol_kind * result)29   unmarshall (connection *conn, enum gcc_cp_symbol_kind *result)
30   {
31     protocol_int p;
32     if (!unmarshall_intlike (conn, &p))
33       return FAIL;
34     *result = (enum gcc_cp_symbol_kind) p;
35     return OK;
36   }
37 
38   status
unmarshall(connection * conn,enum gcc_cp_oracle_request * result)39   unmarshall (connection *conn, enum gcc_cp_oracle_request *result)
40   {
41     protocol_int p;
42     if (!unmarshall_intlike (conn, &p))
43       return FAIL;
44     *result = (enum gcc_cp_oracle_request) p;
45     return OK;
46   }
47 
48   status
unmarshall(connection * conn,enum gcc_cp_qualifiers * result)49   unmarshall (connection *conn, enum gcc_cp_qualifiers *result)
50   {
51     protocol_int p;
52     if (!unmarshall_intlike (conn, &p))
53       return FAIL;
54     *result = (enum gcc_cp_qualifiers) p;
55     return OK;
56   }
57 
58   status
unmarshall(connection * conn,enum gcc_cp_ref_qualifiers * result)59   unmarshall (connection *conn, enum gcc_cp_ref_qualifiers *result)
60   {
61     protocol_int p;
62     if (!unmarshall_intlike (conn, &p))
63       return FAIL;
64     *result = (enum gcc_cp_ref_qualifiers) p;
65     return OK;
66   }
67 
68   // Send a gcc_vbase_array marker followed by the array.
69   status
marshall(connection * conn,const gcc_vbase_array * a)70   marshall (connection *conn, const gcc_vbase_array *a)
71   {
72     size_t len;
73 
74     if (a)
75       len = a->n_elements;
76     else
77       len = (size_t)-1;
78 
79     if (!marshall_array_start (conn, 'v', len))
80       return FAIL;
81 
82     if (!a)
83       return OK;
84 
85     if (!marshall_array_elmts (conn, len * sizeof (a->elements[0]),
86 			       a->elements))
87       return FAIL;
88 
89     return marshall_array_elmts (conn, len * sizeof (a->flags[0]),
90 				 a->flags);
91   }
92 
93   // Read a gcc_vbase_array marker, followed by a gcc_vbase_array.  The
94   // resulting array must be freed by the caller, using 'delete[]' on
95   // elements and virtualp, and 'delete' on the array object itself.
96   status
unmarshall(connection * conn,struct gcc_vbase_array ** result)97   unmarshall (connection *conn, struct gcc_vbase_array **result)
98   {
99     size_t len;
100 
101     if (!unmarshall_array_start (conn, 'v', &len))
102       return FAIL;
103 
104     if (len == (size_t)-1)
105       {
106 	*result = NULL;
107 	return OK;
108       }
109 
110     struct gcc_vbase_array *gva = new gcc_vbase_array;
111 
112     gva->n_elements = len;
113     gva->elements = new gcc_type[len];
114 
115     if (!unmarshall_array_elmts (conn,
116 				 len * sizeof (gva->elements[0]),
117 				 gva->elements))
118       {
119 	delete[] gva->elements;
120 	delete gva;
121 	return FAIL;
122       }
123 
124     gva->flags = new enum gcc_cp_symbol_kind[len];
125 
126     if (!unmarshall_array_elmts (conn,
127 				 len * sizeof (gva->flags[0]),
128 				 gva->flags))
129       {
130 	delete[] gva->flags;
131 	delete[] gva->elements;
132 	delete gva;
133 	return FAIL;
134       }
135 
136     *result = gva;
137     return OK;
138   }
139 
140   // Send a gcc_cp_template_args marker followed by the array.
141   status
marshall(connection * conn,const gcc_cp_template_args * a)142   marshall (connection *conn, const gcc_cp_template_args *a)
143   {
144     size_t len;
145 
146     if (a)
147       len = a->n_elements;
148     else
149       len = (size_t)-1;
150 
151     if (!marshall_array_start (conn, 't', len))
152       return FAIL;
153 
154     if (!a)
155       return OK;
156 
157     if (!marshall_array_elmts (conn, len * sizeof (a->kinds[0]),
158 			       a->kinds))
159       return FAIL;
160 
161     return marshall_array_elmts (conn, len * sizeof (a->elements[0]),
162 				 a->elements);
163   }
164 
165   // Read a gcc_vbase_array marker, followed by a gcc_vbase_array.  The
166   // resulting array must be freed by the caller, using 'delete[]' on
167   // elements and virtualp, and 'delete' on the array object itself.
168   status
unmarshall(connection * conn,struct gcc_cp_template_args ** result)169   unmarshall (connection *conn, struct gcc_cp_template_args **result)
170   {
171     size_t len;
172 
173     if (!unmarshall_array_start (conn, 't', &len))
174       return FAIL;
175 
176     if (len == (size_t)-1)
177       {
178 	*result = NULL;
179 	return OK;
180       }
181 
182     struct gcc_cp_template_args *gva = new gcc_cp_template_args;
183 
184     gva->n_elements = len;
185     gva->kinds = new char[len];
186 
187     if (!unmarshall_array_elmts (conn,
188 				 len * sizeof (gva->kinds[0]),
189 				 gva->kinds))
190       {
191 	delete[] gva->kinds;
192 	delete gva;
193 	return FAIL;
194       }
195 
196     gva->elements = new gcc_cp_template_arg[len];
197 
198     if (!unmarshall_array_elmts (conn,
199 				 len * sizeof (gva->elements[0]),
200 				 gva->elements))
201       {
202 	delete[] gva->elements;
203 	delete[] gva->kinds;
204 	delete gva;
205 	return FAIL;
206       }
207 
208     *result = gva;
209     return OK;
210   }
211 
212   // Send a gcc_cp_function_args marker followed by the array.
213   status
marshall(connection * conn,const gcc_cp_function_args * a)214   marshall (connection *conn, const gcc_cp_function_args *a)
215   {
216     size_t len;
217 
218     if (a)
219       len = a->n_elements;
220     else
221       len = (size_t)-1;
222 
223     if (!marshall_array_start (conn, 'd', len))
224       return FAIL;
225 
226     if (!a)
227       return OK;
228 
229     return marshall_array_elmts (conn, len * sizeof (a->elements[0]),
230 				 a->elements);
231   }
232 
233   // Read a gcc_cp_function_args marker, followed by a
234   // gcc_cp_function_args.  The resulting array must be freed
235   // by the caller, using 'delete[]' on elements and virtualp, and
236   // 'delete' on the array object itself.
237   status
unmarshall(connection * conn,struct gcc_cp_function_args ** result)238   unmarshall (connection *conn, struct gcc_cp_function_args **result)
239   {
240     size_t len;
241 
242     if (!unmarshall_array_start (conn, 'd', &len))
243       return FAIL;
244 
245     if (len == (size_t)-1)
246       {
247 	*result = NULL;
248 	return OK;
249       }
250 
251     struct gcc_cp_function_args *gva = new gcc_cp_function_args;
252 
253     gva->n_elements = len;
254     gva->elements = new gcc_expr[len];
255 
256     if (!unmarshall_array_elmts (conn,
257 				 len * sizeof (gva->elements[0]),
258 				 gva->elements))
259       {
260 	delete[] gva->elements;
261 	delete gva;
262 	return FAIL;
263       }
264 
265     *result = gva;
266 
267     return OK;
268   }
269 }
270 
271 #endif // CC1_PLUGIN_MARSHALL_CP_HH
272