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