1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
|
/* Template support for compile.
Copyright (C) 2016, 2017 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef COMPILE_CPLUS_TEMPLATES_H
#define COMPILE_CPLUS_TEMPLATES_H
#include "gdbtypes.h"
#include "cp-support.h"
#include <string>
#include <vector>
#include <unordered_map>
#include <memory>
struct symbol;
struct gcc_cp_template_args;
struct template_symbol;
namespace compile
{
class function_template_defn;
class class_template_defn;
class compile_cplus_instance;
/* Types used for tracking template definitions. */
typedef std::unique_ptr<function_template_defn> function_template_defn_up;
typedef std::unique_ptr<class_template_defn> class_template_defn_up;
typedef std::pair<std::string, function_template_defn_up>
function_template_map_item_t;
typedef std::unordered_map<std::string, function_template_defn_up>
function_template_defn_map_t;
typedef std::pair<std::string, class_template_defn_up>
class_template_map_item_t;
typedef std::unordered_map<std::string, class_template_defn_up>
class_template_defn_map_t;
/* A base class holding data common to all template definitions. */
class template_defn
{
public:
/* Return the declaration name of this definition. */
const char *
decl_name () const
{
return m_decl_name.c_str ();
}
/* Return the compiler plug-in's decl for this definition. */
gcc_decl
decl () const
{
return m_decl;
}
/* Set the compiler plug-in's decl for this definition. */
void
set_decl (gcc_decl decl)
{
m_decl = decl;
}
/* Return the generic string for this template definition. */
const std::string
generic (void) const
{
return m_generic;
}
/* Return the compiler plug-in's abstract type for the IDX'th
template parameter. */
gcc_type
parameter_abstract_type (unsigned int idx) const
{
return m_abstract_types[idx];
}
/* Set the IDX'th template parameter's abstract type. */
void
set_parameter_abstract_type (unsigned int idx, gcc_type type)
{
m_abstract_types[idx] = type;
}
/* Has this template already been defined in the compiler plug-in? */
bool
defined (void) const
{
return m_defined;
}
/* Mark this definition as defined in the compiler plug-in. */
void
set_defined (bool val)
{
m_defined = val;
}
/* Return the ARG_NUM'th template parameter's default value
or NULL if none was set (or known). */
struct symbol *
default_argument (unsigned int arg_num) const
{
return m_default_arguments[arg_num];
}
/* Record the value of the ARG_NUM'th template parameter. */
void
set_default_argument (unsigned int arg_num, struct symbol *value)
{
m_default_arguments[arg_num] = value;
}
protected:
/* Protected constructor so that no one instantiates this
type directly.
DECL_NAME is the declaration name of this template, i.e., it's
name with no template parameters. GENERIC is the computed generic
template definition. N_PARAMETERS specifies how many template
parameters this template has. */
template_defn (std::string decl_name, std::string generic,
unsigned int n_parameters)
: m_decl_name (decl_name), m_generic (generic),
m_abstract_types (n_parameters), m_decl (0),
m_default_arguments (n_parameters), m_defined (false)
{
}
private:
/* The declaration name of the template, excluding any
parameters. */
std::string m_decl_name;
/* A string representation of the generic template definition. */
std::string m_generic;
/* The abstract template parameter types. */
std::vector<gcc_type> m_abstract_types;
/* The decl associated with this template definition. */
gcc_decl m_decl;
/* A list of default values for the parameters of this template. */
std::vector<struct symbol *> m_default_arguments;
/* Has this template already been defined? This is a necessary evil
since we have to traverse over all hash table entries. */
bool m_defined;
};
/* A function template definition. */
class function_template_defn
: public template_defn
{
public:
/* Construct a new function template definition with the generic
string representation GENERIC and demangle INFO, based on the
concrete instance given by template symbol TSYMBOL.
If this definition is a method template, PARENT_TYPE is the type
of the closing class and FIDX and MIDX are the fieldlist and
method indices, respectively, which describe this method.
If this definition is not a method template, PARENT_TYPE is NULL
and FIDX/MIDX are both -1. */
function_template_defn (std::string generic,
std::unique_ptr<demangle_parse_info> info,
const struct template_symbol *tsymbol,
struct type *parent_type, int fidx, int midx);
/* Return the demangle information for this template. */
const demangle_parse_info *demangle_info (void) const
{
return m_demangle_info.get ();
}
/* Return the concrete instance used to define this template. */
const struct template_symbol *template_symbol (void) const
{
return m_tsymbol;
}
/* For method templates, return the type of the enclosing parent type,
or NULL for non-method templates. */
struct type *parent_type (void) const
{
return m_parent_type;
}
/* For method templates, return the field list index in PARENT_TYPE
which describes this method. Return -1 otherwise. */
int fidx (void) const
{
return m_fidx;
}
/* For method templates, return the index of this method into the
field list (given by fidx()). Return -1 otherwise. */
int midx (void) const
{
return m_midx;
}
private:
/* The template symbol used to create this template definition.
NOTE: Any given template_defn could be associated with any number
of template instances in the program.
This field is not const since we will be lazily computing template
parameter indices for the function's argument and return types. */
const struct template_symbol *m_tsymbol;
/* The parent type or NULL if this does not represent a method. */
struct type *m_parent_type;
/* The fieldlist and method indices for the method or -1 if this template
definition does not represent a method. */
int m_fidx;
int m_midx;
/* Demangle tree for the template defining this generic. */
std::unique_ptr<demangle_parse_info> m_demangle_info;
};
/* A class template definition. */
class class_template_defn
: public template_defn
{
public:
/* A unary function to delete map items. */
static void destroy (class_template_map_item_t p);
/* Construct a new class template definition with the generic
string representation GENERIC based on the concrete instance
TYPE. */
class_template_defn (std::string decl_name, std::string generic,
struct type *type)
: template_defn (decl_name, generic, TYPE_N_TEMPLATE_ARGUMENTS (type)),
m_type (type)
{
}
/* Return concrete instance that this template definition was
based on. */
struct type *type (void) const
{
return m_type;
}
private:
/* The type used to create this template definition.
NOTE: Any given template_defn could be associated with any number
of template instances in the program. */
struct type *m_type;
};
/* Loop over SYMBOLS, defining any generic template definitions for
any template symbols in the list. */
void define_templates (compile_cplus_instance *instance,
VEC (block_symbol_d) *symbols);
/* Scan TYPE for any new function templates.
Does not actually emit definitions for any new templates until
emit_function_template_decls is called. */
void scan_type_for_function_templates (compile_cplus_instance *instance,
struct type *type);
};
#endif /* COMPILE_CPLUS_TEMPLATES_H */
|