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

source code of libcc1/marshall-cp.hh