-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtemplate.h
535 lines (457 loc) · 18.6 KB
/
template.h
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
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
/*ident "@(#)cls4:src/template.h 1.12" */
/*******************************************************************************
C++ source for the C++ Language System, Release 3.0. This product
is a new release of the original cfront developed in the computer
science research center of AT&T Bell Laboratories.
Copyright (c) 1993 UNIX System Laboratories, Inc.
Copyright (c) 1991, 1992 AT&T and UNIX System Laboratories, Inc.
Copyright (c) 1984, 1989, 1990 AT&T. All Rights Reserved.
THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE of AT&T and UNIX System
Laboratories, Inc. The copyright notice above does not evidence
any actual or intended publication of such source code.
*******************************************************************************/
/******************************************************************************
* Copyright (c) 1989 by Object Design, Inc., Burlington, Mass.
* All rights reserved.
*******************************************************************************/
// enum bool { false, true };
extern Pclass current_instantiation;
extern Pfct current_fct_instantiation;
// typedef unsigned char uchar; // sun's types.h: u_char
typedef class templ *Ptempl;
typedef class funct_inst *Pfunct_inst;
typedef class templ_inst *Ptempl_inst;
typedef class basic_inst *Pbase_inst;
typedef class basic_template *Ptempl_base;
typedef class function_template *Pfunt;
typedef class data_template *Pdata;
typedef class templ_state *Ptstate;
typedef class templ_classdef *Ptclass;
typedef class templ_fct *Ptfct;
typedef class Pslot *Pbinding;
typedef class cons *Pcons;
class cons {
/* A Lisp style cons cell to help build lists.
* The parameterized type facility should obviate
* the need for this type-unsafe nonsense. */
public:
void *car;
cons *cdr;
cons(void *pcar, cons *pcdr) {
car = pcar;
cdr = pcdr;
};
};
/*****************************************************************************
* *
* The class template_compilation holds the state, and the associated methods *
* used during template compilation. There is exactly one instance of the *
* type, it is mainly a device used to enforce modularity. In reality, it *
* would never need to be instantiated since all it's members are static. *
* However, since the type::mem for a reference is not supported as *
* yet(cfront 1.2), we need an instantiation to get to the members via *
* pointer syntax instead. *
* *
* ***** should change to pure static class ***** *
* *
* A templ_compilation holds the state relevant to the syntax analysis of a *
* class or member function template definition. *
* *
*****************************************************************************/
/*****************************************************************************
* will merge class and function handling by having owner be a basic template *
* pointer -- first, let's get functions up and running. then do it right *
*****************************************************************************/
class templ_state {
/* save relevant information when parsing friend
* template within a class: currently, only instance
* where a nested template can occur */
public:
templ_state(); // save
~templ_state(); // restore
private:
Plist param_end;
Plist params;
Pcons templ_refs;
Pcons friend_templ_refs;
Pcons last_cons;
Pcons last_friend_cons;
Ptempl owner;
};
class templ_compilation {
/* A templ_compilation holds the state relevant to the syntax
* analysis of a class or member function template definition. *
* There is exactly one instance of the type. It mainly serves
* as a device used to enforce modularity. */
public:
static Plist param_end; // make append easier
static Ptempl list; // list of class templates for compilation
static Pfunt f_list; // list of function templates for compilation
static Pfunt f_owner; // template when compiling a function
static Ptempl owner; // template when compiling a member function
static Ptempl_base parsed_template; // template immediately parsed
static Plist params; // list of parameters to the template
static Pexpr actuals; // list of actuals for explicit class template
static Ptable templates; // templates defined during compilation
static bool in_progress;
static Ptstate save_templ;
/* instantiation parameter parsing in progress. Used in the lexer
* to ensure that name string are consed in the heap, rather than
* being retained as pointers into the lex buffer. */
static int parameters_in_progress;
static bool formals_in_progress;
// the list of templates referenced by the top level definition being compiled.
static Pcons templ_refs;
static Pcons friend_templ_refs;
static Pcons last_cons;
static Pcons last_friend_cons;
void start(); // initialize templ_compilation state
void end(Pname class_name);
void end_of_compilation(); // Done with compilation, instantiate bodies
Pname forward_declaration(Pname class_name);
void introduce_class_templ(Pname cnamep);
void introduce_funct_templ(Pname fnamep);
void append_ref(Ptempl_inst ref); // add to templ_refs
void append_friend_ref(Ptempl_inst ref); // add to friend_templ_refs
void instantiate_ref_templ(); // instantiate templ_refs
void clear_ref_templ(); // zero-out templ_refs
void clear_friend_ref_templ(); // zero-out friend_templ_refs
void collect(TOK parm_type, Pname namep); // collect type parameter
void collect(Pname); // collect expression parameter
void append_parameter(Pname); // place them in params
void enter_parameters();
int get_formals_count(); // how many formals
Pname check_tname(Pname p);
bool current_template(Pname p, Pexpr actuals);
bool friend_template(Pexpr actuals);
Ptempl is_template(Pname);
Ptempl is_template(char *);
Pfunt is_template(char *, TOK);
};
/*
* The canonical template_compilation instance.
* templ_compilation exists as a class simply to provide
* a code and data packaging mechanism.
* There is exactly one generated instance of it.
*/
extern templ_compilation *templp;
// should actually be static member functions of templ_compilation
Pname parametrized_typename(Pname p, Pexpr actuals, bit = 0);
Pbase parametrized_basetype(Pname p, Pexpr actuals);
void check_formals_for_dups(Plist formals);
void check_funct_formals(Plist formals, Pname namep);
class basic_template {
/* the basis for class and member function templates */
friend class templ_compilation;
friend void display_templ_refs(basic_template *);
friend void handle_bound_friend(Ptempl_base, Pname);
protected:
Plist formals; // The formal arguments to the template
Pcons templ_refs; // The templates referenced by this template
/* Use these state variables to set up the correct state for error processing.
* They are used by the "error" routines for statement numbers. */
Pname Cdcl;
Pstmt Cstmt;
// used to detect loops during instantiation; a count greater than two is
// indicative of a non-terminating instantiation sequence
int open_instantiations;
int extrapolated; // extrapolated friend declaration
// ensure that use of formals is consistent across, class, member and
// forward declarations
void check_formals(Plist formals);
public:
virtual void dummy(); // for optimal vtbl laydown
virtual int has_friend(Pname) = 0;
Plist get_formals() {
return formals;
}
int get_formals_count(); // should probably define a member
bool is_extrapolated() {
return extrapolated ? true : false;
}
};
class templ : public basic_template {
/* the template class representation */
friend class templ_inst;
friend class function_template;
friend class data_template;
friend class classdef;
private:
Ptempl_inst insts; // template instantiations
Pbase basep; // template COBJ basetype
Pfunt fns; // member function declarations
Pfunt fns_end;
Pdata data; // static data member declarations
Pdata data_end;
public:
Ptempl_inst get_match(Pexpr, Ptempl_inst, bool);
bool check_actual_args(Pexpr);
Ptempl next; // connects all the class templates in the comp
Pname namep; // the TNAME for the template class
bool defined; // actual definition seen
Pname members; // note the members to catch redefinition errors
Ptempl_inst get_inst(Pexpr, Ptempl_inst = 0);
templ(Plist, Pname);
void resolve_forward_decl(Plist, Pclass);
void instantiate_forward_decl();
Pbase basetype() {
return basep;
} // uninstantiated base type
Pbase inst_basetype(Pexpr actuals); // specific instantiation basetype
Pclass classtype() {
return Pclass(basep->b_name->tp);
}
Pname type_name(Pexpr actuals);
Pfunt collect_function_member(Pname);
Pdata collect_data_member(Pname);
bool instantiate_bodies();
int has_friend(Pname);
};
// Member function templates
class function_template : public basic_template {
/* SBL: go through these */
friend Pbinding is_ftempl_match(Pexpr, Pfunt);
friend Pname has_templ_instance(Pname, Pexpr, bit);
friend class templ_compilation;
friend class templ;
friend class templ_inst;
friend class funct_inst;
friend class basic_inst;
friend class templ_fct;
Pname fn; // The name of the member function
Pfunt next; // connects the list of functions
Pfunt gen_list; // connects overloaded instances
public:
Pfunct_inst insts; // instantiations of the template
function_template(templ &, Plist, Pname); // member functions
function_template(Plist, Pname); // function templates
Pname func_name() {
return fn;
}
void instantiate_forward_decl();
Pfunct_inst get_match(Pexpr, Pfunct_inst, bool);
Pfunct_inst get_inst(Pexpr, Pfunct_inst = 0);
int has_friend(Pname);
};
class data_template : public basic_template { // explicitly initialized static data members
friend class templ;
friend class basic_inst;
friend class templ_inst;
Pname dat_mem;
Pdata next;
public:
data_template(templ &, Plist, Pname);
int has_friend(Pname); // need override pure virtual
};
// Global state variables that must be saved around an instantiation. The
// saving of state was required in the implementstion that interspersed decl
// processing and instantiation, rather than the current strategy, which only
// forces instantiations at the top level outside of any dcl-processing
// context. It is retained in case we ever go back to the "interspersed" style
// of instantiation.
class state {
public:
Pname Cdcl; // the global variables used by the error routines
Pstmt Cstmt;
Pname dcl_list; // Holds the list of typedef names that are hidden
Loc curloc;
int curr_file;
Pexpr curr_expr;
Pin curr_icall;
Pstmt curr_loop;
Pblock curr_block;
Pstmt curr_switch;
int bound;
int inline_restr;
Loc last_line;
state(){}; // prevent used before set warnings.
void save();
void init();
void restore();
};
class pointer_hash;
class tree_copy_info;
// A template starts out being uninstantiated, and is class_instantiated when
// there is a refrence to it with actual arguments. It is body_instantiated at
// the end of compilation, when all its function members are instantiated.
enum inst_status {
uninstantiated,
function_instantiated,
data_instantiated,
class_instantiated,
body_instantiated
};
// templ_inst captures the arguments used in the instantiation of a template.
// These instantiations are rooted in the templ object.
class basic_inst {
/* SBL: go through these */
friend class template_instantiation;
friend class templ;
friend class function_template;
friend class templ_classdef;
friend Pcons make_ref_copy(pointer_hash &, tree_copy_info &, Pcons);
public:
Pname get_tname() {
return tname;
}
Pname get_namep() {
return namep;
}
void print_error_loc(int = 0); // Wants to be a static function
virtual void dummy(); // for optimal vtbl laydown
virtual void print_pretty_name() = 0; // for nice error reporting
virtual char *mangled_name(char *) = 0; // mangle template class/function names
Pexpr actuals; // instantiation arguments, chained using ELIST
// as an expression "cons" node, e1 is the car
// and e2 the cdr. The car points to a name node.
Plist inst_formals; // the instantiation's copy of the formals
static Pbase_inst head; // head of list of active instantiations.
protected:
TOK isa; // for the moment: CLASS,FCT
Pname tname; // name of instantiation
Pname namep; // version of name in ktbl (class) or gtbl(funct)
state context; // the context of this instantiation
Plist hidden_globals; // list of globals hidden during instantiation
// Plist inst_formals; // the instantiation's copy of the formals
inst_status status;
Pbase_inst next_active; // list of currently active instantiations.
char *instantiation_string();
// The class correspondence table. This table is initialized
// when the class definition is instantiated. Subsequently, it is used to
// initial member correspondence tables before copy process is initiated.
pointer_hash *corr;
Pcons ref_copy(pointer_hash &, tree_copy_info &, Pcons);
// save and restore state around the template instantiation
void save_state(Pname p);
void restore_state();
void expose_parameter_names();
void hide_parameter_names();
TOK isA() {
return isa;
}
};
struct Pslot {
Pname param;
Ptype typ;
};
class funct_inst : public basic_inst {
friend class template_instantiation;
friend class function_template;
friend class templ_fct;
private:
Pfunct_inst next; // list of template instantiations
Pfunct_inst tfct_copy(Pcons &, bool);
void bind_formals();
public:
funct_inst(Pexpr act, Pfunt owner);
void instantiate(bool reinstantiate = false);
void print_pretty_name(); // virtual
char *mangled_name(char *); // virtual
bool actuals_match(Pexpr);
Pfunt def; // template definition; this is an instantiation.
bool refp; // notes template references during a C++ definition
bool friend_refp; // notes template references during a C++ definition
Pbinding binding; // actual types binding to formals
bool f_copy_hook(Pnode &);
};
class templ_inst : public basic_inst {
friend class template_instantiation;
friend class templ;
friend class classdef;
friend class templ_classdef;
friend Pcons make_ref_copy(pointer_hash &, tree_copy_info &, Pcons);
private:
Ptempl_inst next; // linked list of template instantiations
Ptempl_inst forward; // this instantiation same as `forward'
public:
templ_inst(Pexpr act, Ptempl owner);
templ_inst(Pexpr act, Ptempl owner, TOK csu);
bool actuals_match(Pexpr check_actuals); /* merge this and function's */
void instantiate_match(Ptempl_inst match);
void kludge_copy(Pbase source_base);
// create a copy of the class type subtree preparatory to the ensuing
// instantiation. Return a non-zero value, only if there was no need to
// create a copy, ie. an identical instantiation already existed.
Ptempl_inst class_copy(Pcons &templ_refs, bool recopy);
// Used to collect references to this template by a definition
Ptempl_inst note_ref();
public:
Ptempl def; // The template definition, for which this is an
// instantiation.
bool refp; // flag to note template references during a C++
// definition
bool friend_refp; // flag to note template references during a C++
void explicit_inst();
// Bind the formals before an instantiation
void bind_formals();
Ptempl_inst canonical_instantiation() {
return (forward ? forward : this);
}
// get the class associated with this instantiation
Pclass get_class() {
return Pclass(Pbase(tname->tp)->b_name->tp);
}
Ptempl_inst instantiate(bool reinstantiate = false);
void print_pretty_name(); // virtual
char *mangled_name(char *buffer); // virtual
// The uninstantiated basetype
Pbase def_basetype() {
return def->basep;
};
// A general way of determining whether two template instantiations are
// the same
bool same(Ptempl_inst t);
bool copy_hook(Pnode &);
// return a copy of the function tree starting with it's name
Pname function_copy(Pfunt, Pcons &);
Pname data_copy(Pdata, Pcons &);
// special check for instantiations used in qualifiers for template function
// member declarations.
bool check_qualifier(Plist formals);
Pname get_parameter(char *s);
};
// Experimental debugging toggle ???
extern int zdebug;
// The class node used for template classes.
// Rep invariant:
// class_base == UNINSTANTIATED ||
// class_base == INSTANTIATED
class templ_classdef : public classdef {
public:
// a pointer to the instantiation; the instantiation
// also points back to it via tname->cobj->name->class
Ptempl_inst inst;
templ_classdef(Ptempl_inst i);
templ_classdef(Ptempl_inst i, TOK csu);
Pname unparametrized_tname() {
return inst->def->namep;
}
};
class templ_fct : public fct {
public:
Pfunct_inst inst; // pointer to the instantiation
templ_fct(Pfunct_inst i);
Pname unparametrized_tname() {
return inst->def->fn;
}
void *operator new(size_t);
void operator delete(void *, size_t);
static Ptfct ptfct_free;
};
// Safe accessor functions for navigating through COBJ base classes
extern Templ_type get_class_base(Pbase b);
extern Ptclass get_template_class(Pbase b);
extern Ptempl_inst get_templ_inst(Pbase b);
// functions and data structures needed for directed instantiation
#include "Block.h"
Blockdeclare(Pchar);
extern Block(Pchar) instfct;
extern int noinst;
extern Block(Pchar) instdata;
extern int nodatainst;
extern bit tempdcl;
extern bit mk_zero_init_flag;
extern int first_file;
extern bit all_flag, alltc_flag, data_flag, ft_flag, none_flag;
extern void set_flags();
extern Pname righttname;