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