|
|
1.1 ! root 1: /* Process declarations and variables for C compiler. ! 2: Copyright (C) 1988, 1992, 1993 Free Software Foundation, Inc. ! 3: Hacked by Michael Tiemann ([email protected]) ! 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: ! 22: /* Process declarations and symbol lookup for C front end. ! 23: Also constructs types; the standard scalar types at initialization, ! 24: and structure, union, array and enum types when they are declared. */ ! 25: ! 26: /* ??? not all decl nodes are given the most useful possible ! 27: line numbers. For example, the CONST_DECLs for enum values. */ ! 28: ! 29: #include "config.h" ! 30: #include <stdio.h> ! 31: #include "tree.h" ! 32: #include "rtl.h" ! 33: #include "flags.h" ! 34: #include "cp-tree.h" ! 35: #include "cp-decl.h" ! 36: #include "cp-lex.h" ! 37: ! 38: extern tree grokdeclarator (); ! 39: extern tree get_file_function_name (); ! 40: static void grok_function_init (); ! 41: ! 42: /* A list of virtual function tables we must make sure to write out. */ ! 43: tree pending_vtables; ! 44: ! 45: /* A list of static class variables. This is needed, because a ! 46: static class variable can be declared inside the class without ! 47: an initializer, and then initialized, staticly, outside the class. */ ! 48: tree pending_statics; ! 49: ! 50: extern tree pending_addressable_inlines; ! 51: ! 52: /* Used to help generate temporary names which are unique within ! 53: a function. Reset to 0 by start_function. */ ! 54: ! 55: static int temp_name_counter; ! 56: ! 57: /* Same, but not reset. Local temp variables and global temp variables ! 58: can have the same name. */ ! 59: static int global_temp_name_counter; ! 60: ! 61: /* Flag used when debugging cp-spew.c */ ! 62: ! 63: extern int spew_debug; ! 64: ! 65: /* C (and C++) language-specific option variables. */ ! 66: ! 67: /* Nonzero means allow type mismatches in conditional expressions; ! 68: just make their values `void'. */ ! 69: ! 70: int flag_cond_mismatch; ! 71: ! 72: /* Nonzero means give `double' the same size as `float'. */ ! 73: ! 74: int flag_short_double; ! 75: ! 76: /* Nonzero means don't recognize the keyword `asm'. */ ! 77: ! 78: int flag_no_asm; ! 79: ! 80: /* Nonzero means don't recognize the non-ANSI builtin functions. */ ! 81: ! 82: int flag_no_builtin; ! 83: ! 84: /* Nonzero means do some things the same way PCC does. */ ! 85: ! 86: int flag_traditional; ! 87: ! 88: /* Nonzero means to treat bitfields as unsigned unless they say `signed'. */ ! 89: ! 90: int flag_signed_bitfields = 1; ! 91: ! 92: /* Nonzero means handle `#ident' directives. 0 means ignore them. */ ! 93: ! 94: int flag_no_ident = 0; ! 95: ! 96: /* Nonzero means handle things in ANSI, instead of GNU fashion. This ! 97: flag should be tested for language behavior that's different between ! 98: ANSI and GNU, but not so horrible as to merit a PEDANTIC label. */ ! 99: ! 100: int flag_ansi = 0; ! 101: ! 102: /* Nonzero means do argument matching for overloading according to the ! 103: ANSI rules, rather than what g++ used to believe to be correct. */ ! 104: ! 105: int flag_ansi_overloading = 0; ! 106: ! 107: /* Nonzero means do emit exported implementations of functions even if ! 108: they can be inlined. */ ! 109: ! 110: int flag_implement_inlines = 1; ! 111: ! 112: /* Nonzero means do emit exported implementations of templates, instead of ! 113: multiple static copies in each file that needs a definition. */ ! 114: ! 115: int flag_external_templates = 0; ! 116: ! 117: /* Nonzero means warn about implicit declarations. */ ! 118: ! 119: int warn_implicit = 1; ! 120: ! 121: /* Nonzero means warn when all ctors or dtors are private, and the class ! 122: has no friends. */ ! 123: ! 124: int warn_ctor_dtor_privacy = 1; ! 125: ! 126: /* Like `warn_return_type', but this is set by users, whereas ! 127: `warn_return_type' is set by the compiler. */ ! 128: ! 129: int explicit_warn_return_type; ! 130: ! 131: /* Nonzero means give string constants the type `const char *' ! 132: to get extra warnings from them. These warnings will be too numerous ! 133: to be useful, except in thoroughly ANSIfied programs. */ ! 134: ! 135: int warn_write_strings; ! 136: ! 137: /* Nonzero means warn about pointer casts that can drop a type qualifier ! 138: from the pointer target type. */ ! 139: ! 140: int warn_cast_qual; ! 141: ! 142: /* Nonzero means warn that dbx info for template class methods isn't fully ! 143: supported yet. */ ! 144: ! 145: int warn_template_debugging; ! 146: ! 147: /* Warn about traditional constructs whose meanings changed in ANSI C. */ ! 148: ! 149: int warn_traditional; ! 150: ! 151: /* Nonzero means warn about sizeof(function) or addition/subtraction ! 152: of function pointers. */ ! 153: ! 154: int warn_pointer_arith; ! 155: ! 156: /* Nonzero means warn for non-prototype function decls ! 157: or non-prototyped defs without previous prototype. */ ! 158: ! 159: int warn_strict_prototypes; ! 160: ! 161: /* Nonzero means warn for any function def without prototype decl. */ ! 162: ! 163: int warn_missing_prototypes; ! 164: ! 165: /* Nonzero means warn about multiple (redundant) decls for the same single ! 166: variable or function. */ ! 167: ! 168: int warn_redundant_decls; ! 169: ! 170: /* Warn if initializer is not completely bracketed. */ ! 171: ! 172: int warn_missing_braces; ! 173: ! 174: /* Warn about *printf or *scanf format/argument anomalies. */ ! 175: ! 176: int warn_format; ! 177: ! 178: /* Warn about a subscript that has type char. */ ! 179: ! 180: int warn_char_subscripts; ! 181: ! 182: /* Warn if a type conversion is done that might have confusing results. */ ! 183: ! 184: int warn_conversion; ! 185: ! 186: /* Warn if adding () is suggested. */ ! 187: ! 188: int warn_parentheses = 1; ! 189: ! 190: /* Non-zero means warn in function declared in derived class has the ! 191: same name as a virtual in the base class, but fails to match the ! 192: type signature of any virtual function in the base class. */ ! 193: int warn_overloaded_virtual; ! 194: ! 195: /* Non-zero means warn when converting between different enumeral types. */ ! 196: int warn_enum_clash; ! 197: ! 198: /* Non-zero means warn when declaring a class that has a non virtual ! 199: destructor, when it really ought to have a virtual one. */ ! 200: int warn_nonvdtor = 1; ! 201: ! 202: /* Nonzero means `$' can be in an identifier. ! 203: See cccp.c for reasons why this breaks some obscure ANSI C programs. */ ! 204: ! 205: #ifndef DOLLARS_IN_IDENTIFIERS ! 206: #define DOLLARS_IN_IDENTIFIERS 1 ! 207: #endif ! 208: int dollars_in_ident = DOLLARS_IN_IDENTIFIERS; ! 209: ! 210: /* Nonzero for -no-strict-prototype switch: do not consider empty ! 211: argument prototype to mean function takes no arguments. */ ! 212: ! 213: int strict_prototype = 1; ! 214: int strict_prototypes_lang_c, strict_prototypes_lang_cplusplus = 1; ! 215: ! 216: /* Nonzero means that labels can be used as first-class objects */ ! 217: ! 218: int flag_labels_ok; ! 219: ! 220: /* Non-zero means to collect statistics which might be expensive ! 221: and to print them when we are done. */ ! 222: int flag_detailed_statistics; ! 223: ! 224: /* C++ specific flags. */ ! 225: /* Nonzero for -fall-virtual: make every member function (except ! 226: constructors) lay down in the virtual function table. Calls ! 227: can then either go through the virtual function table or not, ! 228: depending. */ ! 229: ! 230: int flag_all_virtual; ! 231: ! 232: /* Zero means that `this' is a *const. This gives nice behavior in the ! 233: 2.0 world. 1 gives 1.2-compatible behavior. 2 gives Spring behavior. ! 234: -2 means we're constructing an object and it has fixed type. */ ! 235: ! 236: int flag_this_is_variable; ! 237: ! 238: /* Nonzero means memoize our member lookups. */ ! 239: ! 240: int flag_memoize_lookups; int flag_save_memoized_contexts; ! 241: ! 242: /* 3 means write out only virtuals function tables `defined' ! 243: in this implementation file. ! 244: 2 means write out only specific virtual function tables ! 245: and give them (C) public visibility. ! 246: 1 means write out virtual function tables and give them ! 247: (C) public visibility. ! 248: 0 means write out virtual function tables and give them ! 249: (C) static visibility (default). ! 250: -1 means declare virtual function tables extern. */ ! 251: ! 252: int write_virtuals; ! 253: ! 254: /* Nonzero means we should attempt to elide constructors when possible. */ ! 255: ! 256: int flag_elide_constructors; ! 257: ! 258: /* Nonzero means recognize and handle exception handling constructs. ! 259: 2 means handle exceptions the way Spring wants them handled. */ ! 260: ! 261: int flag_handle_exceptions; ! 262: ! 263: /* Nonzero means recognize and handle exception handling constructs. ! 264: Use ansi syntax and semantics. WORK IN PROGRESS! ! 265: 2 means handle exceptions the way Spring wants them handled. */ ! 266: ! 267: int flag_ansi_exceptions; ! 268: ! 269: /* Nonzero means that member functions defined in class scope are ! 270: inline by default. */ ! 271: ! 272: int flag_default_inline = 1; ! 273: ! 274: /* Controls whether enums and ints freely convert. ! 275: 1 means with complete freedom. ! 276: 0 means enums can convert to ints, but not vice-versa. */ ! 277: int flag_int_enum_equivalence; ! 278: ! 279: /* Controls whether compiler is operating under LUCID's Cadillac ! 280: system. 1 means yes, 0 means no. */ ! 281: int flag_cadillac; ! 282: ! 283: /* Controls whether compiler generates code to build objects ! 284: that can be collected when they become garbage. */ ! 285: int flag_gc; ! 286: ! 287: /* Controls whether compiler generates 'dossiers' that give ! 288: run-time type information. */ ! 289: int flag_dossier; ! 290: ! 291: /* Nonzero if we wish to output cross-referencing information ! 292: for the GNU class browser. */ ! 293: extern int flag_gnu_xref; ! 294: ! 295: /* Nonzero if compiler can make `reasonable' assumptions about ! 296: references and objects. For example, the compiler must be ! 297: conservative about the following and not assume that `a' is nonnull: ! 298: ! 299: obj &a = g (); ! 300: a.f (2); ! 301: ! 302: In general, it is `reasonable' to assume that for many programs, ! 303: and better code can be generated in that case. */ ! 304: ! 305: int flag_assume_nonnull_objects; ! 306: ! 307: /* Table of language-dependent -f options. ! 308: STRING is the option name. VARIABLE is the address of the variable. ! 309: ON_VALUE is the value to store in VARIABLE ! 310: if `-fSTRING' is seen as an option. ! 311: (If `-fno-STRING' is seen as an option, the opposite value is stored.) */ ! 312: ! 313: static struct { char *string; int *variable; int on_value;} lang_f_options[] = ! 314: { ! 315: {"signed-char", &flag_signed_char, 1}, ! 316: {"unsigned-char", &flag_signed_char, 0}, ! 317: {"signed-bitfields", &flag_signed_bitfields, 1}, ! 318: {"unsigned-bitfields", &flag_signed_bitfields, 0}, ! 319: {"short-enums", &flag_short_enums, 1}, ! 320: {"short-double", &flag_short_double, 1}, ! 321: {"cond-mismatch", &flag_cond_mismatch, 1}, ! 322: {"asm", &flag_no_asm, 0}, ! 323: {"builtin", &flag_no_builtin, 0}, ! 324: {"ident", &flag_no_ident, 0}, ! 325: {"labels-ok", &flag_labels_ok, 1}, ! 326: {"stats", &flag_detailed_statistics, 1}, ! 327: {"this-is-variable", &flag_this_is_variable, 1}, ! 328: {"strict-prototype", &strict_prototypes_lang_cplusplus, 1}, ! 329: {"all-virtual", &flag_all_virtual, 1}, ! 330: {"memoize-lookups", &flag_memoize_lookups, 1}, ! 331: {"elide-constructors", &flag_elide_constructors, 1}, ! 332: {"handle-exceptions", &flag_handle_exceptions, 1}, ! 333: {"ansi-exceptions", &flag_ansi_exceptions, 1}, ! 334: {"spring-exceptions", &flag_handle_exceptions, 2}, ! 335: {"default-inline", &flag_default_inline, 1}, ! 336: {"dollars-in-identifiers", &dollars_in_ident, 1}, ! 337: {"enum-int-equiv", &flag_int_enum_equivalence, 1}, ! 338: {"gc", &flag_gc, 1}, ! 339: {"dossier", &flag_dossier, 1}, ! 340: {"xref", &flag_gnu_xref, 1}, ! 341: {"nonnull-objects", &flag_assume_nonnull_objects, 1}, ! 342: {"implement-inlines", &flag_implement_inlines, 1}, ! 343: {"external-templates", &flag_external_templates, 1}, ! 344: {"ansi-overloading", &flag_ansi_overloading, 1}, ! 345: }; ! 346: ! 347: /* Decode the string P as a language-specific option. ! 348: Return 1 if it is recognized (and handle it); ! 349: return 0 if not recognized. */ ! 350: ! 351: int ! 352: #ifdef OBJCPLUS ! 353: cplus_decode_option (p) ! 354: #else ! 355: lang_decode_option (p) ! 356: #endif ! 357: char *p; ! 358: { ! 359: if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) ! 360: flag_traditional = 1, dollars_in_ident = 1, flag_writable_strings = 1, ! 361: flag_this_is_variable = 1; ! 362: /* The +e options are for cfront compatibility. They come in as ! 363: `-+eN', to kludge around gcc.c's argument handling. */ ! 364: else if (p[0] == '-' && p[1] == '+' && p[2] == 'e') ! 365: { ! 366: int old_write_virtuals = write_virtuals; ! 367: if (p[3] == '1') ! 368: write_virtuals = 1; ! 369: else if (p[3] == '0') ! 370: write_virtuals = -1; ! 371: else if (p[3] == '2') ! 372: write_virtuals = 2; ! 373: else error ("invalid +e option"); ! 374: if (old_write_virtuals != 0 ! 375: && write_virtuals != old_write_virtuals) ! 376: error ("conflicting +e options given"); ! 377: } ! 378: else if (p[0] == '-' && p[1] == 'f') ! 379: { ! 380: /* Some kind of -f option. ! 381: P's value is the option sans `-f'. ! 382: Search for it in the table of options. */ ! 383: int found = 0, j; ! 384: ! 385: p += 2; ! 386: /* Try special -f options. */ ! 387: ! 388: if (!strcmp (p, "save-memoized")) ! 389: { ! 390: flag_memoize_lookups = 1; ! 391: flag_save_memoized_contexts = 1; ! 392: found = 1; ! 393: } ! 394: if (!strcmp (p, "no-save-memoized")) ! 395: { ! 396: flag_memoize_lookups = 0; ! 397: flag_save_memoized_contexts = 0; ! 398: found = 1; ! 399: } ! 400: else if (! strncmp (p, "cadillac", 8)) ! 401: { ! 402: flag_cadillac = atoi (p+9); ! 403: found = 1; ! 404: } ! 405: else if (! strncmp (p, "no-cadillac", 11)) ! 406: { ! 407: flag_cadillac = 0; ! 408: found = 1; ! 409: } ! 410: else if (! strcmp (p, "gc")) ! 411: { ! 412: flag_gc = 1; ! 413: /* This must come along for the ride. */ ! 414: flag_dossier = 1; ! 415: found = 1; ! 416: } ! 417: else if (! strcmp (p, "no-gc")) ! 418: { ! 419: flag_gc = 0; ! 420: /* This must come along for the ride. */ ! 421: flag_dossier = 0; ! 422: found = 1; ! 423: } ! 424: else for (j = 0; ! 425: !found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]); ! 426: j++) ! 427: { ! 428: if (!strcmp (p, lang_f_options[j].string)) ! 429: { ! 430: *lang_f_options[j].variable = lang_f_options[j].on_value; ! 431: /* A goto here would be cleaner, ! 432: but breaks the vax pcc. */ ! 433: found = 1; ! 434: } ! 435: if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' ! 436: && ! strcmp (p+3, lang_f_options[j].string)) ! 437: { ! 438: *lang_f_options[j].variable = ! lang_f_options[j].on_value; ! 439: found = 1; ! 440: } ! 441: } ! 442: return found; ! 443: } ! 444: else if (p[0] == '-' && p[1] == 'W') ! 445: { ! 446: int setting = 1; ! 447: ! 448: /* The -W options control the warning behavior of the compiler. */ ! 449: p += 2; ! 450: ! 451: if (p[0] == 'n' && p[1] == 'o' && p[2] == '-') ! 452: setting = 0, p += 3; ! 453: ! 454: if (!strcmp (p, "implicit")) ! 455: warn_implicit = setting; ! 456: else if (!strcmp (p, "return-type")) ! 457: explicit_warn_return_type = setting; ! 458: else if (!strcmp (p, "ctor-dtor-privacy")) ! 459: warn_ctor_dtor_privacy = setting; ! 460: else if (!strcmp (p, "write-strings")) ! 461: warn_write_strings = setting; ! 462: else if (!strcmp (p, "cast-qual")) ! 463: warn_cast_qual = setting; ! 464: else if (!strcmp (p, "traditional")) ! 465: warn_traditional = setting; ! 466: else if (!strcmp (p, "char-subscripts")) ! 467: warn_char_subscripts = setting; ! 468: else if (!strcmp (p, "pointer-arith")) ! 469: warn_pointer_arith = setting; ! 470: else if (!strcmp (p, "strict-prototypes")) ! 471: warn_strict_prototypes = setting; ! 472: else if (!strcmp (p, "missing-prototypes")) ! 473: warn_missing_prototypes = setting; ! 474: else if (!strcmp (p, "redundant-decls")) ! 475: warn_redundant_decls = setting; ! 476: else if (!strcmp (p, "missing-braces")) ! 477: warn_missing_braces = setting; ! 478: else if (!strcmp (p, "format")) ! 479: warn_format = setting; ! 480: else if (!strcmp (p, "conversion")) ! 481: warn_conversion = setting; ! 482: else if (!strcmp (p, "parentheses")) ! 483: warn_parentheses = setting; ! 484: else if (!strcmp (p, "comment")) ! 485: ; /* cpp handles this one. */ ! 486: else if (!strcmp (p, "comments")) ! 487: ; /* cpp handles this one. */ ! 488: else if (!strcmp (p, "trigraphs")) ! 489: ; /* cpp handles this one. */ ! 490: else if (!strcmp (p, "import")) ! 491: ; /* cpp handles this one. */ ! 492: else if (!strcmp (p, "all")) ! 493: { ! 494: extra_warnings = setting; ! 495: explicit_warn_return_type = setting; ! 496: warn_unused = setting; ! 497: warn_implicit = setting; ! 498: warn_ctor_dtor_privacy = setting; ! 499: warn_switch = setting; ! 500: warn_missing_braces = setting; ! 501: /* We save the value of warn_uninitialized, since if they put ! 502: -Wuninitialized on the command line, we need to generate a ! 503: warning about not using it without also specifying -O. */ ! 504: if (warn_uninitialized != 1) ! 505: warn_uninitialized = (setting ? 2 : 0); ! 506: warn_template_debugging = setting; ! 507: #if 1 /* Why was this disabled? -jason */ ! 508: warn_enum_clash = setting; ! 509: #endif ! 510: } ! 511: #ifdef NEXT_SEMANTICS ! 512: else if (! strcmp (p, "style")) ! 513: { ! 514: warn_parentheses = setting; ! 515: } ! 516: #endif ! 517: ! 518: else if (!strcmp (p, "overloaded-virtual")) ! 519: warn_overloaded_virtual = setting; ! 520: else if (!strcmp (p, "enum-clash")) ! 521: warn_enum_clash = setting; ! 522: else return 0; ! 523: } ! 524: else if (!strcmp (p, "-ansi")) ! 525: flag_no_asm = 1, dollars_in_ident = 0, flag_ansi = 1; ! 526: #ifdef SPEW_DEBUG ! 527: /* Undocumented, only ever used when you're invoking cc1plus by hand, since ! 528: it's probably safe to assume no sane person would ever want to use this ! 529: under normal circumstances. */ ! 530: else if (!strcmp (p, "-spew-debug")) ! 531: spew_debug = 1; ! 532: #endif ! 533: else ! 534: return 0; ! 535: ! 536: return 1; ! 537: } ! 538: ! 539: /* Incorporate `const' and `volatile' qualifiers for member functions. ! 540: FUNCTION is a TYPE_DECL or a FUNCTION_DECL. ! 541: QUALS is a list of qualifiers. */ ! 542: tree ! 543: grok_method_quals (ctype, function, quals) ! 544: tree ctype, function, quals; ! 545: { ! 546: tree fntype = TREE_TYPE (function); ! 547: tree raises = TYPE_RAISES_EXCEPTIONS (fntype); ! 548: ! 549: do ! 550: { ! 551: extern tree ridpointers[]; ! 552: ! 553: if (TREE_VALUE (quals) == ridpointers[(int)RID_CONST]) ! 554: { ! 555: if (TYPE_READONLY (ctype)) ! 556: error ("duplicate `%s' %s", ! 557: IDENTIFIER_POINTER (TREE_VALUE (quals)), ! 558: (TREE_CODE (function) == FUNCTION_DECL ! 559: ? "for member function" : "in type declaration")); ! 560: ctype = build_type_variant (ctype, 1, TYPE_VOLATILE (ctype)); ! 561: build_pointer_type (ctype); ! 562: } ! 563: else if (TREE_VALUE (quals) == ridpointers[(int)RID_VOLATILE]) ! 564: { ! 565: if (TYPE_VOLATILE (ctype)) ! 566: error ("duplicate `%s' %s", ! 567: IDENTIFIER_POINTER (TREE_VALUE (quals)), ! 568: (TREE_CODE (function) == FUNCTION_DECL ! 569: ? "for member function" : "in type declaration")); ! 570: ctype = build_type_variant (ctype, TYPE_READONLY (ctype), 1); ! 571: build_pointer_type (ctype); ! 572: } ! 573: else ! 574: my_friendly_abort (20); ! 575: quals = TREE_CHAIN (quals); ! 576: } ! 577: while (quals); ! 578: fntype = build_cplus_method_type (ctype, TREE_TYPE (fntype), ! 579: (TREE_CODE (fntype) == METHOD_TYPE ! 580: ? TREE_CHAIN (TYPE_ARG_TYPES (fntype)) ! 581: : TYPE_ARG_TYPES (fntype))); ! 582: if (raises) ! 583: fntype = build_exception_variant (ctype, fntype, raises); ! 584: ! 585: TREE_TYPE (function) = fntype; ! 586: return ctype; ! 587: } ! 588: ! 589: /* This routine replaces cryptic DECL_NAMEs with readable DECL_NAMEs. ! 590: It leaves DECL_ASSEMBLER_NAMEs with the correct value. */ ! 591: /* This does not yet work with user defined conversion operators ! 592: It should. */ ! 593: static void ! 594: substitute_nice_name (decl) ! 595: tree decl; ! 596: { ! 597: if (DECL_NAME (decl) && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE) ! 598: { ! 599: char *n = decl_as_string (DECL_NAME (decl), 1); ! 600: if (n[strlen (n) - 1] == ' ') ! 601: n[strlen (n) - 1] = 0; ! 602: DECL_NAME (decl) = get_identifier (n); ! 603: } ! 604: } ! 605: ! 606: /* Warn when -fexternal-templates is used and #pragma ! 607: interface/implementation is not used all the times it should be, ! 608: inform the user. */ ! 609: void ! 610: warn_if_unknown_interface () ! 611: { ! 612: static int already_warned = 0; ! 613: if (++already_warned == 1) ! 614: warning ("templates that are built with -fexternal-templates should be in files that have #pragma interface/implementation"); ! 615: } ! 616: ! 617: /* A subroutine of the parser, to handle a component list. */ ! 618: tree ! 619: grok_x_components (specs, components) ! 620: tree specs, components; ! 621: { ! 622: register tree t, x; ! 623: ! 624: /* We just got some friends. They have been recorded elsewhere. */ ! 625: if (components == void_type_node) ! 626: return NULL_TREE; ! 627: ! 628: if (components == NULL_TREE) ! 629: { ! 630: t = groktypename (build_decl_list (specs, NULL_TREE)); ! 631: ! 632: if (t == NULL_TREE) ! 633: { ! 634: error ("error in component specification"); ! 635: return NULL_TREE; ! 636: } ! 637: ! 638: switch (TREE_CODE (t)) ! 639: { ! 640: case VAR_DECL: ! 641: /* Static anonymous unions come out as VAR_DECLs. */ ! 642: if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE ! 643: && ANON_AGGRNAME_P (TYPE_IDENTIFIER (TREE_TYPE (t)))) ! 644: return t; ! 645: ! 646: /* We return SPECS here, because in the parser it was ending ! 647: up with not doing anything to $$, which is what SPECS ! 648: represents. */ ! 649: return specs; ! 650: break; ! 651: ! 652: case RECORD_TYPE: ! 653: /* This code may be needed for UNION_TYPEs as ! 654: well. */ ! 655: if (TYPE_LANG_SPECIFIC (t) ! 656: && CLASSTYPE_DECLARED_EXCEPTION (t)) ! 657: shadow_tag (specs); ! 658: return NULL_TREE; ! 659: break; ! 660: ! 661: case UNION_TYPE: ! 662: case ENUMERAL_TYPE: ! 663: if (TREE_CODE (t) == UNION_TYPE ! 664: && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) ! 665: x = build_lang_field_decl (FIELD_DECL, ! 666: NULL_TREE, t); ! 667: else if (TREE_CODE (t) == ENUMERAL_TYPE) ! 668: x = grok_enum_decls (t, NULL_TREE); ! 669: else ! 670: x = NULL_TREE; ! 671: return x; ! 672: break; ! 673: ! 674: default: ! 675: if (t != void_type_node) ! 676: error ("empty component declaration"); ! 677: return NULL_TREE; ! 678: } ! 679: } ! 680: else ! 681: { ! 682: t = TREE_TYPE (components); ! 683: if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t)) ! 684: return grok_enum_decls (t, components); ! 685: else ! 686: return components; ! 687: } ! 688: } ! 689: ! 690: /* Classes overload their constituent function names automatically. ! 691: When a function name is declared in a record structure, ! 692: its name is changed to it overloaded name. Since names for ! 693: constructors and destructors can conflict, we place a leading ! 694: '$' for destructors. ! 695: ! 696: CNAME is the name of the class we are grokking for. ! 697: ! 698: FUNCTION is a FUNCTION_DECL. It was created by `grokdeclarator'. ! 699: ! 700: FLAGS contains bits saying what's special about today's ! 701: arguments. 1 == DESTRUCTOR. 2 == OPERATOR. ! 702: ! 703: If FUNCTION is a destructor, then we must add the `auto-delete' field ! 704: as a second parameter. There is some hair associated with the fact ! 705: that we must "declare" this variable in the manner consistent with the ! 706: way the rest of the arguments were declared. ! 707: ! 708: QUALS are the qualifiers for the this pointer. */ ! 709: ! 710: void ! 711: grokclassfn (ctype, cname, function, flags, quals) ! 712: tree ctype, cname, function; ! 713: enum overload_flags flags; ! 714: tree quals; ! 715: { ! 716: tree fn_name = DECL_NAME (function); ! 717: tree arg_types; ! 718: tree parm; ! 719: ! 720: if (fn_name == NULL_TREE) ! 721: { ! 722: error ("name missing for member function"); ! 723: fn_name = get_identifier ("<anonymous>"); ! 724: DECL_NAME (function) = fn_name; ! 725: } ! 726: ! 727: if (quals) ! 728: ctype = grok_method_quals (ctype, function, quals); ! 729: ! 730: arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); ! 731: if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE) ! 732: { ! 733: /* Must add the class instance variable up front. */ ! 734: /* Right now we just make this a pointer. But later ! 735: we may wish to make it special. */ ! 736: tree type = TREE_VALUE (arg_types); ! 737: ! 738: if (flags == DTOR_FLAG) ! 739: type = TYPE_MAIN_VARIANT (type); ! 740: else if (DECL_CONSTRUCTOR_P (function)) ! 741: { ! 742: if (TYPE_USES_VIRTUAL_BASECLASSES (ctype)) ! 743: { ! 744: DECL_CONSTRUCTOR_FOR_VBASE_P (function) = 1; ! 745: /* In this case we need "in-charge" flag saying whether ! 746: this constructor is responsible for initialization ! 747: of virtual baseclasses or not. */ ! 748: parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); ! 749: /* Mark the artificial `__in_chrg' parameter as "artificial". */ ! 750: DECL_SOURCE_LINE (parm) = 0; ! 751: DECL_ARG_TYPE (parm) = integer_type_node; ! 752: DECL_REGISTER (parm) = 1; ! 753: TREE_CHAIN (parm) = last_function_parms; ! 754: last_function_parms = parm; ! 755: } ! 756: } ! 757: ! 758: parm = build_decl (PARM_DECL, this_identifier, type); ! 759: /* Mark the artificial `this' parameter as "artificial". */ ! 760: DECL_SOURCE_LINE (parm) = 0; ! 761: DECL_ARG_TYPE (parm) = type; ! 762: /* We can make this a register, so long as we don't ! 763: accidentally complain if someone tries to take its address. */ ! 764: DECL_REGISTER (parm) = 1; ! 765: #if 0 ! 766: /* it is wrong to flag the object as readonly, when ! 767: flag_this_is_variable is 0. */ ! 768: if (flags != DTOR_FLAG ! 769: && (flag_this_is_variable <= 0 || TYPE_READONLY (type))) ! 770: #else ! 771: if (flags != DTOR_FLAG && TYPE_READONLY (type)) ! 772: #endif ! 773: TREE_READONLY (parm) = 1; ! 774: TREE_CHAIN (parm) = last_function_parms; ! 775: last_function_parms = parm; ! 776: } ! 777: ! 778: if (flags == DTOR_FLAG) ! 779: { ! 780: char *buf, *dbuf; ! 781: tree const_integer_type = build_type_variant (integer_type_node, 1, 0); ! 782: int len = sizeof (DESTRUCTOR_DECL_PREFIX)-1; ! 783: ! 784: arg_types = hash_tree_chain (const_integer_type, void_list_node); ! 785: TREE_SIDE_EFFECTS (arg_types) = 1; ! 786: /* Build the overload name. It will look like `7Example'. */ ! 787: if (IDENTIFIER_TYPE_VALUE (cname)) ! 788: dbuf = build_overload_name (IDENTIFIER_TYPE_VALUE (cname), 1, 1); ! 789: else if (IDENTIFIER_LOCAL_VALUE (cname)) ! 790: dbuf = build_overload_name (TREE_TYPE (IDENTIFIER_LOCAL_VALUE (cname)), 1, 1); ! 791: else ! 792: /* Using ctype fixes the `X::Y::~Y()' crash. The cname has no type when ! 793: it's defined out of the class definition, since poplevel_class wipes ! 794: it out. This used to be internal error 346. */ ! 795: dbuf = build_overload_name (ctype, 1, 1); ! 796: buf = (char *) alloca (strlen (dbuf) + sizeof (DESTRUCTOR_DECL_PREFIX)); ! 797: bcopy (DESTRUCTOR_DECL_PREFIX, buf, len); ! 798: buf[len] = '\0'; ! 799: strcat (buf, dbuf); ! 800: DECL_ASSEMBLER_NAME (function) = get_identifier (buf); ! 801: parm = build_decl (PARM_DECL, in_charge_identifier, const_integer_type); ! 802: /* Mark the artificial `__in_chrg' parameter as "artificial". */ ! 803: DECL_SOURCE_LINE (parm) = 0; ! 804: TREE_USED (parm) = 1; ! 805: #if 0 ! 806: /* We don't need to mark the __in_chrg parameter itself as `const' ! 807: since its type is already `const int'. In fact we MUST NOT mark ! 808: it as `const' cuz that will screw up the debug info (causing it ! 809: to say that the type of __in_chrg is `const const int'). */ ! 810: TREE_READONLY (parm) = 1; ! 811: #endif ! 812: DECL_ARG_TYPE (parm) = const_integer_type; ! 813: /* This is the same chain as DECL_ARGUMENTS (...). */ ! 814: TREE_CHAIN (last_function_parms) = parm; ! 815: ! 816: TREE_TYPE (function) = build_cplus_method_type (ctype, void_type_node, ! 817: arg_types); ! 818: TYPE_HAS_DESTRUCTOR (ctype) = 1; ! 819: } ! 820: else ! 821: { ! 822: tree these_arg_types; ! 823: ! 824: if (DECL_CONSTRUCTOR_FOR_VBASE_P (function)) ! 825: { ! 826: arg_types = hash_tree_chain (integer_type_node, ! 827: TREE_CHAIN (arg_types)); ! 828: TREE_TYPE (function) ! 829: = build_cplus_method_type (ctype, ! 830: TREE_TYPE (TREE_TYPE (function)), ! 831: arg_types); ! 832: arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); ! 833: } ! 834: ! 835: these_arg_types = arg_types; ! 836: ! 837: if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE) ! 838: /* Only true for static member functions. */ ! 839: these_arg_types = hash_tree_chain (TYPE_POINTER_TO (ctype), arg_types); ! 840: ! 841: DECL_ASSEMBLER_NAME (function) ! 842: = build_decl_overload (fn_name, these_arg_types, ! 843: 1 + DECL_CONSTRUCTOR_P (function)); ! 844: ! 845: #if 0 ! 846: /* This code is going into the compiler, but currently, it makes ! 847: libg++/src/Interger.cc not compile. The problem is that the nice name ! 848: winds up going into the symbol table, and conversion operations look ! 849: for the manged name. */ ! 850: substitute_nice_name (function); ! 851: #endif ! 852: } ! 853: ! 854: DECL_ARGUMENTS (function) = last_function_parms; ! 855: /* First approximations. */ ! 856: DECL_CONTEXT (function) = ctype; ! 857: DECL_CLASS_CONTEXT (function) = ctype; ! 858: } ! 859: ! 860: /* Work on the expr used by alignof (this is only called by the parser). */ ! 861: tree ! 862: grok_alignof (expr) ! 863: tree expr; ! 864: { ! 865: tree best, t; ! 866: int bestalign; ! 867: ! 868: if (TREE_CODE (expr) == COMPONENT_REF ! 869: && DECL_BIT_FIELD (TREE_OPERAND (expr, 1))) ! 870: error ("`__alignof__' applied to a bit-field"); ! 871: ! 872: if (TREE_CODE (expr) == INDIRECT_REF) ! 873: { ! 874: best = t = TREE_OPERAND (expr, 0); ! 875: bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); ! 876: ! 877: while (TREE_CODE (t) == NOP_EXPR ! 878: && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE) ! 879: { ! 880: int thisalign; ! 881: t = TREE_OPERAND (t, 0); ! 882: thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); ! 883: if (thisalign > bestalign) ! 884: best = t, bestalign = thisalign; ! 885: } ! 886: return c_alignof (TREE_TYPE (TREE_TYPE (best))); ! 887: } ! 888: else ! 889: { ! 890: /* ANSI says arrays and fns are converted inside comma. ! 891: But we can't convert them in build_compound_expr ! 892: because that would break commas in lvalues. ! 893: So do the conversion here if operand was a comma. */ ! 894: if (TREE_CODE (expr) == COMPOUND_EXPR ! 895: && (TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE ! 896: || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)) ! 897: expr = default_conversion (expr); ! 898: return c_alignof (TREE_TYPE (expr)); ! 899: } ! 900: } ! 901: ! 902: /* Create an ARRAY_REF, checking for the user doing things backwards ! 903: along the way. */ ! 904: tree ! 905: grok_array_decl (array_expr, index_exp) ! 906: tree array_expr, index_exp; ! 907: { ! 908: tree type = TREE_TYPE (array_expr); ! 909: ! 910: if (type == error_mark_node || index_exp == error_mark_node) ! 911: return error_mark_node; ! 912: if (type == NULL_TREE) ! 913: { ! 914: /* Something has gone very wrong. Assume we are mistakenly reducing ! 915: an expression instead of a declaration. */ ! 916: error ("parser may be lost: is there a '{' missing somewhere?"); ! 917: return NULL_TREE; ! 918: } ! 919: ! 920: if (TREE_CODE (type) == OFFSET_TYPE ! 921: || TREE_CODE (type) == REFERENCE_TYPE) ! 922: type = TREE_TYPE (type); ! 923: ! 924: /* If they have an `operator[]', use that. */ ! 925: if (TYPE_LANG_SPECIFIC (type) ! 926: && TYPE_OVERLOADS_ARRAY_REF (type)) ! 927: return build_opfncall (ARRAY_REF, LOOKUP_NORMAL, ! 928: array_expr, index_exp, NULL_TREE); ! 929: ! 930: /* Otherwise, create an ARRAY_REF for a pointer or array type. */ ! 931: if (TREE_CODE (type) == POINTER_TYPE ! 932: || TREE_CODE (type) == ARRAY_TYPE) ! 933: return build_array_ref (array_expr, index_exp); ! 934: ! 935: /* Woops, looks like they did something like `5[a]' instead of `a[5]'. ! 936: We don't emit a warning or error for this, since it's allowed ! 937: by ARM $8.2.4. */ ! 938: ! 939: type = TREE_TYPE (index_exp); ! 940: ! 941: if (TREE_CODE (type) == OFFSET_TYPE ! 942: || TREE_CODE (type) == REFERENCE_TYPE) ! 943: type = TREE_TYPE (type); ! 944: ! 945: if (TYPE_LANG_SPECIFIC (type) ! 946: && TYPE_OVERLOADS_ARRAY_REF (type)) ! 947: error ("array expression backwards"); ! 948: else if (TREE_CODE (type) == POINTER_TYPE ! 949: || TREE_CODE (type) == ARRAY_TYPE) ! 950: return build_array_ref (index_exp, array_expr); ! 951: else ! 952: error("`[]' applied to non-pointer type"); ! 953: ! 954: /* We gave an error, so give an error. Huh? */ ! 955: return error_mark_node; ! 956: } ! 957: ! 958: /* Given the cast expression EXP, checking out its validity. Either return ! 959: an error_mark_node if there was an unavoidable error, return a cast to ! 960: void for trying to delete a pointer w/ the value 0, or return the ! 961: call to delete. If DOING_VEC is 1, we handle things differently ! 962: for doing an array delete. If DOING_VEC is 2, they gave us the ! 963: array size as an argument to delete. ! 964: Implements ARM $5.3.4. This is called from the parser. */ ! 965: tree ! 966: delete_sanity (exp, size, doing_vec) ! 967: tree exp, size; ! 968: int doing_vec; ! 969: { ! 970: tree t = stabilize_reference (convert_from_reference (exp)); ! 971: tree type = TREE_TYPE (t); ! 972: enum tree_code code = TREE_CODE (type); ! 973: /* For a regular vector delete (aka, no size argument) we will pass ! 974: this down as a NULL_TREE into build_vec_delete. */ ! 975: tree maxindex = NULL_TREE; ! 976: /* This is used for deleting arrays. */ ! 977: tree elt_size; ! 978: ! 979: switch (doing_vec) ! 980: { ! 981: case 2: ! 982: maxindex = build_binary_op (MINUS_EXPR, size, integer_one_node, 1); ! 983: if (! flag_traditional) ! 984: pedwarn ("ANSI C++ forbids array size in vector delete"); ! 985: /* Fall through. */ ! 986: case 1: ! 987: elt_size = c_sizeof (type); ! 988: break; ! 989: default: ! 990: if (code != POINTER_TYPE) ! 991: { ! 992: cp_error ("type `%#T' argument given to `delete', expected pointer", ! 993: type); ! 994: return error_mark_node; ! 995: } ! 996: ! 997: /* Deleting a pointer with the value zero is legal and has no effect. */ ! 998: if (integer_zerop (t)) ! 999: return build1 (NOP_EXPR, void_type_node, t); ! 1000: } ! 1001: ! 1002: /* You can't delete a pointer to constant. */ ! 1003: if (code == POINTER_TYPE && TREE_READONLY (TREE_TYPE (type))) ! 1004: { ! 1005: error ("`const *' cannot be deleted"); ! 1006: return error_mark_node; ! 1007: } ! 1008: ! 1009: /* If the type has no destructor, then we should build a regular ! 1010: delete, instead of a vector delete. Otherwise, we would end ! 1011: up passing a bogus offset into __builtin_delete, which is ! 1012: not expecting it. */ ! 1013: if (doing_vec ! 1014: && TREE_CODE (type) == POINTER_TYPE ! 1015: && !TYPE_HAS_DESTRUCTOR (TREE_TYPE (type))) ! 1016: doing_vec = 0; ! 1017: ! 1018: if (doing_vec) ! 1019: return build_vec_delete (t, maxindex, elt_size, NULL_TREE, ! 1020: integer_one_node, integer_two_node); ! 1021: else ! 1022: return build_delete (type, t, integer_three_node, ! 1023: LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE, ! 1024: TYPE_HAS_DESTRUCTOR (TREE_TYPE (type))); ! 1025: } ! 1026: ! 1027: /* Sanity check: report error if this function FUNCTION is not ! 1028: really a member of the class (CTYPE) it is supposed to belong to. ! 1029: CNAME is the same here as it is for grokclassfn above. */ ! 1030: ! 1031: void ! 1032: check_classfn (ctype, cname, function) ! 1033: tree ctype, cname, function; ! 1034: { ! 1035: tree fn_name = DECL_NAME (function); ! 1036: tree fndecl; ! 1037: int need_quotes = 0; ! 1038: tree method_vec = CLASSTYPE_METHOD_VEC (ctype); ! 1039: tree *methods = 0; ! 1040: tree *end = 0; ! 1041: ! 1042: if (method_vec != 0) ! 1043: { ! 1044: methods = &TREE_VEC_ELT (method_vec, 0); ! 1045: end = TREE_VEC_END (method_vec); ! 1046: ! 1047: /* First suss out ctors and dtors. */ ! 1048: if (*methods && fn_name == cname) ! 1049: goto got_it; ! 1050: ! 1051: while (++methods != end) ! 1052: { ! 1053: if (fn_name == DECL_NAME (*methods)) ! 1054: { ! 1055: got_it: ! 1056: fndecl = *methods; ! 1057: while (fndecl) ! 1058: { ! 1059: if (DECL_ASSEMBLER_NAME (function) == DECL_ASSEMBLER_NAME (fndecl)) ! 1060: return; ! 1061: fndecl = DECL_CHAIN (fndecl); ! 1062: } ! 1063: break; /* loser */ ! 1064: } ! 1065: } ! 1066: } ! 1067: ! 1068: if (methods != end) ! 1069: cp_error ("argument list for `%D' does not match any in class `%T'", ! 1070: fn_name, ctype); ! 1071: else ! 1072: { ! 1073: methods = 0; ! 1074: cp_error ("no `%D' member function declared in class `%T'", ! 1075: fn_name, ctype); ! 1076: } ! 1077: ! 1078: /* If we did not find the method in the class, add it to ! 1079: avoid spurious errors. */ ! 1080: add_method (ctype, methods, function); ! 1081: } ! 1082: ! 1083: /* Process the specs, declarator (NULL if omitted) and width (NULL if omitted) ! 1084: of a structure component, returning a FIELD_DECL node. ! 1085: QUALS is a list of type qualifiers for this decl (such as for declaring ! 1086: const member functions). ! 1087: ! 1088: This is done during the parsing of the struct declaration. ! 1089: The FIELD_DECL nodes are chained together and the lot of them ! 1090: are ultimately passed to `build_struct' to make the RECORD_TYPE node. ! 1091: ! 1092: C++: ! 1093: ! 1094: If class A defines that certain functions in class B are friends, then ! 1095: the way I have set things up, it is B who is interested in permission ! 1096: granted by A. However, it is in A's context that these declarations ! 1097: are parsed. By returning a void_type_node, class A does not attempt ! 1098: to incorporate the declarations of the friends within its structure. ! 1099: ! 1100: DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING ! 1101: CHANGES TO CODE IN `start_method'. */ ! 1102: ! 1103: tree ! 1104: grokfield (declarator, declspecs, raises, init, asmspec_tree) ! 1105: tree declarator, declspecs, raises, init, asmspec_tree; ! 1106: { ! 1107: register tree value; ! 1108: char *asmspec = 0; ! 1109: ! 1110: /* Convert () initializers to = initializers. */ ! 1111: if (init == NULL_TREE && declarator != NULL_TREE ! 1112: && TREE_CODE (declarator) == CALL_EXPR ! 1113: && TREE_OPERAND (declarator, 0) ! 1114: && (TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE ! 1115: || TREE_CODE (TREE_OPERAND (declarator, 0)) == SCOPE_REF) ! 1116: && parmlist_is_exprlist (TREE_OPERAND (declarator, 1))) ! 1117: { ! 1118: init = TREE_OPERAND (declarator, 1); ! 1119: declarator = TREE_OPERAND (declarator, 0); ! 1120: } ! 1121: ! 1122: if (init ! 1123: && TREE_CODE (init) == TREE_LIST ! 1124: && TREE_VALUE (init) == error_mark_node ! 1125: && TREE_CHAIN (init) == NULL_TREE) ! 1126: init = NULL_TREE; ! 1127: ! 1128: value = grokdeclarator (declarator, declspecs, FIELD, init != 0, raises); ! 1129: if (! value) ! 1130: return NULL_TREE; /* friends went bad. */ ! 1131: ! 1132: /* Pass friendly classes back. */ ! 1133: if (TREE_CODE (value) == VOID_TYPE) ! 1134: return void_type_node; ! 1135: ! 1136: if (DECL_NAME (value) != NULL_TREE ! 1137: && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_' ! 1138: && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr")) ! 1139: cp_error ("member `%D' conflicts with virtual function table field name", value); ! 1140: ! 1141: /* Stash away type declarations. */ ! 1142: if (TREE_CODE (value) == TYPE_DECL) ! 1143: { ! 1144: DECL_NONLOCAL (value) = 1; ! 1145: CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1; ! 1146: #if !NEW_CLASS_SCOPING ! 1147: set_identifier_type_value (DECL_NAME (value), TREE_TYPE (value)); ! 1148: #endif ! 1149: pushdecl_class_level (value); ! 1150: return value; ! 1151: } ! 1152: ! 1153: if (DECL_IN_AGGR_P (value)) ! 1154: { ! 1155: cp_error ("`%D' is already defined in the class %T", value, ! 1156: DECL_CONTEXT (value)); ! 1157: return void_type_node; ! 1158: } ! 1159: ! 1160: if (flag_cadillac) ! 1161: cadillac_start_decl (value); ! 1162: ! 1163: if (asmspec_tree) ! 1164: asmspec = TREE_STRING_POINTER (asmspec_tree); ! 1165: ! 1166: if (init) ! 1167: { ! 1168: if (TREE_CODE (value) == FUNCTION_DECL) ! 1169: { ! 1170: grok_function_init (value, init); ! 1171: init = NULL_TREE; ! 1172: } ! 1173: else if (pedantic) ! 1174: { ! 1175: if (DECL_NAME (value)) ! 1176: pedwarn ("ANSI C++ forbids initialization of member `%s'", ! 1177: IDENTIFIER_POINTER (DECL_NAME (value))); ! 1178: else ! 1179: pedwarn ("ANSI C++ forbids initialization of fields"); ! 1180: ! 1181: init = NULL_TREE; ! 1182: } ! 1183: else ! 1184: { ! 1185: /* We allow initializers to become parameters to base initializers. */ ! 1186: if (TREE_CODE (init) == TREE_LIST) ! 1187: { ! 1188: if (TREE_CHAIN (init) == NULL_TREE) ! 1189: init = TREE_VALUE (init); ! 1190: else ! 1191: init = digest_init (TREE_TYPE (value), init, (tree *)0); ! 1192: } ! 1193: ! 1194: if (TREE_CODE (init) == CONST_DECL) ! 1195: init = DECL_INITIAL (init); ! 1196: else if (TREE_READONLY_DECL_P (init)) ! 1197: init = decl_constant_value (init); ! 1198: else if (TREE_CODE (init) == CONSTRUCTOR) ! 1199: init = digest_init (TREE_TYPE (value), init, (tree *)0); ! 1200: my_friendly_assert (TREE_PERMANENT (init), 192); ! 1201: if (init == error_mark_node) ! 1202: /* We must make this look different than `error_mark_node' ! 1203: because `decl_const_value' would mis-interpret it ! 1204: as only meaning that this VAR_DECL is defined. */ ! 1205: init = build1 (NOP_EXPR, TREE_TYPE (value), init); ! 1206: else if (! TREE_CONSTANT (init)) ! 1207: { ! 1208: /* We can allow references to things that are effectively ! 1209: static, since references are initialized with the address. */ ! 1210: if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE ! 1211: || (TREE_STATIC (init) == 0 ! 1212: && (TREE_CODE_CLASS (TREE_CODE (init)) != 'd' ! 1213: || DECL_EXTERNAL (init) == 0))) ! 1214: { ! 1215: error ("field initializer is not constant"); ! 1216: init = error_mark_node; ! 1217: } ! 1218: } ! 1219: } ! 1220: } ! 1221: ! 1222: /* The corresponding pop_obstacks is in finish_decl. */ ! 1223: push_obstacks_nochange (); ! 1224: ! 1225: if (TREE_CODE (value) == VAR_DECL) ! 1226: { ! 1227: /* We cannot call pushdecl here, because that would ! 1228: fill in the value of our TREE_CHAIN. Instead, we ! 1229: modify finish_decl to do the right thing, namely, to ! 1230: put this decl out straight away. */ ! 1231: if (TREE_STATIC (value)) ! 1232: { ! 1233: /* current_class_type can be NULL_TREE in case of error. */ ! 1234: if (asmspec == 0 && current_class_type) ! 1235: { ! 1236: tree name; ! 1237: char *buf, *buf2; ! 1238: ! 1239: buf2 = build_overload_name (current_class_type, 1, 1); ! 1240: buf = (char *)alloca (IDENTIFIER_LENGTH (DECL_NAME (value)) ! 1241: + sizeof (STATIC_NAME_FORMAT) ! 1242: + strlen (buf2)); ! 1243: sprintf (buf, STATIC_NAME_FORMAT, buf2, ! 1244: IDENTIFIER_POINTER (DECL_NAME (value))); ! 1245: name = get_identifier (buf); ! 1246: TREE_PUBLIC (value) = 1; ! 1247: DECL_INITIAL (value) = error_mark_node; ! 1248: DECL_ASSEMBLER_NAME (value) = name; ! 1249: } ! 1250: pending_statics = perm_tree_cons (NULL_TREE, value, pending_statics); ! 1251: ! 1252: /* Static consts need not be initialized in the class definition. */ ! 1253: if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (value))) ! 1254: { ! 1255: static int explanation = 0; ! 1256: ! 1257: error ("initializer invalid for static member with constructor"); ! 1258: if (explanation++ == 0) ! 1259: error ("(you really want to initialize it separately)"); ! 1260: init = 0; ! 1261: } ! 1262: /* Force the compiler to know when an uninitialized static ! 1263: const member is being used. */ ! 1264: if (TYPE_READONLY (value) && init == 0) ! 1265: TREE_USED (value) = 1; ! 1266: } ! 1267: DECL_INITIAL (value) = init; ! 1268: DECL_IN_AGGR_P (value) = 1; ! 1269: ! 1270: finish_decl (value, init, asmspec_tree, 1); ! 1271: pushdecl_class_level (value); ! 1272: return value; ! 1273: } ! 1274: if (TREE_CODE (value) == FIELD_DECL) ! 1275: { ! 1276: if (asmspec) ! 1277: DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec); ! 1278: if (DECL_INITIAL (value) == error_mark_node) ! 1279: init = error_mark_node; ! 1280: finish_decl (value, init, asmspec_tree, 1); ! 1281: DECL_INITIAL (value) = init; ! 1282: DECL_IN_AGGR_P (value) = 1; ! 1283: return value; ! 1284: } ! 1285: if (TREE_CODE (value) == FUNCTION_DECL) ! 1286: { ! 1287: /* grokdeclarator defers setting this. */ ! 1288: TREE_PUBLIC (value) = 1; ! 1289: if (DECL_CHAIN (value) != NULL_TREE) ! 1290: { ! 1291: /* Need a fresh node here so that we don't get circularity ! 1292: when we link these together. */ ! 1293: value = copy_node (value); ! 1294: /* When does this happen? */ ! 1295: my_friendly_assert (init == NULL_TREE, 193); ! 1296: } ! 1297: finish_decl (value, init, asmspec_tree, 1); ! 1298: ! 1299: /* Pass friends back this way. */ ! 1300: if (DECL_FRIEND_P (value)) ! 1301: return void_type_node; ! 1302: ! 1303: DECL_IN_AGGR_P (value) = 1; ! 1304: return value; ! 1305: } ! 1306: my_friendly_abort (21); ! 1307: /* NOTREACHED */ ! 1308: return NULL_TREE; ! 1309: } ! 1310: ! 1311: /* Like `grokfield', but for bitfields. ! 1312: WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node. */ ! 1313: ! 1314: tree ! 1315: grokbitfield (declarator, declspecs, width) ! 1316: tree declarator, declspecs, width; ! 1317: { ! 1318: register tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, NULL_TREE); ! 1319: ! 1320: if (! value) return NULL_TREE; /* friends went bad. */ ! 1321: ! 1322: /* Pass friendly classes back. */ ! 1323: if (TREE_CODE (value) == VOID_TYPE) ! 1324: return void_type_node; ! 1325: ! 1326: if (TREE_CODE (value) == TYPE_DECL) ! 1327: { ! 1328: cp_error ("cannot declare `%D' to be a bitfield type", value); ! 1329: return NULL_TREE; ! 1330: } ! 1331: ! 1332: if (DECL_IN_AGGR_P (value)) ! 1333: { ! 1334: cp_error ("`%D' is already defined in the class %T", value, ! 1335: DECL_CONTEXT (value)); ! 1336: return void_type_node; ! 1337: } ! 1338: ! 1339: GNU_xref_member (current_class_name, value); ! 1340: ! 1341: if (TREE_STATIC (value)) ! 1342: { ! 1343: cp_error ("static member `%D' cannot be a bitfield", value); ! 1344: return NULL_TREE; ! 1345: } ! 1346: finish_decl (value, NULL_TREE, NULL_TREE, 0); ! 1347: ! 1348: if (width != error_mark_node) ! 1349: { ! 1350: /* detect invalid field size. */ ! 1351: if (TREE_CODE (width) == CONST_DECL) ! 1352: width = DECL_INITIAL (width); ! 1353: else if (TREE_READONLY_DECL_P (width)) ! 1354: width = decl_constant_value (width); ! 1355: if (TREE_CODE (width) != INTEGER_CST) ! 1356: { ! 1357: cp_error ("structure field `%D' width not an integer constant", ! 1358: value); ! 1359: DECL_INITIAL (value) = NULL_TREE; ! 1360: } ! 1361: else ! 1362: { ! 1363: constant_expression_warning (width); ! 1364: DECL_INITIAL (value) = width; ! 1365: DECL_BIT_FIELD (value) = 1; ! 1366: } ! 1367: } ! 1368: ! 1369: DECL_IN_AGGR_P (value) = 1; ! 1370: return value; ! 1371: } ! 1372: ! 1373: /* Like GROKFIELD, except that the declarator has been ! 1374: buried in DECLSPECS. Find the declarator, and ! 1375: return something that looks like it came from ! 1376: GROKFIELD. */ ! 1377: tree ! 1378: groktypefield (declspecs, parmlist) ! 1379: tree declspecs; ! 1380: tree parmlist; ! 1381: { ! 1382: tree spec = declspecs; ! 1383: tree prev = NULL_TREE; ! 1384: ! 1385: tree type_id = NULL_TREE; ! 1386: tree quals = NULL_TREE; ! 1387: tree lengths = NULL_TREE; ! 1388: tree decl = NULL_TREE; ! 1389: ! 1390: while (spec) ! 1391: { ! 1392: register tree id = TREE_VALUE (spec); ! 1393: ! 1394: if (TREE_CODE (spec) != TREE_LIST) ! 1395: /* Certain parse errors slip through. For example, ! 1396: `int class ();' is not caught by the parser. Try ! 1397: weakly to recover here. */ ! 1398: return NULL_TREE; ! 1399: ! 1400: if (TREE_CODE (id) == TYPE_DECL ! 1401: || (TREE_CODE (id) == IDENTIFIER_NODE && TREE_TYPE (id))) ! 1402: { ! 1403: /* We have a constructor/destructor or ! 1404: conversion operator. Use it. */ ! 1405: if (prev) ! 1406: TREE_CHAIN (prev) = TREE_CHAIN (spec); ! 1407: else ! 1408: declspecs = TREE_CHAIN (spec); ! 1409: ! 1410: type_id = id; ! 1411: goto found; ! 1412: } ! 1413: prev = spec; ! 1414: spec = TREE_CHAIN (spec); ! 1415: } ! 1416: ! 1417: /* Nope, we have a conversion operator to a scalar type or something ! 1418: else, that includes things like constructor declarations for ! 1419: templates. */ ! 1420: spec = declspecs; ! 1421: while (spec) ! 1422: { ! 1423: tree id = TREE_VALUE (spec); ! 1424: ! 1425: if (TREE_CODE (id) == IDENTIFIER_NODE) ! 1426: { ! 1427: if (id == ridpointers[(int)RID_INT] ! 1428: || id == ridpointers[(int)RID_DOUBLE] ! 1429: || id == ridpointers[(int)RID_FLOAT] ! 1430: || id == ridpointers[(int)RID_WCHAR]) ! 1431: { ! 1432: if (type_id) ! 1433: error ("extra `%s' ignored", ! 1434: IDENTIFIER_POINTER (id)); ! 1435: else ! 1436: type_id = id; ! 1437: } ! 1438: else if (id == ridpointers[(int)RID_LONG] ! 1439: || id == ridpointers[(int)RID_SHORT] ! 1440: || id == ridpointers[(int)RID_CHAR]) ! 1441: { ! 1442: lengths = tree_cons (NULL_TREE, id, lengths); ! 1443: } ! 1444: else if (id == ridpointers[(int)RID_VOID]) ! 1445: { ! 1446: if (type_id) ! 1447: error ("spurious `void' type ignored"); ! 1448: else ! 1449: error ("conversion to `void' type invalid"); ! 1450: } ! 1451: else if (id == ridpointers[(int)RID_AUTO] ! 1452: || id == ridpointers[(int)RID_REGISTER] ! 1453: || id == ridpointers[(int)RID_TYPEDEF] ! 1454: || id == ridpointers[(int)RID_CONST] ! 1455: || id == ridpointers[(int)RID_VOLATILE]) ! 1456: { ! 1457: error ("type specifier `%s' used invalidly", ! 1458: IDENTIFIER_POINTER (id)); ! 1459: } ! 1460: else if (id == ridpointers[(int)RID_FRIEND] ! 1461: || id == ridpointers[(int)RID_VIRTUAL] ! 1462: || id == ridpointers[(int)RID_INLINE] ! 1463: || id == ridpointers[(int)RID_UNSIGNED] ! 1464: || id == ridpointers[(int)RID_SIGNED] ! 1465: || id == ridpointers[(int)RID_STATIC] ! 1466: || id == ridpointers[(int)RID_EXTERN]) ! 1467: { ! 1468: quals = tree_cons (NULL_TREE, id, quals); ! 1469: } ! 1470: else ! 1471: { ! 1472: /* Happens when we have a global typedef ! 1473: and a class-local member function with ! 1474: the same name. */ ! 1475: type_id = id; ! 1476: goto found; ! 1477: } ! 1478: } ! 1479: else if (TREE_CODE (id) == RECORD_TYPE) ! 1480: { ! 1481: type_id = TYPE_NAME (id); ! 1482: if (TREE_CODE (type_id) == TYPE_DECL) ! 1483: type_id = DECL_NAME (type_id); ! 1484: if (type_id == NULL_TREE) ! 1485: error ("identifier for aggregate type conversion omitted"); ! 1486: } ! 1487: else if (TREE_CODE_CLASS (TREE_CODE (id)) == 't') ! 1488: error ("`operator' missing on conversion operator or tag missing from type"); ! 1489: else ! 1490: my_friendly_abort (194); ! 1491: spec = TREE_CHAIN (spec); ! 1492: } ! 1493: ! 1494: if (type_id) ! 1495: declspecs = chainon (lengths, quals); ! 1496: else if (lengths) ! 1497: { ! 1498: if (TREE_CHAIN (lengths)) ! 1499: error ("multiple length specifiers"); ! 1500: type_id = ridpointers[(int)RID_INT]; ! 1501: declspecs = chainon (lengths, quals); ! 1502: } ! 1503: else if (quals) ! 1504: { ! 1505: error ("no type given, defaulting to `operator int ...'"); ! 1506: type_id = ridpointers[(int)RID_INT]; ! 1507: declspecs = quals; ! 1508: } ! 1509: else ! 1510: return NULL_TREE; ! 1511: ! 1512: found: ! 1513: decl = grokdeclarator (build_parse_node (CALL_EXPR, type_id, parmlist, NULL_TREE), ! 1514: declspecs, FIELD, 0, NULL_TREE); ! 1515: if (decl == NULL_TREE) ! 1516: return NULL_TREE; ! 1517: ! 1518: if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CHAIN (decl) != NULL_TREE) ! 1519: { ! 1520: /* Need a fresh node here so that we don't get circularity ! 1521: when we link these together. */ ! 1522: decl = copy_node (decl); ! 1523: } ! 1524: ! 1525: if (decl == void_type_node ! 1526: || (TREE_CODE (decl) == FUNCTION_DECL ! 1527: && TREE_CODE (TREE_TYPE (decl)) != METHOD_TYPE)) ! 1528: /* bunch of friends. */ ! 1529: return decl; ! 1530: ! 1531: if (DECL_IN_AGGR_P (decl)) ! 1532: { ! 1533: cp_error ("`%D' already defined in the class ", decl); ! 1534: return void_type_node; ! 1535: } ! 1536: ! 1537: finish_decl (decl, NULL_TREE, NULL_TREE, 0); ! 1538: ! 1539: /* If this declaration is common to another declaration ! 1540: complain about such redundancy, and return NULL_TREE ! 1541: so that we don't build a circular list. */ ! 1542: if (DECL_CHAIN (decl)) ! 1543: { ! 1544: cp_error ("function `%D' declared twice in class %T", decl, ! 1545: DECL_CONTEXT (decl)); ! 1546: return NULL_TREE; ! 1547: } ! 1548: DECL_IN_AGGR_P (decl) = 1; ! 1549: return decl; ! 1550: } ! 1551: ! 1552: /* The precedence rules of this grammar (or any other deterministic LALR ! 1553: grammar, for that matter), place the CALL_EXPR somewhere where we ! 1554: may not want it. The solution is to grab the first CALL_EXPR we see, ! 1555: pretend that that is the one that belongs to the parameter list of ! 1556: the type conversion function, and leave everything else alone. ! 1557: We pull it out in place. ! 1558: ! 1559: CALL_REQUIRED is non-zero if we should complain if a CALL_EXPR ! 1560: does not appear in DECL. */ ! 1561: tree ! 1562: grokoptypename (decl, call_required) ! 1563: tree decl; ! 1564: int call_required; ! 1565: { ! 1566: tree tmp, last; ! 1567: ! 1568: my_friendly_assert (TREE_CODE (decl) == TYPE_EXPR, 195); ! 1569: ! 1570: tmp = TREE_OPERAND (decl, 0); ! 1571: last = NULL_TREE; ! 1572: ! 1573: while (tmp) ! 1574: { ! 1575: switch (TREE_CODE (tmp)) ! 1576: { ! 1577: case CALL_EXPR: ! 1578: { ! 1579: tree parms = TREE_OPERAND (tmp, 1); ! 1580: ! 1581: if (last) ! 1582: TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0); ! 1583: else ! 1584: TREE_OPERAND (decl, 0) = TREE_OPERAND (tmp, 0); ! 1585: ! 1586: last = grokdeclarator (TREE_OPERAND (decl, 0), ! 1587: TREE_TYPE (decl), ! 1588: TYPENAME, 0, NULL_TREE); ! 1589: TREE_OPERAND (tmp, 0) = build_typename_overload (last); ! 1590: TREE_TYPE (TREE_OPERAND (tmp, 0)) = last; ! 1591: ! 1592: if (parms ! 1593: && TREE_CODE (TREE_VALUE (parms)) == TREE_LIST) ! 1594: TREE_VALUE (parms) ! 1595: = grokdeclarator (TREE_VALUE (TREE_VALUE (parms)), ! 1596: TREE_PURPOSE (TREE_VALUE (parms)), ! 1597: TYPENAME, 0, NULL_TREE); ! 1598: if (parms) ! 1599: { ! 1600: if (TREE_VALUE (parms) != void_type_node) ! 1601: cp_error ("`operator %T' requires empty parameter list", ! 1602: last); ! 1603: else ! 1604: /* Canonicalize parameter lists. */ ! 1605: TREE_OPERAND (tmp, 1) = void_list_node; ! 1606: } ! 1607: ! 1608: return tmp; ! 1609: } ! 1610: ! 1611: case INDIRECT_REF: ! 1612: case ADDR_EXPR: ! 1613: case ARRAY_REF: ! 1614: break; ! 1615: ! 1616: case SCOPE_REF: ! 1617: /* This is legal when declaring a conversion to ! 1618: something of type pointer-to-member. */ ! 1619: if (TREE_CODE (TREE_OPERAND (tmp, 1)) == INDIRECT_REF) ! 1620: { ! 1621: tmp = TREE_OPERAND (tmp, 1); ! 1622: } ! 1623: else ! 1624: { ! 1625: #if 0 ! 1626: /* We may need to do this if grokdeclarator cannot handle this. */ ! 1627: error ("type `member of class %s' invalid return type", ! 1628: TYPE_NAME_STRING (TREE_OPERAND (tmp, 0))); ! 1629: TREE_OPERAND (tmp, 1) = build_parse_node (INDIRECT_REF, TREE_OPERAND (tmp, 1)); ! 1630: #endif ! 1631: tmp = TREE_OPERAND (tmp, 1); ! 1632: } ! 1633: break; ! 1634: ! 1635: default: ! 1636: my_friendly_abort (196); ! 1637: } ! 1638: last = tmp; ! 1639: tmp = TREE_OPERAND (tmp, 0); ! 1640: } ! 1641: ! 1642: last = grokdeclarator (TREE_OPERAND (decl, 0), ! 1643: TREE_TYPE (decl), ! 1644: TYPENAME, 0, NULL_TREE); ! 1645: ! 1646: if (call_required) ! 1647: cp_error ("`operator %T' construct requires parameter list", last); ! 1648: ! 1649: tmp = build_parse_node (CALL_EXPR, build_typename_overload (last), ! 1650: void_list_node, NULL_TREE); ! 1651: TREE_TYPE (TREE_OPERAND (tmp, 0)) = last; ! 1652: return tmp; ! 1653: } ! 1654: ! 1655: /* When a function is declared with an initializer, ! 1656: do the right thing. Currently, there are two possibilities: ! 1657: ! 1658: class B ! 1659: { ! 1660: public: ! 1661: // initialization possibility #1. ! 1662: virtual void f () = 0; ! 1663: int g (); ! 1664: }; ! 1665: ! 1666: class D1 : B ! 1667: { ! 1668: public: ! 1669: int d1; ! 1670: // error, no f (); ! 1671: }; ! 1672: ! 1673: class D2 : B ! 1674: { ! 1675: public: ! 1676: int d2; ! 1677: void f (); ! 1678: }; ! 1679: ! 1680: class D3 : B ! 1681: { ! 1682: public: ! 1683: int d3; ! 1684: // initialization possibility #2 ! 1685: void f () = B::f; ! 1686: }; ! 1687: ! 1688: */ ! 1689: ! 1690: static void ! 1691: grok_function_init (decl, init) ! 1692: tree decl; ! 1693: tree init; ! 1694: { ! 1695: /* An initializer for a function tells how this function should ! 1696: be inherited. */ ! 1697: tree type = TREE_TYPE (decl); ! 1698: extern tree abort_fndecl; ! 1699: ! 1700: if (TREE_CODE (type) == FUNCTION_TYPE) ! 1701: cp_error ("initializer specified for non-member function `%D'", decl); ! 1702: else if (DECL_VINDEX (decl) == NULL_TREE) ! 1703: cp_error ("initializer specified for non-virtual method `%D'", decl); ! 1704: else if (integer_zerop (init)) ! 1705: { ! 1706: /* Mark this function as being "defined". */ ! 1707: DECL_INITIAL (decl) = error_mark_node; ! 1708: /* pure virtual destructors must be defined. */ ! 1709: if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl))) ! 1710: { ! 1711: /* Give this node rtl from `abort'. */ ! 1712: DECL_RTL (decl) = DECL_RTL (abort_fndecl); ! 1713: } ! 1714: DECL_ABSTRACT_VIRTUAL_P (decl) = 1; ! 1715: } ! 1716: else if (TREE_CODE (init) == OFFSET_REF ! 1717: && TREE_OPERAND (init, 0) == NULL_TREE ! 1718: && TREE_CODE (TREE_TYPE (init)) == METHOD_TYPE) ! 1719: { ! 1720: tree basetype = DECL_CLASS_CONTEXT (init); ! 1721: tree basefn = TREE_OPERAND (init, 1); ! 1722: if (TREE_CODE (basefn) != FUNCTION_DECL) ! 1723: cp_error ("non-method initializer invalid for method `%D'", decl); ! 1724: else if (! BINFO_OFFSET_ZEROP (TYPE_BINFO (DECL_CLASS_CONTEXT (basefn)))) ! 1725: sorry ("base member function from other than first base class"); ! 1726: else ! 1727: { ! 1728: tree binfo = get_binfo (basetype, TYPE_METHOD_BASETYPE (type), 1); ! 1729: if (binfo == error_mark_node) ! 1730: ; ! 1731: else if (binfo == 0) ! 1732: error_not_base_type (TYPE_METHOD_BASETYPE (TREE_TYPE (init)), ! 1733: TYPE_METHOD_BASETYPE (type)); ! 1734: else ! 1735: { ! 1736: /* Mark this function as being defined, ! 1737: and give it new rtl. */ ! 1738: DECL_INITIAL (decl) = error_mark_node; ! 1739: DECL_RTL (decl) = DECL_RTL (basefn); ! 1740: } ! 1741: } ! 1742: } ! 1743: else ! 1744: cp_error ("invalid initializer for virtual method `%D'", decl); ! 1745: } ! 1746: ! 1747: /* When we get a declaration of the form ! 1748: ! 1749: type cname::fname ... ! 1750: ! 1751: the node for `cname::fname' gets built here in a special way. ! 1752: Namely, we push into `cname's scope. When this declaration is ! 1753: processed, we pop back out. */ ! 1754: tree ! 1755: build_push_scope (cname, name) ! 1756: tree cname; ! 1757: tree name; ! 1758: { ! 1759: extern int current_class_depth; ! 1760: tree ctype, rval; ! 1761: ! 1762: if (cname == error_mark_node) ! 1763: return error_mark_node; ! 1764: ! 1765: ctype = IDENTIFIER_TYPE_VALUE (cname); ! 1766: ! 1767: if (ctype == NULL_TREE || ! IS_AGGR_TYPE (ctype)) ! 1768: { ! 1769: error ("`%s' not defined as aggregate type", IDENTIFIER_POINTER (cname)); ! 1770: return name; ! 1771: } ! 1772: ! 1773: rval = build_parse_node (SCOPE_REF, cname, name); ! 1774: ! 1775: /* Don't need to push the scope if we're already in it. ! 1776: We also don't need to push the scope for a ptr-to-member/method. */ ! 1777: ! 1778: if (ctype == current_class_type || TREE_CODE (name) != IDENTIFIER_NODE) ! 1779: return rval; ! 1780: ! 1781: /* We do need to push the scope in this case, since CTYPE helps ! 1782: determine subsequent intializers (i.e., Foo::Bar x = foo_enum_1;). */ ! 1783: ! 1784: #if NEW_CLASS_SCOPING ! 1785: push_nested_class (ctype, 3); ! 1786: #else ! 1787: pushclass (ctype, 3); ! 1788: #endif ! 1789: TREE_COMPLEXITY (rval) = current_class_depth; ! 1790: return rval; ! 1791: } ! 1792: ! 1793: void cplus_decl_attributes (decl, attributes) ! 1794: tree decl, attributes; ! 1795: { ! 1796: if (decl) ! 1797: decl_attributes (decl, attributes); ! 1798: } ! 1799: ! 1800: /* CONSTRUCTOR_NAME: ! 1801: Return the name for the constructor (or destructor) for the ! 1802: specified class. Argument can be RECORD_TYPE, TYPE_DECL, or ! 1803: IDENTIFIER_NODE. When given a template, this routine doesn't ! 1804: lose the specialization. */ ! 1805: tree ! 1806: constructor_name_full (thing) ! 1807: tree thing; ! 1808: { ! 1809: tree t; ! 1810: if (TREE_CODE (thing) == UNINSTANTIATED_P_TYPE) ! 1811: return DECL_NAME (UPT_TEMPLATE (thing)); ! 1812: if (TREE_CODE (thing) == RECORD_TYPE || TREE_CODE (thing) == UNION_TYPE) ! 1813: thing = TYPE_NAME (thing); ! 1814: if (TREE_CODE (thing) == TYPE_DECL ! 1815: || (TREE_CODE (thing) == TEMPLATE_DECL ! 1816: && DECL_TEMPLATE_IS_CLASS (thing))) ! 1817: thing = DECL_NAME (thing); ! 1818: my_friendly_assert (TREE_CODE (thing) == IDENTIFIER_NODE, 197); ! 1819: return thing; ! 1820: } ! 1821: ! 1822: /* CONSTRUCTOR_NAME: ! 1823: Return the name for the constructor (or destructor) for the ! 1824: specified class. Argument can be RECORD_TYPE, TYPE_DECL, or ! 1825: IDENTIFIER_NODE. When given a template, return the plain ! 1826: unspecialized name. */ ! 1827: tree ! 1828: constructor_name (thing) ! 1829: tree thing; ! 1830: { ! 1831: tree t; ! 1832: thing = constructor_name_full (thing); ! 1833: t = IDENTIFIER_TEMPLATE (thing); ! 1834: if (!t) ! 1835: return thing; ! 1836: t = TREE_PURPOSE (t); ! 1837: return DECL_NAME (t); ! 1838: } ! 1839: ! 1840: /* Cache the value of this class's main virtual function table pointer ! 1841: in a register variable. This will save one indirection if a ! 1842: more than one virtual function call is made this function. */ ! 1843: void ! 1844: setup_vtbl_ptr () ! 1845: { ! 1846: extern rtx base_init_insns; ! 1847: ! 1848: if (base_init_insns == 0 ! 1849: && DECL_CONSTRUCTOR_P (current_function_decl)) ! 1850: emit_base_init (current_class_type, 0); ! 1851: ! 1852: #if 0 ! 1853: /* This has something a little wrong with it. ! 1854: ! 1855: On a sun4, code like: ! 1856: ! 1857: be L6 ! 1858: ld [%i0],%o1 ! 1859: ! 1860: is generated, when the below is used when -O4 is given. The delay ! 1861: slot it filled with an instruction that is safe, when this isn't ! 1862: used, like in: ! 1863: ! 1864: be L6 ! 1865: sethi %hi(LC1),%o0 ! 1866: ld [%i0],%o1 ! 1867: ! 1868: on code like: ! 1869: ! 1870: struct A { ! 1871: virtual void print() { printf("xxx"); } ! 1872: void f(); ! 1873: }; ! 1874: ! 1875: void A::f() { ! 1876: if (this) { ! 1877: print(); ! 1878: } else { ! 1879: printf("0"); ! 1880: } ! 1881: } ! 1882: ! 1883: And that is why this is disabled for now. (mrs) ! 1884: */ ! 1885: ! 1886: if ((flag_this_is_variable & 1) == 0 ! 1887: && optimize ! 1888: && current_class_type ! 1889: && CLASSTYPE_VSIZE (current_class_type) ! 1890: && ! DECL_STATIC_FUNCTION_P (current_function_decl)) ! 1891: { ! 1892: tree vfield = build_vfield_ref (C_C_D, current_class_type); ! 1893: current_vtable_decl = CLASSTYPE_VTBL_PTR (current_class_type); ! 1894: DECL_RTL (current_vtable_decl) = 0; ! 1895: DECL_INITIAL (current_vtable_decl) = error_mark_node; ! 1896: /* Have to cast the initializer, since it may have come from a ! 1897: more base class then we ascribe CURRENT_VTABLE_DECL to be. */ ! 1898: finish_decl (current_vtable_decl, convert_force (TREE_TYPE (current_vtable_decl), vfield), 0, 0); ! 1899: current_vtable_decl = build_indirect_ref (current_vtable_decl, NULL_PTR); ! 1900: } ! 1901: else ! 1902: #endif ! 1903: current_vtable_decl = NULL_TREE; ! 1904: } ! 1905: ! 1906: /* Record the existence of an addressable inline function. */ ! 1907: void ! 1908: mark_inline_for_output (decl) ! 1909: tree decl; ! 1910: { ! 1911: if (DECL_PENDING_INLINE_INFO (decl) != 0 ! 1912: && ! DECL_PENDING_INLINE_INFO (decl)->deja_vu) ! 1913: { ! 1914: struct pending_inline *t = pending_inlines; ! 1915: my_friendly_assert (DECL_SAVED_INSNS (decl) == 0, 198); ! 1916: while (t) ! 1917: { ! 1918: if (t == DECL_PENDING_INLINE_INFO (decl)) ! 1919: break; ! 1920: t = t->next; ! 1921: } ! 1922: if (t == 0) ! 1923: { ! 1924: t = DECL_PENDING_INLINE_INFO (decl); ! 1925: t->next = pending_inlines; ! 1926: pending_inlines = t; ! 1927: } ! 1928: DECL_PENDING_INLINE_INFO (decl) = 0; ! 1929: } ! 1930: pending_addressable_inlines = perm_tree_cons (NULL_TREE, decl, ! 1931: pending_addressable_inlines); ! 1932: } ! 1933: ! 1934: void ! 1935: clear_temp_name () ! 1936: { ! 1937: temp_name_counter = 0; ! 1938: } ! 1939: ! 1940: /* Hand off a unique name which can be used for variable we don't really ! 1941: want to know about anyway, for example, the anonymous variables which ! 1942: are needed to make references work. Declare this thing so we can use it. ! 1943: The variable created will be of type TYPE. ! 1944: ! 1945: STATICP is nonzero if this variable should be static. */ ! 1946: ! 1947: tree ! 1948: get_temp_name (type, staticp) ! 1949: tree type; ! 1950: int staticp; ! 1951: { ! 1952: char buf[sizeof (AUTO_TEMP_FORMAT) + 20]; ! 1953: tree decl; ! 1954: int toplev = global_bindings_p (); ! 1955: ! 1956: push_obstacks_nochange (); ! 1957: if (toplev || staticp) ! 1958: { ! 1959: end_temporary_allocation (); ! 1960: sprintf (buf, AUTO_TEMP_FORMAT, global_temp_name_counter++); ! 1961: decl = pushdecl_top_level (build_decl (VAR_DECL, get_identifier (buf), type)); ! 1962: } ! 1963: else ! 1964: { ! 1965: sprintf (buf, AUTO_TEMP_FORMAT, temp_name_counter++); ! 1966: decl = pushdecl (build_decl (VAR_DECL, get_identifier (buf), type)); ! 1967: } ! 1968: TREE_USED (decl) = 1; ! 1969: TREE_STATIC (decl) = staticp; ! 1970: ! 1971: /* If this is a local variable, then lay out its rtl now. ! 1972: Otherwise, callers of this function are responsible for dealing ! 1973: with this variable's rtl. */ ! 1974: if (! toplev) ! 1975: { ! 1976: expand_decl (decl); ! 1977: expand_decl_init (decl); ! 1978: } ! 1979: pop_obstacks (); ! 1980: ! 1981: return decl; ! 1982: } ! 1983: ! 1984: /* Get a variable which we can use for multiple assignments. ! 1985: It is not entered into current_binding_level, because ! 1986: that breaks things when it comes time to do final cleanups ! 1987: (which take place "outside" the binding contour of the function). */ ! 1988: tree ! 1989: get_temp_regvar (type, init) ! 1990: tree type, init; ! 1991: { ! 1992: static char buf[sizeof (AUTO_TEMP_FORMAT) + 20] = { '_' }; ! 1993: tree decl; ! 1994: ! 1995: sprintf (buf+1, AUTO_TEMP_FORMAT, temp_name_counter++); ! 1996: decl = build_decl (VAR_DECL, get_identifier (buf), type); ! 1997: TREE_USED (decl) = 1; ! 1998: DECL_REGISTER (decl) = 1; ! 1999: ! 2000: if (init) ! 2001: store_init_value (decl, init); ! 2002: ! 2003: /* We can expand these without fear, since they cannot need ! 2004: constructors or destructors. */ ! 2005: expand_decl (decl); ! 2006: expand_decl_init (decl); ! 2007: ! 2008: if (type_needs_gc_entry (type)) ! 2009: DECL_GC_OFFSET (decl) = size_int (++current_function_obstack_index); ! 2010: ! 2011: return decl; ! 2012: } ! 2013: ! 2014: /* Make the macro TEMP_NAME_P available to units which do not ! 2015: include c-tree.h. */ ! 2016: int ! 2017: temp_name_p (decl) ! 2018: tree decl; ! 2019: { ! 2020: return TEMP_NAME_P (decl); ! 2021: } ! 2022: ! 2023: /* Finish off the processing of a UNION_TYPE structure. ! 2024: If there are static members, then all members are ! 2025: static, and must be laid out together. If the ! 2026: union is an anonymous union, we arrange for that ! 2027: as well. PUBLIC_P is nonzero if this union is ! 2028: not declared static. */ ! 2029: void ! 2030: finish_anon_union (anon_union_decl) ! 2031: tree anon_union_decl; ! 2032: { ! 2033: tree type = TREE_TYPE (anon_union_decl); ! 2034: tree field, main_decl = NULL_TREE; ! 2035: tree elems = NULL_TREE; ! 2036: int public_p = TREE_PUBLIC (anon_union_decl); ! 2037: int static_p = TREE_STATIC (anon_union_decl); ! 2038: int external_p = DECL_EXTERNAL (anon_union_decl); ! 2039: ! 2040: if ((field = TYPE_FIELDS (type)) == NULL_TREE) ! 2041: return; ! 2042: ! 2043: if (public_p) ! 2044: { ! 2045: error ("global anonymous unions must be declared static"); ! 2046: return; ! 2047: } ! 2048: ! 2049: while (field) ! 2050: { ! 2051: tree decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field)); ! 2052: /* tell `pushdecl' that this is not tentative. */ ! 2053: DECL_INITIAL (decl) = error_mark_node; ! 2054: TREE_PUBLIC (decl) = public_p; ! 2055: TREE_STATIC (decl) = static_p; ! 2056: DECL_EXTERNAL (decl) = external_p; ! 2057: decl = pushdecl (decl); ! 2058: ! 2059: /* Only write out one anon union element--choose the one that ! 2060: can hold them all. */ ! 2061: if (main_decl == NULL_TREE ! 2062: && simple_cst_equal (DECL_SIZE (decl), DECL_SIZE (anon_union_decl))) ! 2063: { ! 2064: main_decl = decl; ! 2065: } ! 2066: else ! 2067: { ! 2068: /* ??? This causes there to be no debug info written out ! 2069: about this decl. */ ! 2070: TREE_ASM_WRITTEN (decl) = 1; ! 2071: } ! 2072: ! 2073: DECL_INITIAL (decl) = NULL_TREE; ! 2074: /* If there's a cleanup to do, it belongs in the ! 2075: TREE_PURPOSE of the following TREE_LIST. */ ! 2076: elems = tree_cons (NULL_TREE, decl, elems); ! 2077: TREE_TYPE (elems) = type; ! 2078: field = TREE_CHAIN (field); ! 2079: } ! 2080: if (static_p) ! 2081: { ! 2082: make_decl_rtl (main_decl, 0, global_bindings_p ()); ! 2083: DECL_RTL (anon_union_decl) = DECL_RTL (main_decl); ! 2084: } ! 2085: ! 2086: /* The following call assumes that there are never any cleanups ! 2087: for anonymous unions--a reasonable assumption. */ ! 2088: expand_anon_union_decl (anon_union_decl, NULL_TREE, elems); ! 2089: ! 2090: if (flag_cadillac) ! 2091: cadillac_finish_anon_union (anon_union_decl); ! 2092: } ! 2093: ! 2094: /* Finish and output a table which is generated by the compiler. ! 2095: NAME is the name to give the table. ! 2096: TYPE is the type of the table entry. ! 2097: INIT is all the elements in the table. ! 2098: PUBLICP is non-zero if this table should be given external visibility. */ ! 2099: tree ! 2100: finish_table (name, type, init, publicp) ! 2101: tree name, type, init; ! 2102: int publicp; ! 2103: { ! 2104: tree itype, atype, decl; ! 2105: static tree empty_table; ! 2106: int is_empty = 0; ! 2107: tree asmspec; ! 2108: ! 2109: itype = build_index_type (size_int (list_length (init) - 1)); ! 2110: atype = build_cplus_array_type (type, itype); ! 2111: layout_type (atype); ! 2112: ! 2113: if (TREE_VALUE (init) == integer_zero_node ! 2114: && TREE_CHAIN (init) == NULL_TREE) ! 2115: { ! 2116: if (empty_table == NULL_TREE) ! 2117: { ! 2118: empty_table = get_temp_name (atype, 1); ! 2119: init = build (CONSTRUCTOR, atype, NULL_TREE, init); ! 2120: TREE_CONSTANT (init) = 1; ! 2121: TREE_STATIC (init) = 1; ! 2122: DECL_INITIAL (empty_table) = init; ! 2123: asmspec = build_string (IDENTIFIER_LENGTH (DECL_NAME (empty_table)), ! 2124: IDENTIFIER_POINTER (DECL_NAME (empty_table))); ! 2125: finish_decl (empty_table, init, asmspec, 0); ! 2126: } ! 2127: is_empty = 1; ! 2128: } ! 2129: ! 2130: if (name == NULL_TREE) ! 2131: { ! 2132: if (is_empty) ! 2133: return empty_table; ! 2134: decl = get_temp_name (atype, 1); ! 2135: } ! 2136: else ! 2137: { ! 2138: decl = build_decl (VAR_DECL, name, atype); ! 2139: decl = pushdecl (decl); ! 2140: TREE_STATIC (decl) = 1; ! 2141: } ! 2142: ! 2143: if (is_empty == 0) ! 2144: { ! 2145: TREE_PUBLIC (decl) = publicp; ! 2146: init = build (CONSTRUCTOR, atype, NULL_TREE, init); ! 2147: TREE_CONSTANT (init) = 1; ! 2148: TREE_STATIC (init) = 1; ! 2149: DECL_INITIAL (decl) = init; ! 2150: asmspec = build_string (IDENTIFIER_LENGTH (DECL_NAME (decl)), ! 2151: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2152: } ! 2153: else ! 2154: { ! 2155: /* This will cause DECL to point to EMPTY_TABLE in rtl-land. */ ! 2156: DECL_EXTERNAL (decl) = 1; ! 2157: TREE_STATIC (decl) = 0; ! 2158: init = 0; ! 2159: asmspec = build_string (IDENTIFIER_LENGTH (DECL_NAME (empty_table)), ! 2160: IDENTIFIER_POINTER (DECL_NAME (empty_table))); ! 2161: } ! 2162: ! 2163: finish_decl (decl, init, asmspec, 0); ! 2164: return decl; ! 2165: } ! 2166: ! 2167: /* Finish processing a builtin type TYPE. It's name is NAME, ! 2168: its fields are in the array FIELDS. LEN is the number of elements ! 2169: in FIELDS minus one, or put another way, it is the maximum subscript ! 2170: used in FIELDS. ! 2171: ! 2172: It is given the same alignment as ALIGN_TYPE. */ ! 2173: void ! 2174: finish_builtin_type (type, name, fields, len, align_type) ! 2175: tree type; ! 2176: char *name; ! 2177: tree fields[]; ! 2178: int len; ! 2179: tree align_type; ! 2180: { ! 2181: register int i; ! 2182: ! 2183: TYPE_FIELDS (type) = fields[0]; ! 2184: for (i = 0; i < len; i++) ! 2185: { ! 2186: layout_type (TREE_TYPE (fields[i])); ! 2187: DECL_FIELD_CONTEXT (fields[i]) = type; ! 2188: TREE_CHAIN (fields[i]) = fields[i+1]; ! 2189: } ! 2190: DECL_FIELD_CONTEXT (fields[i]) = type; ! 2191: DECL_CLASS_CONTEXT (fields[i]) = type; ! 2192: TYPE_ALIGN (type) = TYPE_ALIGN (align_type); ! 2193: layout_type (type); ! 2194: #if 0 /* not yet, should get fixed properly later */ ! 2195: TYPE_NAME (type) = make_type_decl (get_identifier (name), type); ! 2196: #else ! 2197: TYPE_NAME (type) = build_decl (TYPE_DECL, get_identifier (name), type); ! 2198: #endif ! 2199: layout_decl (TYPE_NAME (type), 0); ! 2200: } ! 2201: ! 2202: /* Auxiliary functions to make type signatures for ! 2203: `operator new' and `operator delete' correspond to ! 2204: what compiler will be expecting. */ ! 2205: ! 2206: extern tree sizetype; ! 2207: ! 2208: tree ! 2209: coerce_new_type (type) ! 2210: tree type; ! 2211: { ! 2212: int e1 = 0, e2 = 0; ! 2213: ! 2214: if (TREE_CODE (type) == METHOD_TYPE) ! 2215: type = build_function_type (TREE_TYPE (type), TREE_CHAIN (TYPE_ARG_TYPES (type))); ! 2216: if (TREE_TYPE (type) != ptr_type_node) ! 2217: e1 = 1, error ("`operator new' must return type `void *'"); ! 2218: ! 2219: /* Technically the type must be `size_t', but we may not know ! 2220: what that is. */ ! 2221: if (TYPE_ARG_TYPES (type) == NULL_TREE) ! 2222: e1 = 1, error ("`operator new' takes type `size_t' parameter"); ! 2223: else if (TREE_CODE (TREE_VALUE (TYPE_ARG_TYPES (type))) != INTEGER_TYPE ! 2224: || TYPE_PRECISION (TREE_VALUE (TYPE_ARG_TYPES (type))) != TYPE_PRECISION (sizetype)) ! 2225: e2 = 1, error ("`operator new' takes type `size_t' as first parameter"); ! 2226: if (e2) ! 2227: type = build_function_type (ptr_type_node, tree_cons (NULL_TREE, sizetype, TREE_CHAIN (TYPE_ARG_TYPES (type)))); ! 2228: else if (e1) ! 2229: type = build_function_type (ptr_type_node, TYPE_ARG_TYPES (type)); ! 2230: return type; ! 2231: } ! 2232: ! 2233: tree ! 2234: coerce_delete_type (type) ! 2235: tree type; ! 2236: { ! 2237: int e1 = 0, e2 = 0, e3 = 0; ! 2238: tree arg_types = TYPE_ARG_TYPES (type); ! 2239: ! 2240: if (TREE_CODE (type) == METHOD_TYPE) ! 2241: { ! 2242: type = build_function_type (TREE_TYPE (type), TREE_CHAIN (arg_types)); ! 2243: arg_types = TREE_CHAIN (arg_types); ! 2244: } ! 2245: if (TREE_TYPE (type) != void_type_node) ! 2246: e1 = 1, error ("`operator delete' must return type `void'"); ! 2247: if (arg_types == NULL_TREE ! 2248: || TREE_VALUE (arg_types) != ptr_type_node) ! 2249: e2 = 1, error ("`operator delete' takes type `void *' as first parameter"); ! 2250: ! 2251: if (arg_types ! 2252: && TREE_CHAIN (arg_types) ! 2253: && TREE_CHAIN (arg_types) != void_list_node) ! 2254: { ! 2255: /* Again, technically this argument must be `size_t', but again ! 2256: we may not know what that is. */ ! 2257: tree t2 = TREE_VALUE (TREE_CHAIN (arg_types)); ! 2258: if (TREE_CODE (t2) != INTEGER_TYPE ! 2259: || TYPE_PRECISION (t2) != TYPE_PRECISION (sizetype)) ! 2260: e3 = 1, error ("second argument to `operator delete' must be of type `size_t'"); ! 2261: else if (TREE_CHAIN (TREE_CHAIN (arg_types)) != void_list_node) ! 2262: { ! 2263: e3 = 1; ! 2264: if (TREE_CHAIN (TREE_CHAIN (arg_types))) ! 2265: error ("too many arguments in declaration of `operator delete'"); ! 2266: else ! 2267: error ("`...' invalid in specification of `operator delete'"); ! 2268: } ! 2269: } ! 2270: if (e3) ! 2271: arg_types = tree_cons (NULL_TREE, ptr_type_node, build_tree_list (NULL_TREE, sizetype)); ! 2272: else if (e3 |= e2) ! 2273: { ! 2274: if (arg_types == NULL_TREE) ! 2275: arg_types = void_list_node; ! 2276: else ! 2277: arg_types = tree_cons (NULL_TREE, ptr_type_node, TREE_CHAIN (arg_types)); ! 2278: } ! 2279: else e3 |= e1; ! 2280: ! 2281: if (e3) ! 2282: type = build_function_type (void_type_node, arg_types); ! 2283: ! 2284: return type; ! 2285: } ! 2286: ! 2287: static void ! 2288: write_vtable_entries (decl) ! 2289: tree decl; ! 2290: { ! 2291: tree entries = TREE_CHAIN (CONSTRUCTOR_ELTS (DECL_INITIAL (decl))); ! 2292: ! 2293: if (flag_dossier) ! 2294: entries = TREE_CHAIN (entries); ! 2295: ! 2296: for (; entries; entries = TREE_CHAIN (entries)) ! 2297: { ! 2298: tree fnaddr = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries)); ! 2299: tree fn = TREE_OPERAND (fnaddr, 0); ! 2300: if (! DECL_EXTERNAL (fn) && ! TREE_ASM_WRITTEN (fn) ! 2301: && DECL_SAVED_INSNS (fn)) ! 2302: { ! 2303: if (TREE_PUBLIC (DECL_CLASS_CONTEXT (fn))) ! 2304: TREE_PUBLIC (fn) = 1; ! 2305: TREE_ADDRESSABLE (fn) = 1; ! 2306: temporary_allocation (); ! 2307: output_inline_function (fn); ! 2308: permanent_allocation (); ! 2309: } ! 2310: else ! 2311: assemble_external (fn); ! 2312: } ! 2313: } ! 2314: ! 2315: /* Note even though prev is never used in here, walk_vtables ! 2316: expects this to have two arguments, so concede. */ ! 2317: static void ! 2318: finish_vtable_typedecl (prev, vars) ! 2319: tree prev, vars; ! 2320: { ! 2321: tree decl = TYPE_BINFO_VTABLE (TREE_TYPE (vars)); ! 2322: ! 2323: /* If we are controlled by `+e2', obey. */ ! 2324: if (write_virtuals == 2) ! 2325: { ! 2326: tree binfo = value_member (DECL_NAME (vars), pending_vtables); ! 2327: if (binfo) ! 2328: TREE_PURPOSE (binfo) = void_type_node; ! 2329: else ! 2330: decl = NULL_TREE; ! 2331: } ! 2332: /* If this type has inline virtual functions, then ! 2333: write those functions out now. */ ! 2334: if (decl && write_virtuals >= 0 ! 2335: && ! DECL_EXTERNAL (decl) && (TREE_PUBLIC (decl) || TREE_USED (decl))) ! 2336: write_vtable_entries (decl); ! 2337: } ! 2338: ! 2339: static void ! 2340: finish_vtable_vardecl (prev, vars) ! 2341: tree prev, vars; ! 2342: { ! 2343: if (write_virtuals >= 0 ! 2344: && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars))) ! 2345: { ! 2346: extern tree the_null_vtable_entry; ! 2347: ! 2348: /* Stuff this virtual function table's size into ! 2349: `pfn' slot of `the_null_vtable_entry'. */ ! 2350: tree nelts = array_type_nelts (TREE_TYPE (vars)); ! 2351: SET_FNADDR_FROM_VTABLE_ENTRY (the_null_vtable_entry, nelts); ! 2352: /* Kick out the dossier before writing out the vtable. */ ! 2353: if (flag_dossier) ! 2354: rest_of_decl_compilation (TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (TREE_CHAIN (CONSTRUCTOR_ELTS (DECL_INITIAL (vars))))), 0), 0, 1, 1); ! 2355: ! 2356: /* Write it out. */ ! 2357: write_vtable_entries (vars); ! 2358: if (TREE_TYPE (DECL_INITIAL (vars)) == 0) ! 2359: store_init_value (vars, DECL_INITIAL (vars)); ! 2360: ! 2361: #ifdef DWARF_DEBUGGING_INFO ! 2362: if (write_symbols == DWARF_DEBUG) ! 2363: { ! 2364: /* Mark the VAR_DECL node representing the vtable itself as a ! 2365: "gratuitous" one, thereby forcing dwarfout.c to ignore it. ! 2366: It is rather important that such things be ignored because ! 2367: any effort to actually generate DWARF for them will run ! 2368: into trouble when/if we encounter code like: ! 2369: ! 2370: #pragma interface ! 2371: struct S { virtual void member (); }; ! 2372: ! 2373: because the artificial declaration of the vtable itself (as ! 2374: manufactured by the g++ front end) will say that the vtable ! 2375: is a static member of `S' but only *after* the debug output ! 2376: for the definition of `S' has already been output. This causes ! 2377: grief because the DWARF entry for the definition of the vtable ! 2378: will try to refer back to an earlier *declaration* of the ! 2379: vtable as a static member of `S' and there won't be one. ! 2380: We might be able to arrange to have the "vtable static member" ! 2381: attached to the member list for `S' before the debug info for ! 2382: `S' get written (which would solve the problem) but that would ! 2383: require more intrusive changes to the g++ front end. */ ! 2384: ! 2385: DECL_IGNORED_P (vars) = 1; ! 2386: } ! 2387: #endif /* DWARF_DEBUGGING_INFO */ ! 2388: ! 2389: rest_of_decl_compilation (vars, 0, 1, 1); ! 2390: } ! 2391: /* We know that PREV must be non-zero here. */ ! 2392: TREE_CHAIN (prev) = TREE_CHAIN (vars); ! 2393: } ! 2394: ! 2395: void ! 2396: walk_vtables (typedecl_fn, vardecl_fn) ! 2397: register void (*typedecl_fn)(); ! 2398: register void (*vardecl_fn)(); ! 2399: { ! 2400: tree prev, vars; ! 2401: ! 2402: for (prev = 0, vars = getdecls (); vars; vars = TREE_CHAIN (vars)) ! 2403: { ! 2404: register tree type = TREE_TYPE (vars); ! 2405: ! 2406: if (TREE_CODE (vars) == TYPE_DECL ! 2407: && type != error_mark_node ! 2408: && TYPE_LANG_SPECIFIC (type) ! 2409: && CLASSTYPE_VSIZE (type)) ! 2410: { ! 2411: if (typedecl_fn) (*typedecl_fn) (prev, vars); ! 2412: } ! 2413: else if (TREE_CODE (vars) == VAR_DECL && DECL_VIRTUAL_P (vars)) ! 2414: { ! 2415: if (vardecl_fn) (*vardecl_fn) (prev, vars); ! 2416: } ! 2417: else ! 2418: prev = vars; ! 2419: } ! 2420: } ! 2421: ! 2422: extern int parse_time, varconst_time; ! 2423: ! 2424: #define TIMEVAR(VAR, BODY) \ ! 2425: do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0) ! 2426: ! 2427: /* This routine is called from the last rule in yyparse (). ! 2428: Its job is to create all the code needed to initialize and ! 2429: destroy the global aggregates. We do the destruction ! 2430: first, since that way we only need to reverse the decls once. */ ! 2431: ! 2432: void ! 2433: finish_file () ! 2434: { ! 2435: extern int lineno; ! 2436: int start_time, this_time; ! 2437: ! 2438: tree fnname; ! 2439: tree vars = static_aggregates; ! 2440: int needs_cleaning = 0, needs_messing_up = 0; ! 2441: ! 2442: if (flag_detailed_statistics) ! 2443: dump_tree_statistics (); ! 2444: ! 2445: /* Bad parse errors. Just forget about it. */ ! 2446: if (! global_bindings_p () || current_class_type) ! 2447: return; ! 2448: ! 2449: start_time = get_run_time (); ! 2450: ! 2451: /* Push into C language context, because that's all ! 2452: we'll need here. */ ! 2453: push_lang_context (lang_name_c); ! 2454: ! 2455: /* Set up the name of the file-level functions we may need. */ ! 2456: /* Use a global object (which is already required to be unique over ! 2457: the program) rather than the file name (which imposes extra ! 2458: constraints). -- [email protected], 10 Jan 1990. */ ! 2459: ! 2460: /* See if we really need the hassle. */ ! 2461: while (vars && needs_cleaning == 0) ! 2462: { ! 2463: tree decl = TREE_VALUE (vars); ! 2464: tree type = TREE_TYPE (decl); ! 2465: if (TYPE_NEEDS_DESTRUCTOR (type)) ! 2466: { ! 2467: needs_cleaning = 1; ! 2468: needs_messing_up = 1; ! 2469: break; ! 2470: } ! 2471: else ! 2472: needs_messing_up |= TYPE_NEEDS_CONSTRUCTING (type); ! 2473: vars = TREE_CHAIN (vars); ! 2474: } ! 2475: if (needs_cleaning == 0) ! 2476: goto mess_up; ! 2477: ! 2478: /* Otherwise, GDB can get confused, because in only knows ! 2479: about source for LINENO-1 lines. */ ! 2480: lineno -= 1; ! 2481: ! 2482: fnname = get_file_function_name ('D'); ! 2483: start_function (void_list_node, build_parse_node (CALL_EXPR, fnname, void_list_node, NULL_TREE), 0, 0); ! 2484: fnname = DECL_ASSEMBLER_NAME (current_function_decl); ! 2485: store_parm_decls (); ! 2486: ! 2487: pushlevel (0); ! 2488: clear_last_expr (); ! 2489: push_momentary (); ! 2490: expand_start_bindings (0); ! 2491: ! 2492: /* These must be done in backward order to destroy, ! 2493: in which they happen to be! */ ! 2494: while (vars) ! 2495: { ! 2496: tree decl = TREE_VALUE (vars); ! 2497: tree type = TREE_TYPE (decl); ! 2498: tree temp = TREE_PURPOSE (vars); ! 2499: ! 2500: if (TYPE_NEEDS_DESTRUCTOR (type)) ! 2501: { ! 2502: if (TREE_STATIC (vars)) ! 2503: expand_start_cond (build_binary_op (NE_EXPR, temp, integer_zero_node, 1), 0); ! 2504: if (TREE_CODE (type) == ARRAY_TYPE) ! 2505: temp = decl; ! 2506: else ! 2507: { ! 2508: mark_addressable (decl); ! 2509: temp = build1 (ADDR_EXPR, TYPE_POINTER_TO (type), decl); ! 2510: } ! 2511: temp = build_delete (TREE_TYPE (temp), temp, ! 2512: integer_two_node, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); ! 2513: expand_expr_stmt (temp); ! 2514: ! 2515: if (TREE_STATIC (vars)) ! 2516: expand_end_cond (); ! 2517: } ! 2518: vars = TREE_CHAIN (vars); ! 2519: } ! 2520: ! 2521: expand_end_bindings (getdecls(), 1, 0); ! 2522: poplevel (1, 0, 0); ! 2523: pop_momentary (); ! 2524: ! 2525: finish_function (lineno, 0); ! 2526: ! 2527: assemble_destructor (IDENTIFIER_POINTER (fnname)); ! 2528: ! 2529: /* if it needed cleaning, then it will need messing up: drop through */ ! 2530: ! 2531: mess_up: ! 2532: /* Must do this while we think we are at the top level. */ ! 2533: vars = nreverse (static_aggregates); ! 2534: if (vars != NULL_TREE) ! 2535: { ! 2536: fnname = get_file_function_name ('I'); ! 2537: start_function (void_list_node, build_parse_node (CALL_EXPR, fnname, void_list_node, NULL_TREE), 0, 0); ! 2538: fnname = DECL_ASSEMBLER_NAME (current_function_decl); ! 2539: store_parm_decls (); ! 2540: ! 2541: pushlevel (0); ! 2542: clear_last_expr (); ! 2543: push_momentary (); ! 2544: expand_start_bindings (0); ! 2545: ! 2546: while (vars) ! 2547: { ! 2548: tree decl = TREE_VALUE (vars); ! 2549: tree init = TREE_PURPOSE (vars); ! 2550: ! 2551: /* If this was a static attribute within some function's scope, ! 2552: then don't initialize it here. Also, don't bother ! 2553: with initializers that contain errors. */ ! 2554: if (TREE_STATIC (vars) ! 2555: || (init && TREE_CODE (init) == TREE_LIST ! 2556: && value_member (error_mark_node, init))) ! 2557: { ! 2558: vars = TREE_CHAIN (vars); ! 2559: continue; ! 2560: } ! 2561: ! 2562: if (TREE_CODE (decl) == VAR_DECL) ! 2563: { ! 2564: /* Set these global variables so that GDB at least puts ! 2565: us near the declaration which required the initialization. */ ! 2566: input_filename = DECL_SOURCE_FILE (decl); ! 2567: lineno = DECL_SOURCE_LINE (decl); ! 2568: emit_note (input_filename, lineno); ! 2569: ! 2570: if (init) ! 2571: { ! 2572: if (TREE_CODE (init) == VAR_DECL) ! 2573: { ! 2574: /* This behavior results when there are ! 2575: multiple declarations of an aggregate, ! 2576: the last of which defines it. */ ! 2577: if (DECL_RTL (init) == DECL_RTL (decl)) ! 2578: { ! 2579: my_friendly_assert (DECL_INITIAL (decl) == error_mark_node ! 2580: || (TREE_CODE (DECL_INITIAL (decl)) == CONSTRUCTOR ! 2581: && CONSTRUCTOR_ELTS (DECL_INITIAL (decl)) == NULL_TREE), ! 2582: 199); ! 2583: init = DECL_INITIAL (init); ! 2584: if (TREE_CODE (init) == CONSTRUCTOR ! 2585: && CONSTRUCTOR_ELTS (init) == NULL_TREE) ! 2586: init = NULL_TREE; ! 2587: } ! 2588: #if 0 ! 2589: else if (TREE_TYPE (decl) == TREE_TYPE (init)) ! 2590: { ! 2591: #if 1 ! 2592: my_friendly_abort (200); ! 2593: #else ! 2594: /* point to real decl's rtl anyway. */ ! 2595: DECL_RTL (init) = DECL_RTL (decl); ! 2596: my_friendly_assert (DECL_INITIAL (decl) == error_mark_node, ! 2597: 201); ! 2598: init = DECL_INITIAL (init); ! 2599: #endif /* 1 */ ! 2600: } ! 2601: #endif /* 0 */ ! 2602: } ! 2603: } ! 2604: if (IS_AGGR_TYPE (TREE_TYPE (decl)) ! 2605: || init == 0 ! 2606: || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) ! 2607: { ! 2608: /* Set this up so is_friend() works properly on _GLOBAL_ fns. */ ! 2609: tree old_dcc = DECL_CLASS_CONTEXT (current_function_decl); ! 2610: if (old_dcc == NULL_TREE) ! 2611: DECL_CLASS_CONTEXT (current_function_decl) = TREE_TYPE (decl); ! 2612: expand_aggr_init (decl, init, 0); ! 2613: DECL_CLASS_CONTEXT (current_function_decl) = old_dcc; ! 2614: } ! 2615: else if (TREE_CODE (init) == TREE_VEC) ! 2616: { ! 2617: expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0), ! 2618: TREE_VEC_ELT (init, 1), ! 2619: TREE_VEC_ELT (init, 2), 0), ! 2620: const0_rtx, VOIDmode, 0); ! 2621: free_temp_slots (); ! 2622: } ! 2623: else ! 2624: expand_assignment (decl, init, 0, 0); ! 2625: } ! 2626: else if (TREE_CODE (decl) == SAVE_EXPR) ! 2627: { ! 2628: if (! PARM_DECL_EXPR (decl)) ! 2629: { ! 2630: /* a `new' expression at top level. */ ! 2631: expand_expr (decl, const0_rtx, VOIDmode, 0); ! 2632: free_temp_slots (); ! 2633: expand_aggr_init (build_indirect_ref (decl, NULL_PTR), init, 0); ! 2634: } ! 2635: } ! 2636: else if (decl == error_mark_node) ! 2637: ; ! 2638: else my_friendly_abort (22); ! 2639: vars = TREE_CHAIN (vars); ! 2640: } ! 2641: ! 2642: expand_end_bindings (getdecls(), 1, 0); ! 2643: poplevel (1, 0, 0); ! 2644: pop_momentary (); ! 2645: ! 2646: finish_function (lineno, 0); ! 2647: assemble_constructor (IDENTIFIER_POINTER (fnname)); ! 2648: } ! 2649: ! 2650: /* Done with C language context needs. */ ! 2651: pop_lang_context (); ! 2652: ! 2653: /* Now write out any static class variables (which may have since ! 2654: learned how to be initialized). */ ! 2655: while (pending_statics) ! 2656: { ! 2657: tree decl = TREE_VALUE (pending_statics); ! 2658: if (TREE_USED (decl) == 1 ! 2659: || TREE_READONLY (decl) == 0 ! 2660: || DECL_INITIAL (decl) == 0) ! 2661: rest_of_decl_compilation (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), 1, 1); ! 2662: pending_statics = TREE_CHAIN (pending_statics); ! 2663: } ! 2664: ! 2665: this_time = get_run_time (); ! 2666: parse_time -= this_time - start_time; ! 2667: varconst_time += this_time - start_time; ! 2668: ! 2669: /* Now write out inline functions which had their addresses taken ! 2670: and which were not declared virtual and which were not declared ! 2671: `extern inline'. */ ! 2672: while (pending_addressable_inlines) ! 2673: { ! 2674: tree decl = TREE_VALUE (pending_addressable_inlines); ! 2675: if (! TREE_ASM_WRITTEN (decl) ! 2676: && ! DECL_EXTERNAL (decl) ! 2677: && DECL_SAVED_INSNS (decl)) ! 2678: { ! 2679: temporary_allocation (); ! 2680: output_inline_function (decl); ! 2681: permanent_allocation (); ! 2682: } ! 2683: pending_addressable_inlines = TREE_CHAIN (pending_addressable_inlines); ! 2684: } ! 2685: ! 2686: start_time = get_run_time (); ! 2687: ! 2688: /* Now delete from the chain of variables all virtual function tables. ! 2689: We output them all ourselves, because each will be treated specially. */ ! 2690: ! 2691: #if 1 ! 2692: /* The reason for pushing garbage onto the global_binding_level is to ! 2693: ensure that we can slice out _DECLs which pertain to virtual function ! 2694: tables. If the last thing pushed onto the global_binding_level was a ! 2695: virtual function table, then slicing it out would slice away all the ! 2696: decls (i.e., we lose the head of the chain). ! 2697: ! 2698: There are several ways of getting the same effect, from changing the ! 2699: way that iterators over the chain treat the elements that pertain to ! 2700: virtual function tables, moving the implementation of this code to ! 2701: cp-decl.c (where we can manipulate global_binding_level directly), ! 2702: popping the garbage after pushing it and slicing away the vtable ! 2703: stuff, or just leaving it alone. */ ! 2704: ! 2705: /* Make last thing in global scope not be a virtual function table. */ ! 2706: #if 0 /* not yet, should get fixed properly later */ ! 2707: vars = make_type_decl (get_identifier (" @%$#@!"), integer_type_node); ! 2708: #else ! 2709: vars = build_decl (TYPE_DECL, get_identifier (" @%$#@!"), integer_type_node); ! 2710: #endif ! 2711: DECL_IGNORED_P (vars) = 1; ! 2712: DECL_SOURCE_LINE (vars) = 0; ! 2713: pushdecl (vars); ! 2714: #endif ! 2715: ! 2716: walk_vtables (finish_vtable_typedecl, finish_vtable_vardecl); ! 2717: ! 2718: if (write_virtuals == 2) ! 2719: { ! 2720: /* Now complain about an virtual function tables promised ! 2721: but not delivered. */ ! 2722: while (pending_vtables) ! 2723: { ! 2724: if (TREE_PURPOSE (pending_vtables) == NULL_TREE) ! 2725: error ("virtual function table for `%s' not defined", ! 2726: IDENTIFIER_POINTER (TREE_VALUE (pending_vtables))); ! 2727: pending_vtables = TREE_CHAIN (pending_vtables); ! 2728: } ! 2729: } ! 2730: ! 2731: permanent_allocation (); ! 2732: this_time = get_run_time (); ! 2733: parse_time -= this_time - start_time; ! 2734: varconst_time += this_time - start_time; ! 2735: ! 2736: if (flag_detailed_statistics) ! 2737: dump_time_statistics (); ! 2738: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.