|
|
1.1 root 1: /* -*- Mode:C++ -*- */
2: /*
3: $Source: /usr3/lang/benson/work/stripped_cfront/RCS/template.h,v $ $RCSfile: template.h,v $
4: $Revision: 1.4 $ $Date: 90/04/02 11:31:35 $
5: $Author: sam $ $Locker: $
6: $State: Exp $
7: */
8: /*
9: $Header: /usr3/lang/benson/work/stripped_cfront/RCS/template.h,v 1.4 90/04/02 11:31:35 sam Exp $
10:
11: Copyright 1989 by Object Design, Inc., Burlington, Mass.
12: All rights reserved.
13:
14: */
15:
16:
17: /*****************************************************************************
18: * *
19: * This file contains types pertinent to the implementation of the *
20: * parametrized type facility. *
21: * *
22: *****************************************************************************/
23:
24: enum bool { true = 1, false = 0 } ;
25:
26: typedef class templ *Ptempl ;
27:
28: typedef class templ_inst *Ptempl_inst ;
29:
30: typedef class function_template *Pfunt ;
31:
32: typedef class templ_classdef *Ptclass ;
33:
34: typedef class tree_template *Ptreet ;
35:
36:
37: // A Lisp style cons cell to help build lists. The parametrized type facility,
38: // should obviate the need for this type-unsafe nonsense.
39: class cons {
40: public:
41: void *car ;
42: cons *cdr ;
43: cons (void *pcar, cons *pcdr) { car = pcar ; cdr = pcdr ; } ;
44: } ;
45:
46: typedef cons *Pcons ;
47:
48:
49:
50: /*****************************************************************************
51: * *
52: * The class template_compilation holds the state, and the associated methods *
53: * used during template compilation. There is exactly one instance of the *
54: * type, it is mainly a device used to enforce modularity. In reality, it *
55: * would never need to be instantiated since all it's members are static. *
56: * However, since the type::mem for of reference is not supported as *
57: * yet(cfront 1.2), we need an instantiation to get to the members via *
58: * pointer syntax instead. *
59: * *
60: * A templ_compilation holds the state relevant to the syntax analysis of a *
61: * class or member function template definition. *
62: * *
63: *****************************************************************************/
64:
65: class templ_compilation {
66: static Plist param_end, // make append easier
67: param_tn ; // The type names introduced by the parameters
68:
69: public:
70: static Ptempl list ; // The list of templates for the compilation
71: static Plist params ; // The list of parameters to the template
72: static Ptempl owner ; // The template when compiling a member
73: // function.
74: static table *templates ; // The templates defined during this compilation
75:
76: static Ptreet tree_templates; // The list of tree templates
77:
78: static bool in_progress; // a template compilation is in progress
79: // instantiation parameter parsing in progress. Used in the lexer to ensure
80: // that name string are consed in the heap, rather than being retained as
81: // pointers into the lex buffer.
82: static int parameters_in_progress ;
83:
84: // the list of templates referenced by the top level definition being compiled.
85: static Pcons templ_refs ;
86: static Pcons last_cons ;
87: static Ptype any_type ; // canonical "ANY" type for formal parms
88:
89: // true, if currently compiling an expression tree template
90: static TOK curr_tree_template ;
91:
92: void append_ref(Ptempl_inst ref) ;
93: void start() ;
94:
95: void collect(TOK parm_type, Pname namep) ;
96: void collect(Pname namep) ;
97:
98: void enter_parameters() ;
99: void introduce_class_templ(Pname cnamep) ;
100: void end(Pname class_name) ;
101: Pname forward_declaration(Pname class_name) ;
102: void instantiate_ref_templ() ;
103: void clear_ref_templ() ;
104:
105: Pname check_tname(Pname p) ;
106: bool current_template(Pname p, Pexpr actuals) ;
107: Ptempl is_template(Pname p) ;
108: Ptempl is_template(char *s);
109: void end_of_compilation() ; // Done with compilation, instantiate bodies
110: templ_compilation() ;
111:
112: static Pname tree_parameter(char *s) ; // return true if the name is a tree parameter
113:
114: private:
115: void append_parameter(Pname p) ;
116:
117: } ;
118:
119:
120:
121: // The canonical template_compilation instance. templ_compilation exists as a
122: // class simply to provide a code and data packaging mechanism. There is
123: // exactly one generated instance of it.
124:
125: extern templ_compilation *templp ;
126:
127: // should actually be static member functions of templ_compilation
128: Pname parametrized_typename (Pname p, Pexpr actuals) ;
129: Pbase parametrized_basetype (Pname p, Pexpr actuals) ;
130:
131:
132:
133:
134: // the basis for class and member function templates
135: class basic_template {
136: friend templ_compilation ;
137: protected:
138: Plist formals ; // The formal arguments to the template
139: Pcons templ_refs ; // The templates referenced by this template
140:
141: // check class constraints placed on formals while processing member
142: // function bodies.
143: bool check_constraints(Pexpr actuals) ;
144:
145: // ensure that use of formals is consistent across, class, member and
146: // forward declarations
147: void check_formals(Plist formals) ;
148:
149: public:
150: // used to order template class definitions for instantiations. Not being
151: // used as yet.
152: int definition_number ;
153:
154: // used to generate the definition numbers, used by the above member.
155: static int definition_tick ;
156:
157: Plist get_formals() {return formals ;}
158: } ;
159:
160:
161:
162: // the template for a class
163: class templ : public basic_template {
164: Pbase basep ; // COBJ basetype for the template
165: Ptempl_inst insts ; // instantiations of the template
166: Pfunt fns ; // member function declarations
167: Pfunt fns_end ; // last fun in the above list
168:
169: // Use these state variables to set up the correct state for error
170: // processing. They are used by the "error" routines for statement numbers.
171: Pname Cdcl ;
172: Pstmt Cstmt ;
173:
174: friend templ_inst ;
175: friend function_template ;
176:
177: // used to detect loops during instantiation; a count greater than two is
178: // indicative of a non-terminating instantiation sequence
179: int open_instantiations ;
180:
181: Ptempl_inst get_match(Pexpr actuals,
182: Ptempl_inst exclude,
183: bool match_instantiated_only) ;
184: bool check_actual_args (Pexpr actuals) ;
185:
186: public:
187: Ptempl next ; // connects all the class templates in the comp
188: Pname namep ; // the TNAME for the template class
189: bool defined ; // the actual definition, not just a forward
190: // declaration has been seen.
191:
192: Pname members ; // note the members to catch redefinition errors
193:
194: Ptempl_inst get_inst(Pexpr actuals, Ptempl_inst exclude = 0) ;
195: templ(Plist parms, Pname p) ;
196: void resolve_forward_decl(Plist parms, Pclass c) ;
197: void instantiate_forward_decl() ;
198:
199: // The uninstantiated base type
200: Pbase basetype() {return basep; }
201: // The basetype for a specific instantiation
202: Pbase inst_basetype(Pexpr actuals) ;
203:
204: Pname typename(Pexpr actuals) ;
205:
206: Pfunt collect_function_member(Pname fname) ;
207: bool has_tree_expr_formals() ;
208: bool instantiate_bodies() ;
209: } ;
210:
211:
212:
213: // Member function templates
214: class function_template : public basic_template {
215: Pname fn ; // The name of the member function
216: Pfunt next ; // connects the list of member functions
217:
218: friend templ ;
219: friend templ_inst ;
220:
221: public:
222: function_template (templ & owner, Plist params, Pname n) ;
223: } ;
224:
225:
226:
227: // compiler internal expression templates, used to implement Objectstore constructs
228: class tree_template : public basic_template {
229: TOK kind ; // STATEMENT or EXPRESSION
230: Pnode e ; // the post-syntax tree representing the
231: // expression or statement constituting the
232: // template.
233: Ptreet next ; // the next expression template
234: static int count ; // the number of instantiations
235:
236: public:
237: char *string ; // the name used for template lookup
238: tree_template(TOK tree_kind, char *s, Plist params, Pnode tree,
239: Pcons references) ;
240: static Ptreet get(char *s) ;
241: Pname get_parameter(char *s) ;
242: static void test() ;
243: Pexpr expand(Pexpr actuals) ;
244: } ;
245:
246:
247:
248:
249: // Global state variables that must be saved around an instantiation. The
250: // saving of state was required in the implementstion that interspersed decl
251: // processing and instantiation, rather than the current strategy, which only
252: // forces instantiations at the top level outside of any dcl-processing
253: // context. It is retained in case we ever go back to the "interspersed" style
254: // of instantiation.
255: class state {
256:
257: public:
258: Pname Cdcl ; // the global variables used by the error routines
259: Pstmt Cstmt ;
260: Pname dcl_list ; // Holds the list of typedef names that are hidden
261: Loc curloc ;
262:
263: int curr_file ;
264: Pexpr curr_expr ;
265: Pin curr_icall ;
266: Pstmt curr_loop;
267: Pblock curr_block;
268: Pstmt curr_switch;
269:
270: int bound ;
271: int inline_restr ;
272: Loc last_line ;
273:
274: int no_of_badcall;
275: int no_of_undcl ;
276:
277: Pname badcall ;
278: Pname undcl ;
279:
280: state() {} ; // prevent used before set warnings.
281: void save() ;
282:
283: void init() ;
284: void restore() ;
285: } ;
286:
287:
288: class pointer_hash ;
289: class tree_copy_info ;
290:
291:
292: // A template starts out being uninstantiated, and is class_instantiated when
293: // there is a refrence to it with actual arguments. It is body_instantiated at
294: // the end of compilation, when all its function members are instantiated.
295: enum inst_status { uninstantiated, class_instantiated, body_instantiated };
296:
297: // templ_inst captures the arguments used in the instantiation of a template.
298: // These instantiations are rooted in the templ object.
299: class templ_inst {
300:
301: friend class template_instantiation ;
302:
303: Pname tname ; // The instantiation name, it is the TNAME that
304: // leads up to an actual instantiation of the class
305: Pname namep ; // The version of TNAME in the ktbl
306: Pexpr actuals ; // instantiation arguments, chained using ELIST
307: // as an expression "cons" node, e1 is the car
308: // and e2 the cdr. The car points to a name node.
309: Ptempl_inst next ; // The linked list of instantiations for this
310: // template.
311: Ptempl_inst next_active ; // The list of currently active instantiations.
312: state context ; // the context of this instantiation
313: Ptempl_inst forward ; // This instantiation is the same as the one
314: // pointed to.
315:
316: // Contains the list of global names that are hidden during an
317: // instantiation.
318: Plist hidden_globals ;
319:
320: // The class correspondence table. This table is initialized
321: // when the class definition is instantiated. Subsequently, it is used to
322: // initial member correspondence tables before the copy process is
323: // initiated.
324: pointer_hash *corr ;
325:
326: // the instantiation's copy of the formals
327: Plist inst_formals ;
328:
329: inst_status status ;
330:
331: friend class templ ;
332: friend class templ_classdef ;
333: friend class tree_template ;
334: friend Pcons make_ref_copy(pointer_hash &h, tree_copy_info &info,
335: Pcons old_templ_refs);
336:
337: templ_inst (Pexpr act, Ptempl owner) ;
338: bool actuals_match(Pexpr check_actuals) ;
339: void instantiate_match(Ptempl_inst match) ;
340: void kludge_copy(Pbase source_base) ;
341: // create a copy of the class type subtree preparatory to the ensuing
342: // instantiation. Return a non-zero value, only if there was no need to
343: // create a copy, ie. an identical instantiation already existed.
344: Ptempl_inst class_copy(Pcons &templ_refs, bool recopy) ;
345: Pcons ref_copy(pointer_hash &h, tree_copy_info &info, Pcons old_templ_refs) ;
346:
347: // save and restore state around the template instantiation
348: void save_state(Pname p) ;
349: void restore_state() ;
350:
351: // Used to collect references to this template by a definition
352: Ptempl_inst note_ref() ;
353: char *instantiation_string() ;
354:
355: void expose_parameter_names() ;
356: void hide_parameter_names() ;
357:
358: public:
359: Ptempl def ; // The template definition, for which this is an
360: // instantiation.
361: bool refp ; // A flag used to note template references during
362: // a C++ definition
363: void print_error_loc() ; // Wants to be a static function
364: // Bind the formals before an instantiation
365: void bind_formals() ;
366:
367: Ptempl_inst canonical_instantiation() {
368: return ( forward ? forward : this ) ;
369: }
370:
371: // get the class associated with this instantiation
372: Pclass get_class() { return Pclass(Pbase(tname->tp)->b_name->tp) ;}
373:
374: void instantiate(bool reinstantiate = false) ;
375: static Ptempl_inst head ; // Head of the list of active instantiations.
376: void print_pretty_name() ;
377: char *mangled_name(char *buffer) ;
378: // The uninstantiated basetype
379: Pbase def_basetype() { return def->basep ; } ;
380: // A general way of determining whether two template instantiations are
381: // the same
382: bool same(Ptempl_inst t) ;
383: bool copy_hook(Pnode&) ;
384: // return a copy of the function tree starting with it's name
385: Pname function_copy(Pfunt fnt, Pcons &templ_refs) ;
386:
387: // special check for instantiations used in qualifiers for template function
388: // member declarations.
389: bool check_qualifier(Plist formals) ;
390: Pname get_parameter(char *s) ;
391: } ;
392:
393:
394:
395: // Experimental debugging toggle
396: extern int zdebug ;
397:
398:
399: // The class node used for template classes.
400: // Rep invariant:
401: // class_base == uninstantiated_template_class ||
402: // class_base == instantiated_template_class
403:
404: class templ_classdef : public classdef {
405: public:
406: Ptempl_inst inst ; // a pointer to the instantiation; the
407: // instantiation also points back to it via
408: // the tname ->cobj->name->class path
409: templ_classdef(Ptempl_inst i) ;
410: Pname unparametrized_tname() { return inst->def->namep ; }
411: void instantiate() { inst->instantiate() ; }
412:
413: } ;
414:
415:
416: // Safe accessor functions for navigating through COBJ base classes
417:
418: extern class_type_enum get_class_base (Pbase b) ;
419:
420: extern Ptclass get_template_class (Pbase b) ;
421:
422: extern Ptempl_inst get_templ_inst(Pbase b) ;
423:
424:
425: /*
426: $Log: template.h,v $
427: * Revision 1.4 90/04/02 11:31:35 sam
428: * Made comments current.
429: *
430: * Revision 1.3 90/03/30 18:50:55 sam
431: * 1) Added the introduce_class_templ member function to the templ_compilation
432: * class.
433: * 2) Rationalized the definition of class templ. Made basic_template be it's
434: * base class, instead of type. The latter was the base type, simply so that
435: * it could be stored in a table associating strings with types. Don't have
436: * to resolve to such kludgery in the PT world.
437: * 3) Added the member open_instantiations to detect non-terminating
438: * instantiations
439: *
440: * Revision 1.2 90/03/27 10:16:27 sam
441: * > Merged in revision 1.13 from the main line of development
442: *
443: * Revision 1.1 89/11/20 08:50:58 benson
444: * Initial revision
445: *
446: * Revision 1.11 89/10/16 15:25:00 sam
447: * use pointer_hash rather than Hash as the type of the correspondence table.
448: *
449: * Revision 1.10 89/09/26 16:44:34 sam
450: * fix the forward declaration of template classes
451: *
452: * Revision 1.9 89/09/18 16:37:37 sam
453: * provide for error recovery upon argument mismatch in a template instantiation
454: *
455: *
456: * Revision 1.8 89/09/15 09:31:50 benson
457: * move tree_template.string into the public section.
458: *
459: * Revision 1.7 89/08/30 13:02:12 sam
460: * added support for dealing with __expressions in class formal templates
461: *
462: * Revision 1.6 89/08/28 09:42:05 sam
463: * Support for nested references in internal templates. These nested
464: * references are instantiated whenever an expansion takes place.
465: *
466: * Revision 1.5 89/08/23 10:26:00 sam
467: * support for BS style formal syntax. refer to 1.5 templates.c for more
468: * detailed comments.
469: *
470: * Revision 1.4 89/08/11 14:57:09 sam
471: * implementation of multiple instantiation templates.
472: *
473: * Revision 1.3 89/07/27 11:33:40 sam
474: * the comments in template.c 1.3 describe the modifications.
475: *
476: * Revision 1.2 89/07/07 14:34:11 sam
477: * Added the templ_classdef::unparametrized_type_name() function member, as part
478: * of the base init fix.
479: *
480: * Revision 1.1 89/06/29 09:21:32 benson
481: * Initial revision
482: *
483: * Revision 1.1 89/06/22 16:29:29 sam
484: * Initial revision
485: *
486:
487:
488: end_log
489: */
490:
491:
492:
493: /*
494: $Log $
495:
496:
497: end_log
498: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.