|
|
1.1 ! root 1: /* Handle parameterized types (templates) for GNU C++. ! 2: Copyright (C) 1992, 1993 Free Software Foundation, Inc. ! 3: Written by Ken Raeburn ([email protected]) while at Watchmaker Computing. ! 4: ! 5: This file is part of GNU CC. ! 6: ! 7: GNU CC is free software; you can redistribute it and/or modify ! 8: it under the terms of the GNU General Public License as published by ! 9: the Free Software Foundation; either version 2, or (at your option) ! 10: any later version. ! 11: ! 12: GNU CC is distributed in the hope that it will be useful, ! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: GNU General Public License for more details. ! 16: ! 17: You should have received a copy of the GNU General Public License ! 18: along with GNU CC; see the file COPYING. If not, write to ! 19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 20: ! 21: /* Known bugs or deficiencies include: ! 22: * templates for class static data don't work (methods only) ! 23: * duplicated method templates can crash the compiler ! 24: * interface/impl data is taken from file defining the template ! 25: * all methods must be provided in header files; can't use a source ! 26: file that contains only the method templates and "just win" ! 27: * method templates must be seen before the expansion of the ! 28: class template is done ! 29: */ ! 30: ! 31: #include "config.h" ! 32: #include <stdio.h> ! 33: #include "obstack.h" ! 34: ! 35: #include "tree.h" ! 36: #include "flags.h" ! 37: #include "cp-tree.h" ! 38: #include "cp-decl.h" ! 39: #ifdef OBJCPLUS ! 40: #include "obcp-parse.h" ! 41: #else ! 42: #include "cp-parse.h" ! 43: #endif ! 44: ! 45: extern struct obstack permanent_obstack; ! 46: extern tree grokdeclarator (); ! 47: ! 48: extern int lineno; ! 49: extern char *input_filename; ! 50: struct pending_inline *pending_template_expansions; ! 51: ! 52: int processing_template_decl; ! 53: int processing_template_defn; ! 54: ! 55: #define obstack_chunk_alloc xmalloc ! 56: #define obstack_chunk_free free ! 57: ! 58: static int unify (); ! 59: static void add_pending_template (); ! 60: ! 61: void overload_template_name (), pop_template_decls (); ! 62: ! 63: /* We've got a template header coming up; set obstacks up to save the ! 64: nodes created permanently. (There might be cases with nested templates ! 65: where we don't have to do this, but they aren't implemented, and it ! 66: probably wouldn't be worth the effort.) */ ! 67: void ! 68: begin_template_parm_list () ! 69: { ! 70: pushlevel (0); ! 71: push_obstacks (&permanent_obstack, &permanent_obstack); ! 72: pushlevel (0); ! 73: } ! 74: ! 75: /* Process information from new template parameter NEXT and append it to the ! 76: LIST being built. The rules for use of a template parameter type name ! 77: by later parameters are not well-defined for us just yet. However, the ! 78: only way to avoid having to parse expressions of unknown complexity (and ! 79: with tokens of unknown types) is to disallow it completely. So for now, ! 80: that is what is assumed. */ ! 81: tree ! 82: process_template_parm (list, next) ! 83: tree list, next; ! 84: { ! 85: tree parm; ! 86: tree decl = 0; ! 87: int is_type; ! 88: parm = next; ! 89: my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259); ! 90: is_type = TREE_CODE (TREE_PURPOSE (parm)) == IDENTIFIER_NODE; ! 91: if (!is_type) ! 92: { ! 93: tree tinfo = 0; ! 94: int idx = 0; ! 95: parm = TREE_PURPOSE (parm); ! 96: my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 260); ! 97: parm = TREE_VALUE (parm); ! 98: /* is a const-param */ ! 99: parm = grokdeclarator (TREE_VALUE (next), TREE_PURPOSE (next), ! 100: PARM, 0, NULL_TREE); ! 101: /* A template parameter is not modifiable. */ ! 102: TREE_READONLY (parm) = 1; ! 103: if (TREE_CODE (TREE_TYPE (parm)) == RECORD_TYPE ! 104: || TREE_CODE (TREE_TYPE (parm)) == UNION_TYPE) ! 105: { ! 106: sorry ("aggregate template parameter types"); ! 107: TREE_TYPE (parm) = void_type_node; ! 108: } ! 109: tinfo = make_node (TEMPLATE_CONST_PARM); ! 110: my_friendly_assert (TREE_PERMANENT (tinfo), 260.5); ! 111: if (TREE_PERMANENT (parm) == 0) ! 112: { ! 113: parm = copy_node (parm); ! 114: TREE_PERMANENT (parm) = 1; ! 115: } ! 116: TREE_TYPE (tinfo) = TREE_TYPE (parm); ! 117: decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm)); ! 118: DECL_INITIAL (decl) = tinfo; ! 119: DECL_INITIAL (parm) = tinfo; ! 120: } ! 121: else ! 122: { ! 123: tree t = make_node (TEMPLATE_TYPE_PARM); ! 124: decl = build_lang_decl (TYPE_DECL, TREE_PURPOSE (parm), t); ! 125: TYPE_NAME (t) = decl; ! 126: TREE_VALUE (parm) = t; ! 127: } ! 128: pushdecl (decl); ! 129: return chainon (list, parm); ! 130: } ! 131: ! 132: /* The end of a template parameter list has been reached. Process the ! 133: tree list into a parameter vector, converting each parameter into a more ! 134: useful form. Type parameters are saved as IDENTIFIER_NODEs, and others ! 135: as PARM_DECLs. */ ! 136: ! 137: tree ! 138: end_template_parm_list (parms) ! 139: tree parms; ! 140: { ! 141: int nparms = 0; ! 142: tree saved_parmlist; ! 143: tree parm; ! 144: for (parm = parms; parm; parm = TREE_CHAIN (parm)) ! 145: nparms++; ! 146: saved_parmlist = make_tree_vec (nparms); ! 147: ! 148: for (parm = parms, nparms = 0; parm; parm = TREE_CHAIN (parm), nparms++) ! 149: { ! 150: tree p = parm; ! 151: if (TREE_CODE (p) == TREE_LIST) ! 152: { ! 153: tree t = TREE_VALUE (p); ! 154: TREE_VALUE (p) = NULL_TREE; ! 155: p = TREE_PURPOSE (p); ! 156: my_friendly_assert (TREE_CODE (p) == IDENTIFIER_NODE, 261); ! 157: TEMPLATE_TYPE_SET_INFO (t, saved_parmlist, nparms); ! 158: } ! 159: else ! 160: { ! 161: tree tinfo = DECL_INITIAL (p); ! 162: DECL_INITIAL (p) = NULL_TREE; ! 163: TEMPLATE_CONST_SET_INFO (tinfo, saved_parmlist, nparms); ! 164: } ! 165: TREE_VEC_ELT (saved_parmlist, nparms) = p; ! 166: } ! 167: set_current_level_tags_transparency (1); ! 168: processing_template_decl++; ! 169: return saved_parmlist; ! 170: } ! 171: ! 172: /* end_template_decl is called after a template declaration is seen. ! 173: D1 is template header; D2 is class_head_sans_basetype or a ! 174: TEMPLATE_DECL with its DECL_RESULT field set. */ ! 175: void ! 176: end_template_decl (d1, d2, is_class) ! 177: tree d1, d2, is_class; ! 178: { ! 179: tree decl; ! 180: struct template_info *tmpl; ! 181: ! 182: tmpl = (struct template_info *) obstack_alloc (&permanent_obstack, ! 183: sizeof (struct template_info)); ! 184: tmpl->text = 0; ! 185: tmpl->length = 0; ! 186: tmpl->aggr = is_class; ! 187: ! 188: /* cloned from reinit_parse_for_template */ ! 189: tmpl->filename = input_filename; ! 190: tmpl->lineno = lineno; ! 191: tmpl->parm_vec = d1; /* [eichin:19911015.2306EST] */ ! 192: ! 193: if (d2 == NULL_TREE || d2 == error_mark_node) ! 194: { ! 195: decl = 0; ! 196: goto lose; ! 197: } ! 198: ! 199: if (is_class) ! 200: { ! 201: decl = build_lang_decl (TEMPLATE_DECL, d2, NULL_TREE); ! 202: } ! 203: else ! 204: { ! 205: if (TREE_CODE (d2) == TEMPLATE_DECL) ! 206: decl = d2; ! 207: else ! 208: { ! 209: /* Class destructor templates and operator templates are ! 210: slipping past as non-template nodes. Process them here, since ! 211: I haven't figured out where to catch them earlier. I could ! 212: go do that, but it's a choice between getting that done and ! 213: staying only N months behind schedule. Sorry.... */ ! 214: enum tree_code code; ! 215: my_friendly_assert (TREE_CODE (d2) == CALL_EXPR, 263); ! 216: code = TREE_CODE (TREE_OPERAND (d2, 0)); ! 217: my_friendly_assert (code == BIT_NOT_EXPR ! 218: || code == OP_IDENTIFIER ! 219: || code == SCOPE_REF, 264); ! 220: d2 = grokdeclarator (d2, NULL_TREE, MEMFUNCDEF, 0, NULL_TREE); ! 221: decl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (d2), ! 222: TREE_TYPE (d2)); ! 223: DECL_TEMPLATE_RESULT (decl) = d2; ! 224: DECL_CONTEXT (decl) = DECL_CONTEXT (d2); ! 225: DECL_CLASS_CONTEXT (decl) = DECL_CLASS_CONTEXT (d2); ! 226: DECL_NAME (decl) = DECL_NAME (d2); ! 227: TREE_TYPE (decl) = TREE_TYPE (d2); ! 228: if (interface_unknown && flag_external_templates) ! 229: warn_if_unknown_interface (); ! 230: TREE_PUBLIC (decl) = TREE_PUBLIC (d2) = flag_external_templates && !interface_unknown; ! 231: DECL_EXTERNAL (decl) = (DECL_EXTERNAL (d2) ! 232: && !(DECL_CLASS_CONTEXT (d2) ! 233: && !DECL_THIS_EXTERN (d2))); ! 234: } ! 235: ! 236: /* All routines creating TEMPLATE_DECL nodes should now be using ! 237: build_lang_decl, which will have set this up already. */ ! 238: my_friendly_assert (DECL_LANG_SPECIFIC (decl) != 0, 265); ! 239: ! 240: /* @@ Somewhere, permanent allocation isn't being used. */ ! 241: if (! DECL_TEMPLATE_IS_CLASS (decl) ! 242: && TREE_CODE (DECL_TEMPLATE_RESULT (decl)) == FUNCTION_DECL) ! 243: { ! 244: tree result = DECL_TEMPLATE_RESULT (decl); ! 245: /* Will do nothing if allocation was already permanent. */ ! 246: DECL_ARGUMENTS (result) = copy_to_permanent (DECL_ARGUMENTS (result)); ! 247: } ! 248: ! 249: /* If this is for a method, there's an extra binding level here. */ ! 250: if (! DECL_TEMPLATE_IS_CLASS (decl) ! 251: && DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)) != NULL_TREE) ! 252: { ! 253: /* @@ Find out where this should be getting set! */ ! 254: tree r = DECL_TEMPLATE_RESULT (decl); ! 255: if (DECL_CLASS_CONTEXT (r) == NULL_TREE) ! 256: DECL_CLASS_CONTEXT (r) = DECL_CONTEXT (r); ! 257: } ! 258: } ! 259: DECL_TEMPLATE_INFO (decl) = tmpl; ! 260: DECL_TEMPLATE_PARMS (decl) = d1; ! 261: lose: ! 262: if (decl) ! 263: { ! 264: /* If context of decl is non-null (i.e., method template), add it ! 265: to the appropriate class template, and pop the binding levels. */ ! 266: if (! DECL_TEMPLATE_IS_CLASS (decl) ! 267: && DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)) != NULL_TREE) ! 268: { ! 269: tree ctx = DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)); ! 270: tree tmpl; ! 271: my_friendly_assert (TREE_CODE (ctx) == UNINSTANTIATED_P_TYPE, 266); ! 272: tmpl = UPT_TEMPLATE (ctx); ! 273: DECL_TEMPLATE_MEMBERS (tmpl) = ! 274: perm_tree_cons (DECL_NAME (decl), decl, ! 275: DECL_TEMPLATE_MEMBERS (tmpl)); ! 276: poplevel (0, 0, 0); ! 277: poplevel (0, 0, 0); ! 278: } ! 279: /* Otherwise, go back to top level first, and push the template decl ! 280: again there. */ ! 281: else ! 282: { ! 283: poplevel (0, 0, 0); ! 284: poplevel (0, 0, 0); ! 285: if (TREE_TYPE (decl) ! 286: && IDENTIFIER_GLOBAL_VALUE (DECL_NAME (decl)) != NULL_TREE) ! 287: push_overloaded_decl (decl, 0); ! 288: else ! 289: pushdecl (decl); ! 290: } ! 291: } ! 292: #if 0 /* It happens sometimes, with syntactic or semantic errors. ! 293: ! 294: One specific case: ! 295: template <class A, int X, int Y> class Foo { ... }; ! 296: template <class A, int X, int y> Foo<X,Y>::method (Foo& x) { ... } ! 297: Note the missing "A" in the class containing "method". */ ! 298: my_friendly_assert (global_bindings_p (), 267); ! 299: #else ! 300: while (! global_bindings_p ()) ! 301: poplevel (0, 0, 0); ! 302: #endif ! 303: pop_obstacks (); ! 304: processing_template_decl--; ! 305: (void) get_pending_sizes (); ! 306: } ! 307: ! 308: /* If TYPE is a template parm type, then return its actual type found ! 309: in TVEC. Otherwise, return TYPE. */ ! 310: static tree ! 311: grok_template_type (tvec, type) ! 312: tree tvec, type; ! 313: { ! 314: if (TREE_CODE (type) == TEMPLATE_TYPE_PARM) ! 315: return TREE_VEC_ELT (tvec, TEMPLATE_TYPE_IDX (type)); ! 316: else ! 317: return type; ! 318: } ! 319: ! 320: /* Convert all template arguments to their appropriate types, and return ! 321: a vector containing the resulting values. If any error occurs, return ! 322: error_mark_node. */ ! 323: static tree ! 324: coerce_template_parms (parms, arglist, in_decl) ! 325: tree parms, arglist; ! 326: tree in_decl; ! 327: { ! 328: int nparms, i, lost = 0; ! 329: tree vec; ! 330: ! 331: if (TREE_CODE (arglist) == TREE_VEC) ! 332: nparms = TREE_VEC_LENGTH (arglist); ! 333: else ! 334: nparms = list_length (arglist); ! 335: if (nparms != TREE_VEC_LENGTH (parms)) ! 336: { ! 337: error ("incorrect number of parameters (%d, should be %d)", ! 338: nparms, TREE_VEC_LENGTH (parms)); ! 339: if (in_decl) ! 340: cp_error_at ("in template expansion for decl `%D'", in_decl); ! 341: return error_mark_node; ! 342: } ! 343: ! 344: if (TREE_CODE (arglist) == TREE_VEC) ! 345: vec = copy_node (arglist); ! 346: else ! 347: { ! 348: vec = make_tree_vec (nparms); ! 349: for (i = 0; i < nparms; i++) ! 350: { ! 351: tree arg = arglist; ! 352: arglist = TREE_CHAIN (arglist); ! 353: if (arg == error_mark_node) ! 354: lost++; ! 355: else ! 356: arg = TREE_VALUE (arg); ! 357: TREE_VEC_ELT (vec, i) = arg; ! 358: } ! 359: } ! 360: for (i = 0; i < nparms; i++) ! 361: { ! 362: tree arg = TREE_VEC_ELT (vec, i); ! 363: tree parm = TREE_VEC_ELT (parms, i); ! 364: tree val = 0; ! 365: int is_type, requires_type; ! 366: ! 367: is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't'; ! 368: requires_type = TREE_CODE (parm) == IDENTIFIER_NODE; ! 369: if (is_type != requires_type) ! 370: { ! 371: if (in_decl) ! 372: cp_error_at ("type/value mismatch in template parameter list for `%D'", in_decl); ! 373: lost++; ! 374: TREE_VEC_ELT (vec, i) = error_mark_node; ! 375: continue; ! 376: } ! 377: if (is_type) ! 378: val = groktypename (arg); ! 379: else if (TREE_CODE (arg) == STRING_CST) ! 380: { ! 381: cp_error ("string literal %E is not a valid template argument", arg); ! 382: error ("because it is the address of an object with static linkage"); ! 383: val = error_mark_node; ! 384: } ! 385: else ! 386: { ! 387: TREE_TYPE (parm) = grok_template_type (vec, TREE_TYPE (parm)); ! 388: val = digest_init (TREE_TYPE (parm), arg, (tree *) 0); ! 389: ! 390: if (val == error_mark_node) ! 391: ; ! 392: ! 393: /* 14.2: Other template-arguments must be constant-expressions, ! 394: addresses of objects or functions with external linkage, or of ! 395: static class members. */ ! 396: else if (!TREE_CONSTANT (val)) ! 397: { ! 398: cp_error ("non-const `%E' cannot be used as template argument", ! 399: arg); ! 400: val = error_mark_node; ! 401: } ! 402: else if (TREE_CODE (val) == ADDR_EXPR) ! 403: { ! 404: tree a = TREE_OPERAND (val, 0); ! 405: if ((TREE_CODE (a) == VAR_DECL ! 406: || TREE_CODE (a) == FUNCTION_DECL) ! 407: && !TREE_PUBLIC (a)) ! 408: { ! 409: cp_error ("address of non-extern `%E' cannot be used as template argument", a); ! 410: val = error_mark_node; ! 411: } ! 412: } ! 413: } ! 414: ! 415: if (val == error_mark_node) ! 416: lost++; ! 417: ! 418: TREE_VEC_ELT (vec, i) = val; ! 419: } ! 420: if (lost) ! 421: return error_mark_node; ! 422: return vec; ! 423: } ! 424: ! 425: /* Given class template name and parameter list, produce a user-friendly name ! 426: for the instantiation. */ ! 427: static char * ! 428: mangle_class_name_for_template (name, parms, arglist) ! 429: char *name; ! 430: tree parms, arglist; ! 431: { ! 432: static struct obstack scratch_obstack; ! 433: static char *scratch_firstobj; ! 434: int i, nparms; ! 435: char ibuf[100]; ! 436: ! 437: if (!scratch_firstobj) ! 438: { ! 439: gcc_obstack_init (&scratch_obstack); ! 440: scratch_firstobj = obstack_alloc (&scratch_obstack, 1); ! 441: } ! 442: else ! 443: obstack_free (&scratch_obstack, scratch_firstobj); ! 444: ! 445: #if 0 ! 446: #define buflen sizeof(buf) ! 447: #define check if (bufp >= buf+buflen-1) goto too_long ! 448: #define ccat(c) *bufp++=(c); check ! 449: #define advance bufp+=strlen(bufp); check ! 450: #define cat(s) strncpy(bufp, s, buf+buflen-bufp-1); advance ! 451: #else ! 452: #define check ! 453: #define ccat(c) obstack_1grow (&scratch_obstack, (c)); ! 454: #define advance ! 455: #define cat(s) obstack_grow (&scratch_obstack, (s), strlen (s)) ! 456: #endif ! 457: #define icat(n) sprintf(ibuf,"%d",(n)); cat(ibuf) ! 458: #define xcat(n) sprintf(ibuf,"%ux",n); cat(ibuf) ! 459: ! 460: cat (name); ! 461: ccat ('<'); ! 462: nparms = TREE_VEC_LENGTH (parms); ! 463: my_friendly_assert (nparms == TREE_VEC_LENGTH (arglist), 268); ! 464: for (i = 0; i < nparms; i++) ! 465: { ! 466: tree parm = TREE_VEC_ELT (parms, i), arg = TREE_VEC_ELT (arglist, i); ! 467: ! 468: if (i) ! 469: ccat (','); ! 470: ! 471: if (TREE_CODE (parm) == IDENTIFIER_NODE) ! 472: { ! 473: cat (type_as_string (arg, 0)); ! 474: continue; ! 475: } ! 476: else ! 477: my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269); ! 478: ! 479: if (TREE_CODE (arg) == TREE_LIST) ! 480: { ! 481: /* New list cell was built because old chain link was in ! 482: use. */ ! 483: my_friendly_assert (TREE_PURPOSE (arg) == NULL_TREE, 270); ! 484: arg = TREE_VALUE (arg); ! 485: } ! 486: /* No need to check arglist against parmlist here; we did that ! 487: in coerce_template_parms, called from lookup_template_class. */ ! 488: cat (expr_as_string (arg, 0)); ! 489: } ! 490: { ! 491: char *bufp = obstack_next_free (&scratch_obstack); ! 492: int offset = 0; ! 493: while (bufp[offset - 1] == ' ') ! 494: offset--; ! 495: obstack_blank_fast (&scratch_obstack, offset); ! 496: ! 497: /* B<C<char> >, not B<C<char>> */ ! 498: if (bufp[offset - 1] == '>') ! 499: ccat (' '); ! 500: } ! 501: ccat ('>'); ! 502: ccat ('\0'); ! 503: return (char *) obstack_base (&scratch_obstack); ! 504: ! 505: too_long: ! 506: fatal ("out of (preallocated) string space creating template instantiation name"); ! 507: /* NOTREACHED */ ! 508: return NULL; ! 509: } ! 510: ! 511: /* Given an IDENTIFIER_NODE (type TEMPLATE_DECL) and a chain of ! 512: parameters, find the desired type. ! 513: ! 514: D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments. ! 515: Since ARGLIST is build on the decl_obstack, we must copy it here ! 516: to keep it from being reclaimed when the decl storage is reclaimed. ! 517: ! 518: IN_DECL, if non-NULL, is the template declaration we are trying to ! 519: instantiate. */ ! 520: tree ! 521: lookup_template_class (d1, arglist, in_decl) ! 522: tree d1, arglist; ! 523: tree in_decl; ! 524: { ! 525: tree template, parmlist; ! 526: char *mangled_name; ! 527: tree id; ! 528: ! 529: my_friendly_assert (TREE_CODE (d1) == IDENTIFIER_NODE, 272); ! 530: template = IDENTIFIER_GLOBAL_VALUE (d1); /* XXX */ ! 531: if (! template) ! 532: template = IDENTIFIER_CLASS_VALUE (d1); ! 533: /* With something like `template <class T> class X class X { ... };' ! 534: we could end up with D1 having nothing but an IDENTIFIER_LOCAL_VALUE. ! 535: We don't want to do that, but we have to deal with the situation, so ! 536: let's give them some syntax errors to chew on instead of a crash. */ ! 537: if (! template) ! 538: return error_mark_node; ! 539: if (TREE_CODE (template) != TEMPLATE_DECL) ! 540: { ! 541: cp_error ("non-template type `%T' used as a template", d1); ! 542: if (in_decl) ! 543: cp_error_at ("for template declaration `%D'", in_decl); ! 544: return error_mark_node; ! 545: } ! 546: parmlist = DECL_TEMPLATE_PARMS (template); ! 547: ! 548: arglist = coerce_template_parms (parmlist, arglist, in_decl); ! 549: if (arglist == error_mark_node) ! 550: return error_mark_node; ! 551: if (uses_template_parms (arglist)) ! 552: { ! 553: tree t = make_lang_type (UNINSTANTIATED_P_TYPE); ! 554: tree d; ! 555: id = make_anon_name (); ! 556: d = build_lang_decl (TYPE_DECL, id, t); ! 557: TYPE_NAME (t) = d; ! 558: TYPE_VALUES (t) = build_tree_list (template, arglist); ! 559: pushdecl_top_level (d); ! 560: } ! 561: else ! 562: { ! 563: mangled_name = mangle_class_name_for_template (IDENTIFIER_POINTER (d1), ! 564: parmlist, arglist); ! 565: id = get_identifier (mangled_name); ! 566: } ! 567: if (!IDENTIFIER_TEMPLATE (id)) ! 568: { ! 569: arglist = copy_to_permanent (arglist); ! 570: IDENTIFIER_TEMPLATE (id) = perm_tree_cons (template, arglist, NULL_TREE); ! 571: } ! 572: return id; ! 573: } ! 574: ! 575: void ! 576: push_template_decls (parmlist, arglist, class_level) ! 577: tree parmlist, arglist; ! 578: int class_level; ! 579: { ! 580: int i, nparms; ! 581: ! 582: /* Don't want to push values into global context. */ ! 583: if (!class_level) ! 584: pushlevel (0); ! 585: nparms = TREE_VEC_LENGTH (parmlist); ! 586: ! 587: for (i = 0; i < nparms; i++) ! 588: { ! 589: int requires_type, is_type; ! 590: tree parm = TREE_VEC_ELT (parmlist, i); ! 591: tree arg = TREE_VEC_ELT (arglist, i); ! 592: tree decl = 0; ! 593: ! 594: requires_type = TREE_CODE (parm) == IDENTIFIER_NODE; ! 595: is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't'; ! 596: if (is_type) ! 597: { ! 598: /* add typename to namespace */ ! 599: if (!requires_type) ! 600: { ! 601: error ("template use error: type provided where value needed"); ! 602: continue; ! 603: } ! 604: decl = arg; ! 605: my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 't', 273); ! 606: decl = build_lang_decl (TYPE_DECL, parm, decl); ! 607: } ! 608: else ! 609: { ! 610: /* add const decl to namespace */ ! 611: tree val; ! 612: if (requires_type) ! 613: { ! 614: error ("template use error: value provided where type needed"); ! 615: continue; ! 616: } ! 617: val = digest_init (TREE_TYPE (parm), arg, (tree *) 0); ! 618: if (val != error_mark_node) ! 619: { ! 620: decl = build_decl (VAR_DECL, DECL_NAME (parm), TREE_TYPE (parm)); ! 621: DECL_INITIAL (decl) = val; ! 622: TREE_READONLY (decl) = 1; ! 623: } ! 624: } ! 625: if (decl != 0) ! 626: { ! 627: layout_decl (decl, 0); ! 628: if (class_level) ! 629: pushdecl_class_level (decl); ! 630: else ! 631: pushdecl (decl); ! 632: } ! 633: } ! 634: if (!class_level) ! 635: set_current_level_tags_transparency (1); ! 636: } ! 637: ! 638: void ! 639: pop_template_decls (parmlist, arglist, class_level) ! 640: tree parmlist, arglist; ! 641: int class_level; ! 642: { ! 643: if (!class_level) ! 644: poplevel (0, 0, 0); ! 645: } ! 646: ! 647: /* Should be defined in cp-parse.h. */ ! 648: extern int yychar; ! 649: ! 650: int ! 651: uses_template_parms (t) ! 652: tree t; ! 653: { ! 654: if (!t) ! 655: return 0; ! 656: switch (TREE_CODE (t)) ! 657: { ! 658: case INDIRECT_REF: ! 659: case COMPONENT_REF: ! 660: /* We assume that the object must be instantiated in order to build ! 661: the COMPONENT_REF, so we test only whether the type of the ! 662: COMPONENT_REF uses template parms. */ ! 663: return uses_template_parms (TREE_TYPE (t)); ! 664: ! 665: case IDENTIFIER_NODE: ! 666: if (!IDENTIFIER_TEMPLATE (t)) ! 667: return 0; ! 668: return uses_template_parms (TREE_VALUE (IDENTIFIER_TEMPLATE (t))); ! 669: ! 670: /* aggregates of tree nodes */ ! 671: case TREE_VEC: ! 672: { ! 673: int i = TREE_VEC_LENGTH (t); ! 674: while (i--) ! 675: if (uses_template_parms (TREE_VEC_ELT (t, i))) ! 676: return 1; ! 677: return 0; ! 678: } ! 679: case TREE_LIST: ! 680: if (uses_template_parms (TREE_PURPOSE (t)) ! 681: || uses_template_parms (TREE_VALUE (t))) ! 682: return 1; ! 683: return uses_template_parms (TREE_CHAIN (t)); ! 684: ! 685: /* constructed type nodes */ ! 686: case POINTER_TYPE: ! 687: case REFERENCE_TYPE: ! 688: return uses_template_parms (TREE_TYPE (t)); ! 689: case RECORD_TYPE: ! 690: case UNION_TYPE: ! 691: if (!TYPE_NAME (t)) ! 692: return 0; ! 693: if (!TYPE_IDENTIFIER (t)) ! 694: return 0; ! 695: return uses_template_parms (TYPE_IDENTIFIER (t)); ! 696: case FUNCTION_TYPE: ! 697: if (uses_template_parms (TYPE_ARG_TYPES (t))) ! 698: return 1; ! 699: return uses_template_parms (TREE_TYPE (t)); ! 700: case ARRAY_TYPE: ! 701: if (uses_template_parms (TYPE_DOMAIN (t))) ! 702: return 1; ! 703: return uses_template_parms (TREE_TYPE (t)); ! 704: case OFFSET_TYPE: ! 705: if (uses_template_parms (TYPE_OFFSET_BASETYPE (t))) ! 706: return 1; ! 707: return uses_template_parms (TREE_TYPE (t)); ! 708: case METHOD_TYPE: ! 709: if (uses_template_parms (TYPE_OFFSET_BASETYPE (t))) ! 710: return 1; ! 711: if (uses_template_parms (TYPE_ARG_TYPES (t))) ! 712: return 1; ! 713: return uses_template_parms (TREE_TYPE (t)); ! 714: ! 715: /* decl nodes */ ! 716: case TYPE_DECL: ! 717: return uses_template_parms (DECL_NAME (t)); ! 718: case FUNCTION_DECL: ! 719: if (uses_template_parms (TREE_TYPE (t))) ! 720: return 1; ! 721: /* fall through */ ! 722: case VAR_DECL: ! 723: case PARM_DECL: ! 724: /* ??? What about FIELD_DECLs? */ ! 725: /* The type of a decl can't use template parms if the name of the ! 726: variable doesn't, because it's impossible to resolve them. So ! 727: ignore the type field for now. */ ! 728: if (DECL_CONTEXT (t) && uses_template_parms (DECL_CONTEXT (t))) ! 729: return 1; ! 730: if (uses_template_parms (TREE_TYPE (t))) ! 731: { ! 732: error ("template parms used where they can't be resolved"); ! 733: } ! 734: return 0; ! 735: ! 736: case CALL_EXPR: ! 737: return uses_template_parms (TREE_TYPE (t)); ! 738: case ADDR_EXPR: ! 739: return uses_template_parms (TREE_OPERAND (t, 0)); ! 740: ! 741: /* template parm nodes */ ! 742: case TEMPLATE_TYPE_PARM: ! 743: case TEMPLATE_CONST_PARM: ! 744: return 1; ! 745: ! 746: /* simple type nodes */ ! 747: case INTEGER_TYPE: ! 748: if (uses_template_parms (TYPE_MIN_VALUE (t))) ! 749: return 1; ! 750: return uses_template_parms (TYPE_MAX_VALUE (t)); ! 751: ! 752: case REAL_TYPE: ! 753: case VOID_TYPE: ! 754: case ENUMERAL_TYPE: ! 755: return 0; ! 756: ! 757: /* constants */ ! 758: case INTEGER_CST: ! 759: case REAL_CST: ! 760: case STRING_CST: ! 761: return 0; ! 762: ! 763: case ERROR_MARK: ! 764: /* Non-error_mark_node ERROR_MARKs are bad things. */ ! 765: my_friendly_assert (t == error_mark_node, 274); ! 766: /* NOTREACHED */ ! 767: return 0; ! 768: ! 769: case UNINSTANTIATED_P_TYPE: ! 770: return 1; ! 771: ! 772: default: ! 773: switch (TREE_CODE_CLASS (TREE_CODE (t))) ! 774: { ! 775: case '1': ! 776: case '2': ! 777: case '3': ! 778: case '<': ! 779: { ! 780: int i; ! 781: for (i = tree_code_length[(int) TREE_CODE (t)]; --i >= 0;) ! 782: if (uses_template_parms (TREE_OPERAND (t, i))) ! 783: return 1; ! 784: return 0; ! 785: } ! 786: default: ! 787: break; ! 788: } ! 789: sorry ("testing %s for template parms", ! 790: tree_code_name [(int) TREE_CODE (t)]); ! 791: my_friendly_abort (82); ! 792: /* NOTREACHED */ ! 793: return 0; ! 794: } ! 795: } ! 796: ! 797: void ! 798: instantiate_member_templates (arg) ! 799: tree arg; ! 800: { ! 801: tree t; ! 802: tree classname = TREE_VALUE (arg); ! 803: tree id = classname; ! 804: tree members = DECL_TEMPLATE_MEMBERS (TREE_PURPOSE (IDENTIFIER_TEMPLATE (id))); ! 805: ! 806: for (t = members; t; t = TREE_CHAIN (t)) ! 807: { ! 808: tree parmvec, type, classparms, tdecl, t2; ! 809: int nparms, xxx = 0, i; ! 810: ! 811: my_friendly_assert (TREE_VALUE (t) != NULL_TREE, 275); ! 812: my_friendly_assert (TREE_CODE (TREE_VALUE (t)) == TEMPLATE_DECL, 276); ! 813: /* @@ Should verify that class parm list is a list of ! 814: distinct template parameters, and covers all the template ! 815: parameters. */ ! 816: tdecl = TREE_VALUE (t); ! 817: type = DECL_CONTEXT (DECL_TEMPLATE_RESULT (tdecl)); ! 818: classparms = UPT_PARMS (type); ! 819: nparms = TREE_VEC_LENGTH (classparms); ! 820: parmvec = make_tree_vec (nparms); ! 821: for (i = 0; i < nparms; i++) ! 822: TREE_VEC_ELT (parmvec, i) = NULL_TREE; ! 823: switch (unify (DECL_TEMPLATE_PARMS (tdecl), ! 824: &TREE_VEC_ELT (parmvec, 0), nparms, ! 825: type, IDENTIFIER_TYPE_VALUE (classname), ! 826: &xxx)) ! 827: { ! 828: case 0: ! 829: /* Success -- well, no inconsistency, at least. */ ! 830: for (i = 0; i < nparms; i++) ! 831: if (TREE_VEC_ELT (parmvec, i) == NULL_TREE) ! 832: goto failure; ! 833: t2 = instantiate_template (tdecl, ! 834: &TREE_VEC_ELT (parmvec, 0)); ! 835: type = IDENTIFIER_TYPE_VALUE (id); ! 836: my_friendly_assert (type != 0, 277); ! 837: if (CLASSTYPE_INTERFACE_UNKNOWN (type)) ! 838: { ! 839: DECL_EXTERNAL (t2) = 0; ! 840: TREE_PUBLIC (t2) = 0; ! 841: } ! 842: else ! 843: { ! 844: DECL_EXTERNAL (t2) = CLASSTYPE_INTERFACE_ONLY (type); ! 845: TREE_PUBLIC (t2) = 1; ! 846: } ! 847: break; ! 848: case 1: ! 849: /* Failure. */ ! 850: failure: ! 851: cp_error ("type unification error instantiating %T::%D", ! 852: classname, tdecl); ! 853: cp_error_at ("for template declaration `%D'", tdecl); ! 854: ! 855: continue /* loop of members */; ! 856: default: ! 857: /* Eek, a bug. */ ! 858: my_friendly_abort (83); ! 859: } ! 860: } ! 861: } ! 862: ! 863: struct tinst_level *current_tinst_level = 0; ! 864: struct tinst_level *free_tinst_level = 0; ! 865: ! 866: void ! 867: push_tinst_level (name) ! 868: tree name; ! 869: { ! 870: struct tinst_level *new; ! 871: tree global = IDENTIFIER_GLOBAL_VALUE (name); ! 872: ! 873: if (free_tinst_level) ! 874: { ! 875: new = free_tinst_level; ! 876: free_tinst_level = new->next; ! 877: } ! 878: else ! 879: new = (struct tinst_level *) xmalloc (sizeof (struct tinst_level)); ! 880: ! 881: new->classname = name; ! 882: if (global) ! 883: { ! 884: new->line = DECL_SOURCE_LINE (global); ! 885: new->file = DECL_SOURCE_FILE (global); ! 886: } ! 887: else ! 888: { ! 889: new->line = lineno; ! 890: new->file = input_filename; ! 891: } ! 892: new->next = current_tinst_level; ! 893: current_tinst_level = new; ! 894: } ! 895: ! 896: void ! 897: pop_tinst_level () ! 898: { ! 899: struct tinst_level *old = current_tinst_level; ! 900: ! 901: current_tinst_level = old->next; ! 902: old->next = free_tinst_level; ! 903: free_tinst_level = old; ! 904: } ! 905: ! 906: struct tinst_level * ! 907: tinst_for_decl () ! 908: { ! 909: struct tinst_level *p = current_tinst_level; ! 910: ! 911: if (p) ! 912: for (; p->next ; p = p->next ) ! 913: ; ! 914: return p; ! 915: } ! 916: ! 917: tree ! 918: instantiate_class_template (classname, setup_parse) ! 919: tree classname; ! 920: int setup_parse; ! 921: { ! 922: struct template_info *template_info; ! 923: tree template, t1; ! 924: ! 925: if (classname == error_mark_node) ! 926: return error_mark_node; ! 927: ! 928: my_friendly_assert (TREE_CODE (classname) == IDENTIFIER_NODE, 278); ! 929: template = IDENTIFIER_TEMPLATE (classname); ! 930: ! 931: if (IDENTIFIER_HAS_TYPE_VALUE (classname)) ! 932: { ! 933: tree type = IDENTIFIER_TYPE_VALUE (classname); ! 934: if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE) ! 935: return type; ! 936: if (TYPE_BEING_DEFINED (type) ! 937: || TYPE_SIZE (type) ! 938: || CLASSTYPE_USE_TEMPLATE (type) != 0) ! 939: return type; ! 940: } ! 941: ! 942: /* If IDENTIFIER_LOCAL_VALUE is already set on this template classname ! 943: (it's something like `foo<int>'), that means we're already working on ! 944: the instantiation for it. Normally, a classname comes in with nothing ! 945: but its IDENTIFIER_TEMPLATE slot set. If we were to try to instantiate ! 946: this again, we'd get a redeclaration error. Since we're already working ! 947: on it, we'll pass back this classname's TYPE_DECL (it's the value of ! 948: the classname's IDENTIFIER_LOCAL_VALUE). Only do this if we're setting ! 949: things up for the parser, though---if we're just trying to instantiate ! 950: it (e.g., via tsubst) we can trip up cuz it may not have an ! 951: IDENTIFIER_TYPE_VALUE when it will need one. */ ! 952: if (setup_parse && IDENTIFIER_LOCAL_VALUE (classname)) ! 953: return IDENTIFIER_LOCAL_VALUE (classname); ! 954: ! 955: if (uses_template_parms (classname)) ! 956: { ! 957: if (!TREE_TYPE (classname)) ! 958: { ! 959: tree t = make_lang_type (RECORD_TYPE); ! 960: tree d = build_lang_decl (TYPE_DECL, classname, t); ! 961: DECL_NAME (d) = classname; ! 962: TYPE_NAME (t) = d; ! 963: pushdecl (d); ! 964: } ! 965: return NULL_TREE; ! 966: } ! 967: ! 968: t1 = TREE_PURPOSE (template); ! 969: my_friendly_assert (TREE_CODE (t1) == TEMPLATE_DECL, 279); ! 970: ! 971: /* If a template is declared but not defined, accept it; don't crash. ! 972: Later uses requiring the definition will be flagged as errors by ! 973: other code. Thanks to [email protected] for this bug fix. */ ! 974: if (DECL_TEMPLATE_INFO (t1)->text == 0) ! 975: setup_parse = 0; ! 976: ! 977: push_to_top_level (); ! 978: template_info = DECL_TEMPLATE_INFO (t1); ! 979: if (setup_parse) ! 980: { ! 981: push_tinst_level (classname); ! 982: push_template_decls (DECL_TEMPLATE_PARMS (TREE_PURPOSE (template)), ! 983: TREE_VALUE (template), 0); ! 984: set_current_level_tags_transparency (1); ! 985: feed_input (template_info->text, template_info->length, (struct obstack *)0); ! 986: lineno = template_info->lineno; ! 987: input_filename = template_info->filename; ! 988: /* Get interface/implementation back in sync. */ ! 989: extract_interface_info (); ! 990: overload_template_name (classname, 0); ! 991: yychar = PRE_PARSED_CLASS_DECL; ! 992: yylval.ttype = build_tree_list (class_type_node, classname); ! 993: processing_template_defn++; ! 994: if (!flag_external_templates) ! 995: interface_unknown++; ! 996: } ! 997: else ! 998: { ! 999: tree t, decl, id, tmpl; ! 1000: ! 1001: id = classname; ! 1002: tmpl = TREE_PURPOSE (IDENTIFIER_TEMPLATE (id)); ! 1003: t = xref_tag (DECL_TEMPLATE_INFO (tmpl)->aggr, id, NULL_TREE); ! 1004: my_friendly_assert (TREE_CODE (t) == RECORD_TYPE ! 1005: || TREE_CODE (t) == UNION_TYPE, 280); ! 1006: ! 1007: /* Now, put a copy of the decl in global scope, to avoid ! 1008: * recursive expansion. */ ! 1009: decl = IDENTIFIER_LOCAL_VALUE (id); ! 1010: if (!decl) ! 1011: decl = IDENTIFIER_CLASS_VALUE (id); ! 1012: if (decl) ! 1013: { ! 1014: my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 281); ! 1015: /* We'd better make sure we're on the permanent obstack or else ! 1016: * we'll get a "friendly" abort 124 in pushdecl. Perhaps a ! 1017: * copy_to_permanent would be sufficient here, but then a ! 1018: * sharing problem might occur. I don't know -- [email protected] */ ! 1019: push_obstacks (&permanent_obstack, &permanent_obstack); ! 1020: pushdecl_top_level (copy_node (decl)); ! 1021: pop_obstacks (); ! 1022: } ! 1023: pop_from_top_level (); ! 1024: } ! 1025: ! 1026: return NULL_TREE; ! 1027: } ! 1028: ! 1029: static int ! 1030: list_eq (t1, t2) ! 1031: tree t1, t2; ! 1032: { ! 1033: if (t1 == NULL_TREE) ! 1034: return t2 == NULL_TREE; ! 1035: if (t2 == NULL_TREE) ! 1036: return 0; ! 1037: /* Don't care if one declares its arg const and the other doesn't -- the ! 1038: main variant of the arg type is all that matters. */ ! 1039: if (TYPE_MAIN_VARIANT (TREE_VALUE (t1)) ! 1040: != TYPE_MAIN_VARIANT (TREE_VALUE (t2))) ! 1041: return 0; ! 1042: return list_eq (TREE_CHAIN (t1), TREE_CHAIN (t2)); ! 1043: } ! 1044: ! 1045: static tree ! 1046: tsubst (t, args, nargs, in_decl) ! 1047: tree t, *args; ! 1048: int nargs; ! 1049: tree in_decl; ! 1050: { ! 1051: tree type; ! 1052: ! 1053: if (t == NULL_TREE || t == error_mark_node) ! 1054: return t; ! 1055: ! 1056: type = TREE_TYPE (t); ! 1057: if (type ! 1058: /* Minor optimization. ! 1059: ?? Are these really the most frequent cases? Is the savings ! 1060: significant? */ ! 1061: && type != integer_type_node ! 1062: && type != void_type_node ! 1063: && type != char_type_node) ! 1064: type = build_type_variant (tsubst (type, args, nargs, in_decl), ! 1065: TYPE_READONLY (type), ! 1066: TYPE_VOLATILE (type)); ! 1067: switch (TREE_CODE (t)) ! 1068: { ! 1069: case ERROR_MARK: ! 1070: case IDENTIFIER_NODE: ! 1071: case OP_IDENTIFIER: ! 1072: case VOID_TYPE: ! 1073: case REAL_TYPE: ! 1074: case ENUMERAL_TYPE: ! 1075: case INTEGER_CST: ! 1076: case REAL_CST: ! 1077: case STRING_CST: ! 1078: case RECORD_TYPE: ! 1079: case UNION_TYPE: ! 1080: return t; ! 1081: ! 1082: case INTEGER_TYPE: ! 1083: if (t == integer_type_node) ! 1084: return t; ! 1085: ! 1086: if (TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST ! 1087: && TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST) ! 1088: return t; ! 1089: return build_index_2_type ! 1090: (tsubst (TYPE_MIN_VALUE (t), args, nargs, in_decl), ! 1091: tsubst (TYPE_MAX_VALUE (t), args, nargs, in_decl)); ! 1092: ! 1093: case TEMPLATE_TYPE_PARM: ! 1094: return build_type_variant (args[TEMPLATE_TYPE_IDX (t)], ! 1095: TYPE_READONLY (t), ! 1096: TYPE_VOLATILE (t)); ! 1097: ! 1098: case TEMPLATE_CONST_PARM: ! 1099: return args[TEMPLATE_CONST_IDX (t)]; ! 1100: ! 1101: case FUNCTION_DECL: ! 1102: { ! 1103: tree r; ! 1104: tree fnargs, result; ! 1105: ! 1106: if (type == TREE_TYPE (t) ! 1107: && (DECL_CONTEXT (t) == NULL_TREE ! 1108: || TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) != 't')) ! 1109: return t; ! 1110: fnargs = tsubst (DECL_ARGUMENTS (t), args, nargs, t); ! 1111: result = tsubst (DECL_RESULT (t), args, nargs, t); ! 1112: if (DECL_CONTEXT (t) != NULL_TREE ! 1113: && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't') ! 1114: { ! 1115: /* Look it up in that class, and return the decl node there, ! 1116: instead of creating a new one. */ ! 1117: tree ctx, methods, name, method; ! 1118: int n_methods; ! 1119: int i, found = 0; ! 1120: ! 1121: name = DECL_NAME (t); ! 1122: ctx = tsubst (DECL_CONTEXT (t), args, nargs, t); ! 1123: methods = CLASSTYPE_METHOD_VEC (ctx); ! 1124: if (methods == NULL_TREE) ! 1125: /* No methods at all -- no way this one can match. */ ! 1126: goto no_match; ! 1127: n_methods = TREE_VEC_LENGTH (methods); ! 1128: ! 1129: r = NULL_TREE; ! 1130: ! 1131: if (!strncmp (OPERATOR_TYPENAME_FORMAT, ! 1132: IDENTIFIER_POINTER (name), ! 1133: sizeof (OPERATOR_TYPENAME_FORMAT) - 1)) ! 1134: { ! 1135: /* Type-conversion operator. Reconstruct the name, in ! 1136: case it's the name of one of the template's parameters. */ ! 1137: name = build_typename_overload (TREE_TYPE (type)); ! 1138: } ! 1139: ! 1140: if (DECL_CONTEXT (t) != NULL_TREE ! 1141: && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't' ! 1142: && constructor_name (DECL_CONTEXT (t)) == DECL_NAME (t)) ! 1143: name = constructor_name (ctx); ! 1144: #if 0 ! 1145: fprintf (stderr, "\nfor function %s in class %s:\n", ! 1146: IDENTIFIER_POINTER (name), ! 1147: IDENTIFIER_POINTER (TYPE_IDENTIFIER (ctx))); ! 1148: #endif ! 1149: for (i = 0; i < n_methods; i++) ! 1150: { ! 1151: int pass; ! 1152: ! 1153: method = TREE_VEC_ELT (methods, i); ! 1154: if (method == NULL_TREE || DECL_NAME (method) != name) ! 1155: continue; ! 1156: ! 1157: pass = 0; ! 1158: maybe_error: ! 1159: for (; method; method = TREE_CHAIN (method)) ! 1160: { ! 1161: my_friendly_assert (TREE_CODE (method) == FUNCTION_DECL, ! 1162: 282); ! 1163: if (TREE_TYPE (method) != type) ! 1164: { ! 1165: tree mtype = TREE_TYPE (method); ! 1166: tree t1, t2; ! 1167: ! 1168: /* Keep looking for a method that matches ! 1169: perfectly. This takes care of the problem ! 1170: where destructors (which have implicit int args) ! 1171: look like constructors which have an int arg. */ ! 1172: if (pass == 0) ! 1173: continue; ! 1174: ! 1175: t1 = TYPE_ARG_TYPES (mtype); ! 1176: t2 = TYPE_ARG_TYPES (type); ! 1177: if (TREE_CODE (mtype) == FUNCTION_TYPE) ! 1178: t2 = TREE_CHAIN (t2); ! 1179: ! 1180: if (list_eq (t1, t2)) ! 1181: { ! 1182: if (TREE_CODE (mtype) == FUNCTION_TYPE) ! 1183: { ! 1184: tree newtype; ! 1185: newtype = build_function_type (TREE_TYPE (type), ! 1186: TYPE_ARG_TYPES (type)); ! 1187: newtype = build_type_variant (newtype, ! 1188: TYPE_READONLY (type), ! 1189: TYPE_VOLATILE (type)); ! 1190: type = newtype; ! 1191: if (TREE_TYPE (type) != TREE_TYPE (mtype)) ! 1192: goto maybe_bad_return_type; ! 1193: } ! 1194: else if (TYPE_METHOD_BASETYPE (mtype) ! 1195: == TYPE_METHOD_BASETYPE (type)) ! 1196: { ! 1197: /* Types didn't match, but arg types and ! 1198: `this' do match, so the return type is ! 1199: all that should be messing it up. */ ! 1200: maybe_bad_return_type: ! 1201: if (TREE_TYPE (type) != TREE_TYPE (mtype)) ! 1202: error ("inconsistent return types for method `%s' in class `%s'", ! 1203: IDENTIFIER_POINTER (name), ! 1204: IDENTIFIER_POINTER (TYPE_IDENTIFIER (ctx))); ! 1205: } ! 1206: r = method; ! 1207: break; ! 1208: } ! 1209: found = 1; ! 1210: continue; ! 1211: } ! 1212: #if 0 ! 1213: fprintf (stderr, "\tfound %s\n\n", ! 1214: IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (method))); ! 1215: #endif ! 1216: ! 1217: if (DECL_ARGUMENTS (method) ! 1218: && ! TREE_PERMANENT (DECL_ARGUMENTS (method))) ! 1219: /* @@ Is this early enough? Might we want to do ! 1220: this instead while processing the expansion? */ ! 1221: DECL_ARGUMENTS (method) ! 1222: = tsubst (DECL_ARGUMENTS (t), args, nargs, t); ! 1223: r = method; ! 1224: break; ! 1225: } ! 1226: if (r == NULL_TREE && pass == 0) ! 1227: { ! 1228: pass = 1; ! 1229: method = TREE_VEC_ELT (methods, i); ! 1230: goto maybe_error; ! 1231: } ! 1232: } ! 1233: if (r == NULL_TREE) ! 1234: { ! 1235: no_match: ! 1236: cp_error ! 1237: (found ! 1238: ? "template for method `%D' doesn't match any in class `%T'" ! 1239: : "method `%D' not found in class `%T'", name, ctx); ! 1240: if (in_decl) ! 1241: cp_error_at ("in attempt to instantiate `%D' declared at this point in file", in_decl); ! 1242: return error_mark_node; ! 1243: } ! 1244: } ! 1245: else ! 1246: { ! 1247: r = DECL_NAME (t); ! 1248: { ! 1249: tree decls, val; ! 1250: int got_it = 0; ! 1251: ! 1252: decls = IDENTIFIER_GLOBAL_VALUE (r); ! 1253: if (decls == NULL_TREE) ! 1254: /* no match */; ! 1255: else if (TREE_CODE (decls) == TREE_LIST) ! 1256: while (decls) ! 1257: { ! 1258: val = TREE_VALUE (decls); ! 1259: decls = TREE_CHAIN (decls); ! 1260: try_one: ! 1261: if (TREE_CODE (val) == FUNCTION_DECL ! 1262: && TREE_TYPE (val) == type) ! 1263: { ! 1264: got_it = 1; ! 1265: r = val; ! 1266: break; ! 1267: } ! 1268: } ! 1269: else ! 1270: { ! 1271: val = decls; ! 1272: decls = NULL_TREE; ! 1273: goto try_one; ! 1274: } ! 1275: ! 1276: if (!got_it) ! 1277: { ! 1278: r = build_decl_overload (r, TYPE_VALUES (type), ! 1279: DECL_CONTEXT (t) != NULL_TREE); ! 1280: r = build_lang_decl (FUNCTION_DECL, r, type); ! 1281: } ! 1282: } ! 1283: } ! 1284: TREE_PUBLIC (r) = TREE_PUBLIC (t); ! 1285: DECL_EXTERNAL (r) = DECL_EXTERNAL (t); ! 1286: TREE_STATIC (r) = TREE_STATIC (t); ! 1287: DECL_INLINE (r) = DECL_INLINE (t); ! 1288: { ! 1289: #if 0 /* Maybe later. -jason */ ! 1290: struct tinst_level *til = tinst_for_decl(); ! 1291: ! 1292: /* should always be true under new approach */ ! 1293: if (til) ! 1294: { ! 1295: DECL_SOURCE_FILE (r) = til->file; ! 1296: DECL_SOURCE_LINE (r) = til->line; ! 1297: } ! 1298: else ! 1299: #endif ! 1300: { ! 1301: DECL_SOURCE_FILE (r) = DECL_SOURCE_FILE (t); ! 1302: DECL_SOURCE_LINE (r) = DECL_SOURCE_LINE (t); ! 1303: } ! 1304: } ! 1305: DECL_CLASS_CONTEXT (r) = tsubst (DECL_CLASS_CONTEXT (t), args, nargs, t); ! 1306: make_decl_rtl (r, NULL_PTR, 1); ! 1307: DECL_ARGUMENTS (r) = fnargs; ! 1308: DECL_RESULT (r) = result; ! 1309: if (DECL_CONTEXT (t) == NULL_TREE ! 1310: || TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) != 't') ! 1311: push_overloaded_decl_top_level (r, 0); ! 1312: return r; ! 1313: } ! 1314: ! 1315: case PARM_DECL: ! 1316: { ! 1317: tree r; ! 1318: r = build_decl (PARM_DECL, DECL_NAME (t), type); ! 1319: DECL_INITIAL (r) = TREE_TYPE (r); ! 1320: if (TREE_CHAIN (t)) ! 1321: TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args, nargs, TREE_CHAIN (t)); ! 1322: return r; ! 1323: } ! 1324: ! 1325: case TREE_LIST: ! 1326: { ! 1327: tree purpose, value, chain, result; ! 1328: int via_public, via_virtual, via_protected; ! 1329: ! 1330: if (t == void_list_node) ! 1331: return t; ! 1332: ! 1333: via_public = TREE_VIA_PUBLIC (t); ! 1334: via_protected = TREE_VIA_PROTECTED (t); ! 1335: via_virtual = TREE_VIA_VIRTUAL (t); ! 1336: ! 1337: purpose = TREE_PURPOSE (t); ! 1338: if (purpose) ! 1339: purpose = tsubst (purpose, args, nargs, in_decl); ! 1340: value = TREE_VALUE (t); ! 1341: if (value) ! 1342: value = tsubst (value, args, nargs, in_decl); ! 1343: chain = TREE_CHAIN (t); ! 1344: if (chain && chain != void_type_node) ! 1345: chain = tsubst (chain, args, nargs, in_decl); ! 1346: if (purpose == TREE_PURPOSE (t) ! 1347: && value == TREE_VALUE (t) ! 1348: && chain == TREE_CHAIN (t)) ! 1349: return t; ! 1350: result = hash_tree_cons (via_public, via_virtual, via_protected, ! 1351: purpose, value, chain); ! 1352: TREE_PARMLIST (result) = TREE_PARMLIST (t); ! 1353: return result; ! 1354: } ! 1355: case TREE_VEC: ! 1356: { ! 1357: int len = TREE_VEC_LENGTH (t), need_new = 0, i; ! 1358: tree *elts = (tree *) alloca (len * sizeof (tree)); ! 1359: bzero (elts, len * sizeof (tree)); ! 1360: ! 1361: for (i = 0; i < len; i++) ! 1362: { ! 1363: elts[i] = tsubst (TREE_VEC_ELT (t, i), args, nargs, in_decl); ! 1364: if (elts[i] != TREE_VEC_ELT (t, i)) ! 1365: need_new = 1; ! 1366: } ! 1367: ! 1368: if (!need_new) ! 1369: return t; ! 1370: ! 1371: t = make_tree_vec (len); ! 1372: for (i = 0; i < len; i++) ! 1373: TREE_VEC_ELT (t, i) = elts[i]; ! 1374: return t; ! 1375: } ! 1376: case POINTER_TYPE: ! 1377: case REFERENCE_TYPE: ! 1378: { ! 1379: tree r; ! 1380: enum tree_code code; ! 1381: if (type == TREE_TYPE (t)) ! 1382: return t; ! 1383: ! 1384: code = TREE_CODE (t); ! 1385: if (code == POINTER_TYPE) ! 1386: r = build_pointer_type (type); ! 1387: else ! 1388: r = build_reference_type (type); ! 1389: r = build_type_variant (r, TYPE_READONLY (t), TYPE_VOLATILE (t)); ! 1390: /* Will this ever be needed for TYPE_..._TO values? */ ! 1391: layout_type (r); ! 1392: return r; ! 1393: } ! 1394: case FUNCTION_TYPE: ! 1395: case METHOD_TYPE: ! 1396: { ! 1397: tree values = TYPE_VALUES (t); /* same as TYPE_ARG_TYPES */ ! 1398: tree context = TYPE_CONTEXT (t); ! 1399: tree new_value; ! 1400: ! 1401: /* Don't bother recursing if we know it won't change anything. */ ! 1402: if (! (values == void_type_node ! 1403: || values == integer_type_node)) ! 1404: values = tsubst (values, args, nargs, in_decl); ! 1405: if (context) ! 1406: context = tsubst (context, args, nargs, in_decl); ! 1407: /* Could also optimize cases where return value and ! 1408: values have common elements (e.g., T min(const &T, const T&). */ ! 1409: ! 1410: /* If the above parameters haven't changed, just return the type. */ ! 1411: if (type == TREE_TYPE (t) ! 1412: && values == TYPE_VALUES (t) ! 1413: && context == TYPE_CONTEXT (t)) ! 1414: return t; ! 1415: ! 1416: /* Construct a new type node and return it. */ ! 1417: if (TREE_CODE (t) == FUNCTION_TYPE ! 1418: && context == NULL_TREE) ! 1419: { ! 1420: new_value = build_function_type (type, values); ! 1421: } ! 1422: else if (context == NULL_TREE) ! 1423: { ! 1424: tree base = tsubst (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), ! 1425: args, nargs, in_decl); ! 1426: new_value = build_cplus_method_type (base, type, ! 1427: TREE_CHAIN (values)); ! 1428: } ! 1429: else ! 1430: { ! 1431: new_value = make_node (TREE_CODE (t)); ! 1432: TREE_TYPE (new_value) = type; ! 1433: TYPE_CONTEXT (new_value) = context; ! 1434: TYPE_VALUES (new_value) = values; ! 1435: TYPE_SIZE (new_value) = TYPE_SIZE (t); ! 1436: TYPE_ALIGN (new_value) = TYPE_ALIGN (t); ! 1437: TYPE_MODE (new_value) = TYPE_MODE (t); ! 1438: if (TYPE_METHOD_BASETYPE (t)) ! 1439: TYPE_METHOD_BASETYPE (new_value) = tsubst (TYPE_METHOD_BASETYPE (t), ! 1440: args, nargs, in_decl); ! 1441: /* Need to generate hash value. */ ! 1442: my_friendly_abort (84); ! 1443: } ! 1444: new_value = build_type_variant (new_value, ! 1445: TYPE_READONLY (t), ! 1446: TYPE_VOLATILE (t)); ! 1447: return new_value; ! 1448: } ! 1449: case ARRAY_TYPE: ! 1450: { ! 1451: tree domain = tsubst (TYPE_DOMAIN (t), args, nargs, in_decl); ! 1452: tree r; ! 1453: if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t)) ! 1454: return t; ! 1455: r = build_cplus_array_type (type, domain); ! 1456: return r; ! 1457: } ! 1458: ! 1459: case UNINSTANTIATED_P_TYPE: ! 1460: { ! 1461: int nparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (UPT_TEMPLATE (t))); ! 1462: tree argvec = make_tree_vec (nparms); ! 1463: tree parmvec = UPT_PARMS (t); ! 1464: int i; ! 1465: tree id; ! 1466: for (i = 0; i < nparms; i++) ! 1467: TREE_VEC_ELT (argvec, i) = tsubst (TREE_VEC_ELT (parmvec, i), ! 1468: args, nargs, in_decl); ! 1469: id = lookup_template_class (DECL_NAME (UPT_TEMPLATE (t)), argvec, NULL_TREE); ! 1470: if (! IDENTIFIER_HAS_TYPE_VALUE (id)) { ! 1471: instantiate_class_template(id, 0); ! 1472: /* set up pending_classes */ ! 1473: add_pending_template (id); ! 1474: ! 1475: TYPE_MAIN_VARIANT (IDENTIFIER_TYPE_VALUE (id)) = ! 1476: IDENTIFIER_TYPE_VALUE (id); ! 1477: } ! 1478: return build_type_variant (IDENTIFIER_TYPE_VALUE (id), ! 1479: TYPE_READONLY (t), ! 1480: TYPE_VOLATILE (t)); ! 1481: } ! 1482: ! 1483: case MINUS_EXPR: ! 1484: case PLUS_EXPR: ! 1485: return fold (build (TREE_CODE (t), TREE_TYPE (t), ! 1486: tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl), ! 1487: tsubst (TREE_OPERAND (t, 1), args, nargs, in_decl))); ! 1488: ! 1489: case NEGATE_EXPR: ! 1490: case NOP_EXPR: ! 1491: return fold (build1 (TREE_CODE (t), TREE_TYPE (t), ! 1492: tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl))); ! 1493: ! 1494: default: ! 1495: sorry ("use of `%s' in function template", ! 1496: tree_code_name [(int) TREE_CODE (t)]); ! 1497: return error_mark_node; ! 1498: } ! 1499: } ! 1500: ! 1501: tree ! 1502: instantiate_template (tmpl, targ_ptr) ! 1503: tree tmpl, *targ_ptr; ! 1504: { ! 1505: tree targs, fndecl; ! 1506: int i, len; ! 1507: struct pending_inline *p; ! 1508: struct template_info *t; ! 1509: struct obstack *old_fmp_obstack; ! 1510: extern struct obstack *function_maybepermanent_obstack; ! 1511: ! 1512: push_obstacks (&permanent_obstack, &permanent_obstack); ! 1513: old_fmp_obstack = function_maybepermanent_obstack; ! 1514: function_maybepermanent_obstack = &permanent_obstack; ! 1515: ! 1516: my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 283); ! 1517: len = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (tmpl)); ! 1518: ! 1519: for (fndecl = DECL_TEMPLATE_INSTANTIATIONS (tmpl); ! 1520: fndecl; fndecl = TREE_CHAIN (fndecl)) ! 1521: { ! 1522: tree *t1 = &TREE_VEC_ELT (TREE_PURPOSE (fndecl), 0); ! 1523: for (i = len - 1; i >= 0; i--) ! 1524: if (t1[i] != targ_ptr[i]) ! 1525: goto no_match; ! 1526: ! 1527: /* Here, we have a match. */ ! 1528: fndecl = TREE_VALUE (fndecl); ! 1529: function_maybepermanent_obstack = old_fmp_obstack; ! 1530: pop_obstacks (); ! 1531: return fndecl; ! 1532: ! 1533: no_match: ! 1534: ; ! 1535: } ! 1536: ! 1537: targs = make_tree_vec (len); ! 1538: i = len; ! 1539: while (i--) ! 1540: TREE_VEC_ELT (targs, i) = targ_ptr[i]; ! 1541: ! 1542: /* substitute template parameters */ ! 1543: fndecl = tsubst (DECL_RESULT (tmpl), targ_ptr, ! 1544: TREE_VEC_LENGTH (targs), tmpl); ! 1545: ! 1546: /* If it's a static member fn in the template, we need to change it ! 1547: into a FUNCTION_TYPE and chop off its this pointer. */ ! 1548: if (TREE_CODE (TREE_TYPE (DECL_RESULT (tmpl))) == METHOD_TYPE ! 1549: && fndecl != error_mark_node ! 1550: && DECL_STATIC_FUNCTION_P (fndecl)) ! 1551: { ! 1552: tree olddecl = DECL_RESULT (tmpl); ! 1553: revert_static_member_fn (&TREE_TYPE (olddecl), &DECL_RESULT (tmpl), ! 1554: &TYPE_ARG_TYPES (TREE_TYPE (olddecl))); ! 1555: /* Chop off the this pointer that grokclassfn so kindly added ! 1556: for us (it didn't know yet if the fn was static or not). */ ! 1557: DECL_ARGUMENTS (olddecl) = TREE_CHAIN (DECL_ARGUMENTS (olddecl)); ! 1558: DECL_ARGUMENTS (fndecl) = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); ! 1559: } ! 1560: ! 1561: t = DECL_TEMPLATE_INFO (tmpl); ! 1562: if (t->text) ! 1563: { ! 1564: p = (struct pending_inline *) permalloc (sizeof (struct pending_inline)); ! 1565: p->parm_vec = t->parm_vec; ! 1566: p->bindings = targs; ! 1567: p->can_free = 0; ! 1568: p->deja_vu = 0; ! 1569: p->buf = t->text; ! 1570: p->len = t->length; ! 1571: p->fndecl = fndecl; ! 1572: { ! 1573: int l = lineno; ! 1574: char * f = input_filename; ! 1575: ! 1576: lineno = p->lineno = t->lineno; ! 1577: input_filename = p->filename = t->filename; ! 1578: ! 1579: extract_interface_info (); ! 1580: ! 1581: if (interface_unknown && flag_external_templates) ! 1582: warn_if_unknown_interface (); ! 1583: if (interface_unknown || !flag_external_templates) ! 1584: p->interface = 1; /* unknown */ ! 1585: else ! 1586: p->interface = interface_only ? 0 : 2; ! 1587: ! 1588: lineno = l; ! 1589: input_filename = f; ! 1590: ! 1591: extract_interface_info (); ! 1592: } ! 1593: } ! 1594: else ! 1595: p = (struct pending_inline *)0; ! 1596: ! 1597: DECL_TEMPLATE_INSTANTIATIONS (tmpl) = ! 1598: tree_cons (targs, fndecl, DECL_TEMPLATE_INSTANTIATIONS (tmpl)); ! 1599: ! 1600: function_maybepermanent_obstack = old_fmp_obstack; ! 1601: pop_obstacks (); ! 1602: ! 1603: if (fndecl == error_mark_node || p == (struct pending_inline *)0) ! 1604: { ! 1605: /* do nothing */ ! 1606: } ! 1607: else if (DECL_INLINE (fndecl)) ! 1608: { ! 1609: DECL_PENDING_INLINE_INFO (fndecl) = p; ! 1610: p->next = pending_inlines; ! 1611: pending_inlines = p; ! 1612: } ! 1613: else ! 1614: { ! 1615: p->next = pending_template_expansions; ! 1616: pending_template_expansions = p; ! 1617: } ! 1618: return fndecl; ! 1619: } ! 1620: ! 1621: void ! 1622: undo_template_name_overload (id, classlevel) ! 1623: tree id; ! 1624: int classlevel; ! 1625: { ! 1626: tree template; ! 1627: ! 1628: template = IDENTIFIER_TEMPLATE (id); ! 1629: if (!template) ! 1630: return; ! 1631: ! 1632: #if 0 /* not yet, should get fixed properly later */ ! 1633: poplevel (0, 0, 0); ! 1634: #endif ! 1635: #if 1 /* XXX */ ! 1636: /* This was a botch... See `overload_template_name' just below. */ ! 1637: if (!classlevel) ! 1638: poplevel (0, 0, 0); ! 1639: #endif ! 1640: } ! 1641: ! 1642: void ! 1643: overload_template_name (id, classlevel) ! 1644: tree id; ! 1645: int classlevel; ! 1646: { ! 1647: tree template, t, decl; ! 1648: struct template_info *tinfo; ! 1649: ! 1650: my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 284); ! 1651: template = IDENTIFIER_TEMPLATE (id); ! 1652: if (!template) ! 1653: return; ! 1654: ! 1655: template = TREE_PURPOSE (template); ! 1656: tinfo = DECL_TEMPLATE_INFO (template); ! 1657: template = DECL_NAME (template); ! 1658: my_friendly_assert (template != NULL_TREE, 285); ! 1659: ! 1660: #if 1 /* XXX */ ! 1661: /* This was a botch... names of templates do not get their own private ! 1662: scopes. Rather, the names of generated template instances should ! 1663: just get pushed into whatever scope we happen to be in at the moment. ! 1664: This will typically (but not always) be the global scope. (Maybe ! 1665: what we really want to do here is a `push_to_toplevel' and then stay ! 1666: there while we are generating the instance; popping back out to the ! 1667: current scope when we are done generating the instance.) */ ! 1668: if (!classlevel) ! 1669: { ! 1670: pushlevel (1); ! 1671: declare_pseudo_global_level (); ! 1672: } ! 1673: #endif ! 1674: ! 1675: t = xref_tag (tinfo->aggr, id, NULL_TREE); ! 1676: my_friendly_assert (TREE_CODE (t) == RECORD_TYPE ! 1677: || TREE_CODE (t) == UNION_TYPE ! 1678: || TREE_CODE (t) == UNINSTANTIATED_P_TYPE, 286); ! 1679: ! 1680: decl = build_decl (TYPE_DECL, template, t); ! 1681: ! 1682: #if 0 /* fix this later */ ! 1683: /* We don't want to call here if the work has already been done. */ ! 1684: t = (classlevel ! 1685: ? IDENTIFIER_CLASS_VALUE (template) ! 1686: : IDENTIFIER_LOCAL_VALUE (template)); ! 1687: if (t ! 1688: && TREE_CODE (t) == TYPE_DECL ! 1689: && TREE_TYPE (t) == t) ! 1690: my_friendly_abort (85); ! 1691: #endif ! 1692: ! 1693: if (classlevel) ! 1694: pushdecl_class_level (decl); ! 1695: else ! 1696: #if 0 /* not yet, should get fixed properly later */ ! 1697: pushdecl (decl); ! 1698: pushlevel (1); ! 1699: #else ! 1700: { ! 1701: pushdecl (decl); ! 1702: /* @@ Is this necessary now? */ ! 1703: IDENTIFIER_LOCAL_VALUE (template) = decl; ! 1704: } ! 1705: #endif ! 1706: ! 1707: /* Fake this for now, just to make dwarfout.c happy. It will have to ! 1708: be done in a proper way later on. */ ! 1709: DECL_CONTEXT (decl) = t; ! 1710: } ! 1711: ! 1712: /* T1 is PRE_PARSED_CLASS_DECL; T3 is result of XREF_TAG lookup. */ ! 1713: void ! 1714: end_template_instantiation (t1, t3) ! 1715: tree t1, t3; ! 1716: { ! 1717: extern struct pending_input *to_be_restored; ! 1718: tree t, decl; ! 1719: ! 1720: processing_template_defn--; ! 1721: if (!flag_external_templates) ! 1722: interface_unknown--; ! 1723: ! 1724: /* Restore the old parser input state. */ ! 1725: if (yychar == YYEMPTY) ! 1726: yychar = yylex (); ! 1727: if (yychar != END_OF_SAVED_INPUT) ! 1728: error ("parse error at end of class template"); ! 1729: else ! 1730: { ! 1731: restore_pending_input (to_be_restored); ! 1732: to_be_restored = 0; ! 1733: } ! 1734: ! 1735: /* Our declarations didn't get stored in the global slot, since ! 1736: there was a (supposedly tags-transparent) scope in between. */ ! 1737: t = IDENTIFIER_TYPE_VALUE (TREE_VALUE (t1)); ! 1738: my_friendly_assert (t != NULL_TREE ! 1739: && TREE_CODE_CLASS (TREE_CODE (t)) == 't', ! 1740: 287); ! 1741: CLASSTYPE_USE_TEMPLATE (t) = 2; ! 1742: /* Make methods of template classes static, unless ! 1743: -fexternal-templates is given. */ ! 1744: if (!flag_external_templates) ! 1745: SET_CLASSTYPE_INTERFACE_UNKNOWN (t); ! 1746: decl = IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (t1)); ! 1747: my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 288); ! 1748: ! 1749: undo_template_name_overload (TREE_VALUE (t1), 0); ! 1750: t = IDENTIFIER_TEMPLATE (TREE_VALUE (t1)); ! 1751: pop_template_decls (DECL_TEMPLATE_PARMS (TREE_PURPOSE (t)), TREE_VALUE (t), ! 1752: 0); ! 1753: pop_from_top_level (); ! 1754: ! 1755: /* This will fix up the type-value field. */ ! 1756: pushdecl_top_level (decl); ! 1757: #ifdef DWARF_DEBUGGING_INFO ! 1758: if (write_symbols == DWARF_DEBUG && TREE_CODE (decl) == TYPE_DECL) ! 1759: { ! 1760: /* We just completed the definition of a new file-scope type, ! 1761: so we can go ahead and output debug-info for it now. */ ! 1762: TYPE_STUB_DECL (TREE_TYPE (decl)) = decl; ! 1763: rest_of_type_compilation (TREE_TYPE (decl), 1); ! 1764: } ! 1765: #endif /* DWARF_DEBUGGING_INFO */ ! 1766: ! 1767: /* Restore interface/implementation settings. */ ! 1768: extract_interface_info (); ! 1769: } ! 1770: ! 1771: /* Store away the text of an inline template function. No rtl is ! 1772: generated for this function until it is actually needed. */ ! 1773: ! 1774: void ! 1775: reinit_parse_for_template (yychar, d1, d2) ! 1776: int yychar; ! 1777: tree d1, d2; ! 1778: { ! 1779: struct template_info *template_info; ! 1780: extern struct obstack inline_text_obstack; /* see comment in cp-lex.c */ ! 1781: ! 1782: if (d2 == NULL_TREE || d2 == error_mark_node) ! 1783: { ! 1784: lose: ! 1785: /* @@ Should use temp obstack, and discard results. */ ! 1786: reinit_parse_for_block (yychar, &inline_text_obstack, 1); ! 1787: return; ! 1788: } ! 1789: ! 1790: if (TREE_CODE (d2) == IDENTIFIER_NODE) ! 1791: d2 = IDENTIFIER_GLOBAL_VALUE (d2); ! 1792: if (!d2) ! 1793: goto lose; ! 1794: template_info = DECL_TEMPLATE_INFO (d2); ! 1795: if (!template_info) ! 1796: { ! 1797: template_info = (struct template_info *) permalloc (sizeof (struct template_info)); ! 1798: bzero (template_info, sizeof (struct template_info)); ! 1799: DECL_TEMPLATE_INFO (d2) = template_info; ! 1800: } ! 1801: template_info->filename = input_filename; ! 1802: template_info->lineno = lineno; ! 1803: reinit_parse_for_block (yychar, &inline_text_obstack, 1); ! 1804: template_info->text = obstack_base (&inline_text_obstack); ! 1805: template_info->length = obstack_object_size (&inline_text_obstack); ! 1806: obstack_finish (&inline_text_obstack); ! 1807: template_info->parm_vec = d1; ! 1808: } ! 1809: ! 1810: /* Type unification. ! 1811: ! 1812: We have a function template signature with one or more references to ! 1813: template parameters, and a parameter list we wish to fit to this ! 1814: template. If possible, produce a list of parameters for the template ! 1815: which will cause it to fit the supplied parameter list. ! 1816: ! 1817: Return zero for success, 2 for an incomplete match that doesn't resolve ! 1818: all the types, and 1 for complete failure. An error message will be ! 1819: printed only for an incomplete match. ! 1820: ! 1821: TPARMS[NTPARMS] is an array of template parameter types; ! 1822: TARGS[NTPARMS] is the array of template parameter values. PARMS is ! 1823: the function template's signature (using TEMPLATE_PARM_IDX nodes), ! 1824: and ARGS is the argument list we're trying to match against it. */ ! 1825: ! 1826: int ! 1827: type_unification (tparms, targs, parms, args, nsubsts) ! 1828: tree tparms, *targs, parms, args; ! 1829: int *nsubsts; ! 1830: { ! 1831: tree parm, arg; ! 1832: int i; ! 1833: int ntparms = TREE_VEC_LENGTH (tparms); ! 1834: ! 1835: my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289); ! 1836: my_friendly_assert (TREE_CODE (parms) == TREE_LIST, 290); ! 1837: /* ARGS could be NULL (via a call from cp-parse.y to ! 1838: build_x_function_call). */ ! 1839: if (args) ! 1840: my_friendly_assert (TREE_CODE (args) == TREE_LIST, 291); ! 1841: my_friendly_assert (ntparms > 0, 292); ! 1842: ! 1843: bzero (targs, sizeof (tree) * ntparms); ! 1844: ! 1845: while (parms ! 1846: && parms != void_list_node ! 1847: && args) ! 1848: { ! 1849: parm = TREE_VALUE (parms); ! 1850: parms = TREE_CHAIN (parms); ! 1851: arg = TREE_VALUE (args); ! 1852: args = TREE_CHAIN (args); ! 1853: ! 1854: if (arg == error_mark_node) ! 1855: return 1; ! 1856: if (arg == unknown_type_node) ! 1857: return 1; ! 1858: #if 0 ! 1859: if (TREE_CODE (arg) == VAR_DECL) ! 1860: arg = TREE_TYPE (arg); ! 1861: else if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'e') ! 1862: arg = TREE_TYPE (arg); ! 1863: #else ! 1864: my_friendly_assert (TREE_TYPE (arg) != NULL_TREE, 293); ! 1865: arg = TREE_TYPE (arg); ! 1866: #endif ! 1867: ! 1868: switch (unify (tparms, targs, ntparms, parm, arg, nsubsts)) ! 1869: { ! 1870: case 0: ! 1871: break; ! 1872: case 1: ! 1873: return 1; ! 1874: } ! 1875: } ! 1876: /* Fail if we've reached the end of the parm list, and more args ! 1877: are present, and the parm list isn't variadic. */ ! 1878: if (args && parms == void_list_node) ! 1879: return 1; ! 1880: /* Fail if parms are left and they don't have default values. */ ! 1881: if (parms ! 1882: && parms != void_list_node ! 1883: && TREE_PURPOSE (parms) == NULL_TREE) ! 1884: return 1; ! 1885: for (i = 0; i < ntparms; i++) ! 1886: if (!targs[i]) ! 1887: { ! 1888: error ("incomplete type unification"); ! 1889: return 2; ! 1890: } ! 1891: return 0; ! 1892: } ! 1893: ! 1894: /* Tail recursion is your friend. */ ! 1895: static int ! 1896: unify (tparms, targs, ntparms, parm, arg, nsubsts) ! 1897: tree tparms, *targs, parm, arg; ! 1898: int *nsubsts, ntparms; ! 1899: { ! 1900: int idx; ! 1901: ! 1902: /* I don't think this will do the right thing with respect to types. ! 1903: But the only case I've seen it in so far has been array bounds, where ! 1904: signedness is the only information lost, and I think that will be ! 1905: okay. */ ! 1906: while (TREE_CODE (parm) == NOP_EXPR) ! 1907: parm = TREE_OPERAND (parm, 0); ! 1908: ! 1909: if (arg == error_mark_node) ! 1910: return 1; ! 1911: if (arg == unknown_type_node) ! 1912: return 1; ! 1913: if (arg == parm) ! 1914: return 0; ! 1915: ! 1916: if (TREE_CODE (arg) == REFERENCE_TYPE) ! 1917: arg = TREE_TYPE (arg); ! 1918: ! 1919: switch (TREE_CODE (parm)) ! 1920: { ! 1921: case TEMPLATE_TYPE_PARM: ! 1922: (*nsubsts)++; ! 1923: if (TEMPLATE_TYPE_TPARMLIST (parm) != tparms) ! 1924: { ! 1925: error ("mixed template headers?!"); ! 1926: my_friendly_abort (86); ! 1927: return 1; ! 1928: } ! 1929: idx = TEMPLATE_TYPE_IDX (parm); ! 1930: /* Simple cases: Value already set, does match or doesn't. */ ! 1931: if (targs[idx] == arg) ! 1932: return 0; ! 1933: else if (targs[idx]) ! 1934: return 1; ! 1935: /* Check for mixed types and values. */ ! 1936: if (TREE_CODE (TREE_VEC_ELT (tparms, idx)) != IDENTIFIER_NODE) ! 1937: return 1; ! 1938: targs[idx] = arg; ! 1939: return 0; ! 1940: case TEMPLATE_CONST_PARM: ! 1941: (*nsubsts)++; ! 1942: idx = TEMPLATE_CONST_IDX (parm); ! 1943: if (targs[idx] == arg) ! 1944: return 0; ! 1945: else if (targs[idx]) ! 1946: { ! 1947: my_friendly_abort (87); ! 1948: return 1; ! 1949: } ! 1950: /* else if (typeof arg != tparms[idx]) ! 1951: return 1;*/ ! 1952: ! 1953: targs[idx] = copy_to_permanent (arg); ! 1954: return 0; ! 1955: ! 1956: case POINTER_TYPE: ! 1957: if (TREE_CODE (arg) != POINTER_TYPE) ! 1958: return 1; ! 1959: return unify (tparms, targs, ntparms, TREE_TYPE (parm), TREE_TYPE (arg), ! 1960: nsubsts); ! 1961: ! 1962: case REFERENCE_TYPE: ! 1963: return unify (tparms, targs, ntparms, TREE_TYPE (parm), arg, nsubsts); ! 1964: ! 1965: case ARRAY_TYPE: ! 1966: if (TREE_CODE (arg) != ARRAY_TYPE) ! 1967: return 1; ! 1968: if (unify (tparms, targs, ntparms, TYPE_DOMAIN (parm), TYPE_DOMAIN (arg), ! 1969: nsubsts) != 0) ! 1970: return 1; ! 1971: return unify (tparms, targs, ntparms, TREE_TYPE (parm), TREE_TYPE (arg), ! 1972: nsubsts); ! 1973: ! 1974: case REAL_TYPE: ! 1975: case INTEGER_TYPE: ! 1976: if (TREE_CODE (parm) == INTEGER_TYPE && TREE_CODE (arg) == INTEGER_TYPE) ! 1977: { ! 1978: if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg) ! 1979: && unify (tparms, targs, ntparms, ! 1980: TYPE_MIN_VALUE (parm), TYPE_MIN_VALUE (arg), nsubsts)) ! 1981: return 1; ! 1982: if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg) ! 1983: && unify (tparms, targs, ntparms, ! 1984: TYPE_MAX_VALUE (parm), TYPE_MAX_VALUE (arg), nsubsts)) ! 1985: return 1; ! 1986: } ! 1987: /* As far as unification is concerned, this wins. Later checks ! 1988: will invalidate it if necessary. */ ! 1989: return 0; ! 1990: ! 1991: /* Types INTEGER_CST and MINUS_EXPR can come from array bounds. */ ! 1992: case INTEGER_CST: ! 1993: if (TREE_CODE (arg) != INTEGER_CST) ! 1994: return 1; ! 1995: return !tree_int_cst_equal (parm, arg); ! 1996: ! 1997: case MINUS_EXPR: ! 1998: { ! 1999: tree t1, t2; ! 2000: t1 = TREE_OPERAND (parm, 0); ! 2001: t2 = TREE_OPERAND (parm, 1); ! 2002: if (TREE_CODE (t1) != TEMPLATE_CONST_PARM) ! 2003: return 1; ! 2004: return unify (tparms, targs, ntparms, t1, ! 2005: fold (build (PLUS_EXPR, integer_type_node, arg, t2)), ! 2006: nsubsts); ! 2007: } ! 2008: ! 2009: case TREE_VEC: ! 2010: { ! 2011: int i; ! 2012: if (TREE_CODE (arg) != TREE_VEC) ! 2013: return 1; ! 2014: if (TREE_VEC_LENGTH (parm) != TREE_VEC_LENGTH (arg)) ! 2015: return 1; ! 2016: for (i = TREE_VEC_LENGTH (parm) - 1; i >= 0; i--) ! 2017: if (unify (tparms, targs, ntparms, ! 2018: TREE_VEC_ELT (parm, i), TREE_VEC_ELT (arg, i), ! 2019: nsubsts)) ! 2020: return 1; ! 2021: return 0; ! 2022: } ! 2023: ! 2024: case UNINSTANTIATED_P_TYPE: ! 2025: { ! 2026: tree a; ! 2027: /* Unification of something that is not a template fails. (mrs) */ ! 2028: if (TYPE_NAME (arg) == 0) ! 2029: return 1; ! 2030: a = IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (arg)); ! 2031: /* Unification of something that is not a template fails. (mrs) */ ! 2032: if (a == 0) ! 2033: return 1; ! 2034: if (UPT_TEMPLATE (parm) != TREE_PURPOSE (a)) ! 2035: /* different templates */ ! 2036: return 1; ! 2037: return unify (tparms, targs, ntparms, UPT_PARMS (parm), TREE_VALUE (a), ! 2038: nsubsts); ! 2039: } ! 2040: ! 2041: case RECORD_TYPE: ! 2042: /* Unification of something that is not a template fails. (mrs) */ ! 2043: return 1; ! 2044: ! 2045: default: ! 2046: sorry ("use of `%s' in template type unification", ! 2047: tree_code_name [(int) TREE_CODE (parm)]); ! 2048: return 1; ! 2049: } ! 2050: } ! 2051: ! 2052: ! 2053: #undef DEBUG ! 2054: ! 2055: int ! 2056: do_pending_expansions () ! 2057: { ! 2058: struct pending_inline *i, *new_list = 0; ! 2059: ! 2060: if (!pending_template_expansions) ! 2061: return 0; ! 2062: ! 2063: #ifdef DEBUG ! 2064: fprintf (stderr, "\n\n\t\t IN DO_PENDING_EXPANSIONS\n\n"); ! 2065: #endif ! 2066: ! 2067: i = pending_template_expansions; ! 2068: while (i) ! 2069: { ! 2070: tree context; ! 2071: ! 2072: struct pending_inline *next = i->next; ! 2073: tree t = i->fndecl; ! 2074: ! 2075: int decision = 0; ! 2076: #define DECIDE(N) if(1){decision=(N); goto decided;}else ! 2077: ! 2078: my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL ! 2079: || TREE_CODE (t) == VAR_DECL, 294); ! 2080: if (TREE_ASM_WRITTEN (t)) ! 2081: DECIDE (0); ! 2082: /* If it's a method, let the class type decide it. ! 2083: @@ What if the method template is in a separate file? ! 2084: Maybe both file contexts should be taken into account? */ ! 2085: context = DECL_CONTEXT (t); ! 2086: if (context != NULL_TREE ! 2087: && TREE_CODE_CLASS (TREE_CODE (context)) == 't') ! 2088: { ! 2089: /* If `unknown', we might want a static copy. ! 2090: If `implementation', we want a global one. ! 2091: If `interface', ext ref. */ ! 2092: if (CLASSTYPE_INTERFACE_KNOWN (context)) ! 2093: DECIDE (!CLASSTYPE_INTERFACE_ONLY (context)); ! 2094: #if 0 /* This doesn't get us stuff needed only by the file initializer. */ ! 2095: DECIDE (TREE_USED (t)); ! 2096: #else /* This compiles too much stuff, but that's probably better in ! 2097: most cases than never compiling the stuff we need. */ ! 2098: DECIDE (1); ! 2099: #endif ! 2100: } ! 2101: /* else maybe call extract_interface_info? */ ! 2102: if (TREE_USED (t)) /* is this right? */ ! 2103: DECIDE (1); ! 2104: ! 2105: decided: ! 2106: #ifdef DEBUG ! 2107: print_node_brief (stderr, decision ? "yes: " : "no: ", t, 0); ! 2108: fprintf (stderr, "\t%s\n", ! 2109: (DECL_ASSEMBLER_NAME (t) ! 2110: ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t)) ! 2111: : "")); ! 2112: #endif ! 2113: if (decision == 1) ! 2114: { ! 2115: i->next = pending_inlines; ! 2116: pending_inlines = i; ! 2117: } ! 2118: else ! 2119: { ! 2120: i->next = new_list; ! 2121: new_list = i; ! 2122: } ! 2123: i = next; ! 2124: } ! 2125: pending_template_expansions = new_list; ! 2126: if (!pending_inlines) ! 2127: return 0; ! 2128: do_pending_inlines (); ! 2129: return 1; ! 2130: } ! 2131: ! 2132: ! 2133: struct pending_template { ! 2134: struct pending_template *next; ! 2135: tree id; ! 2136: }; ! 2137: ! 2138: static struct pending_template* pending_templates; ! 2139: ! 2140: void ! 2141: do_pending_templates () ! 2142: { ! 2143: struct pending_template* t; ! 2144: ! 2145: for ( t = pending_templates; t; t = t->next) ! 2146: { ! 2147: instantiate_class_template (t->id, 1); ! 2148: } ! 2149: ! 2150: for ( t = pending_templates; t; t = pending_templates) ! 2151: { ! 2152: pending_templates = t->next; ! 2153: free(t); ! 2154: } ! 2155: } ! 2156: ! 2157: static void ! 2158: add_pending_template (pt) ! 2159: tree pt; ! 2160: { ! 2161: struct pending_template *p; ! 2162: ! 2163: p = (struct pending_template *) malloc (sizeof (struct pending_template)); ! 2164: p->next = pending_templates; ! 2165: pending_templates = p; ! 2166: p->id = pt; ! 2167: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.