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