|
|
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.