decl2.c revision 90075
118334Speter/* Process declarations and variables for C compiler.
290075Sobrien   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
390075Sobrien   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
418334Speter   Hacked by Michael Tiemann (tiemann@cygnus.com)
518334Speter
618334SpeterThis file is part of GNU CC.
718334Speter
818334SpeterGNU CC is free software; you can redistribute it and/or modify
918334Speterit under the terms of the GNU General Public License as published by
1018334Speterthe Free Software Foundation; either version 2, or (at your option)
1118334Speterany later version.
1218334Speter
1318334SpeterGNU CC is distributed in the hope that it will be useful,
1418334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1518334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1618334SpeterGNU General Public License for more details.
1718334Speter
1818334SpeterYou should have received a copy of the GNU General Public License
1918334Speteralong with GNU CC; see the file COPYING.  If not, write to
2018334Speterthe Free Software Foundation, 59 Temple Place - Suite 330,
2118334SpeterBoston, MA 02111-1307, USA.  */
2218334Speter
2318334Speter
2418334Speter/* Process declarations and symbol lookup for C front end.
2518334Speter   Also constructs types; the standard scalar types at initialization,
2618334Speter   and structure, union, array and enum types when they are declared.  */
2718334Speter
2818334Speter/* ??? not all decl nodes are given the most useful possible
2918334Speter   line numbers.  For example, the CONST_DECLs for enum values.  */
3018334Speter
3118334Speter#include "config.h"
3250397Sobrien#include "system.h"
3318334Speter#include "tree.h"
3418334Speter#include "rtl.h"
3590075Sobrien#include "expr.h"
3618334Speter#include "flags.h"
3718334Speter#include "cp-tree.h"
3818334Speter#include "decl.h"
3918334Speter#include "lex.h"
4018334Speter#include "output.h"
4150397Sobrien#include "except.h"
4250397Sobrien#include "toplev.h"
4390075Sobrien#include "ggc.h"
4490075Sobrien#include "timevar.h"
4550397Sobrien#include "cpplib.h"
4690075Sobrien#include "target.h"
4790075Sobrienextern cpp_reader *parse_in;
4818334Speter
4952284Sobrien/* This structure contains information about the initializations
5052284Sobrien   and/or destructions required for a particular priority level.  */
5152284Sobrientypedef struct priority_info_s {
5252284Sobrien  /* Non-zero if there have been any initializations at this priority
5352284Sobrien     throughout the translation unit.  */
5452284Sobrien  int initializations_p;
5552284Sobrien  /* Non-zero if there have been any destructions at this priority
5652284Sobrien     throughout the translation unit.  */
5752284Sobrien  int destructions_p;
5852284Sobrien} *priority_info;
5952284Sobrien
6090075Sobrienstatic void mark_vtable_entries PARAMS ((tree));
6190075Sobrienstatic void grok_function_init PARAMS ((tree, tree));
6290075Sobrienstatic int finish_vtable_vardecl PARAMS ((tree *, void *));
6390075Sobrienstatic int prune_vtable_vardecl PARAMS ((tree *, void *));
6490075Sobrienstatic int is_namespace_ancestor PARAMS ((tree, tree));
6590075Sobrienstatic void add_using_namespace PARAMS ((tree, tree, int));
6690075Sobrienstatic tree ambiguous_decl PARAMS ((tree, tree, tree,int));
6790075Sobrienstatic tree build_anon_union_vars PARAMS ((tree, tree*, int, int));
6890075Sobrienstatic int acceptable_java_type PARAMS ((tree));
6990075Sobrienstatic void output_vtable_inherit PARAMS ((tree));
7090075Sobrienstatic tree start_objects PARAMS ((int, int));
7190075Sobrienstatic void finish_objects PARAMS ((int, int, tree));
7290075Sobrienstatic tree merge_functions PARAMS ((tree, tree));
7390075Sobrienstatic tree decl_namespace PARAMS ((tree));
7490075Sobrienstatic tree validate_nonmember_using_decl PARAMS ((tree, tree *, tree *));
7590075Sobrienstatic void do_nonmember_using_decl PARAMS ((tree, tree, tree, tree,
7652284Sobrien					   tree *, tree *));
7790075Sobrienstatic tree start_static_storage_duration_function PARAMS ((void));
7890075Sobrienstatic void finish_static_storage_duration_function PARAMS ((tree));
7990075Sobrienstatic priority_info get_priority_info PARAMS ((int));
8090075Sobrienstatic void do_static_initialization PARAMS ((tree, tree));
8190075Sobrienstatic void do_static_destruction PARAMS ((tree));
8290075Sobrienstatic tree start_static_initialization_or_destruction PARAMS ((tree, int));
8390075Sobrienstatic void finish_static_initialization_or_destruction PARAMS ((tree));
8490075Sobrienstatic void generate_ctor_or_dtor_function PARAMS ((int, int));
8552284Sobrienstatic int generate_ctor_and_dtor_functions_for_priority
8690075Sobrien                                  PARAMS ((splay_tree_node, void *));
8790075Sobrienstatic tree prune_vars_needing_no_initialization PARAMS ((tree));
8890075Sobrienstatic void write_out_vars PARAMS ((tree));
8990075Sobrienstatic void import_export_class	PARAMS ((tree));
9090075Sobrienstatic tree key_method PARAMS ((tree));
9190075Sobrienstatic int compare_options PARAMS ((const PTR, const PTR));
9290075Sobrienstatic tree get_guard_bits PARAMS ((tree));
9350397Sobrien
9418334Speter/* A list of static class variables.  This is needed, because a
9518334Speter   static class variable can be declared inside the class without
9690075Sobrien   an initializer, and then initialized, statically, outside the class.  */
9752284Sobrienstatic varray_type pending_statics;
9890075Sobrien#define pending_statics_used \
9990075Sobrien  (pending_statics ? pending_statics->elements_used : 0)
10018334Speter
10118334Speter/* A list of functions which were declared inline, but which we
10250397Sobrien   may need to emit outline anyway.  */
10390075Sobrienstatic varray_type deferred_fns;
10490075Sobrien#define deferred_fns_used \
10590075Sobrien  (deferred_fns ? deferred_fns->elements_used : 0)
10618334Speter
10718334Speter/* Flag used when debugging spew.c */
10818334Speter
10918334Speterextern int spew_debug;
11018334Speter
11150397Sobrien/* Nonzero if we're done parsing and into end-of-file activities.  */
11250397Sobrien
11350397Sobrienint at_eof;
11450397Sobrien
11518334Speter/* Functions called along with real static constructors and destructors.  */
11618334Speter
11790075Sobrientree static_ctors;
11890075Sobrientree static_dtors;
11950397Sobrien
12090075Sobrien/* The :: namespace. */
12150397Sobrien
12250397Sobrientree global_namespace;
12318334Speter
12418334Speter/* C (and C++) language-specific option variables.  */
12518334Speter
12618334Speter/* Nonzero means don't recognize the keyword `asm'.  */
12718334Speter
12818334Speterint flag_no_asm;
12918334Speter
13018334Speter/* Nonzero means don't recognize any extension keywords.  */
13118334Speter
13218334Speterint flag_no_gnu_keywords;
13318334Speter
13450397Sobrien/* Nonzero means do some things the same way PCC does.  Only provided so
13550397Sobrien   the compiler will link.  */
13618334Speter
13718334Speterint flag_traditional;
13818334Speter
13918334Speter/* Nonzero means to treat bitfields as unsigned unless they say `signed'.  */
14018334Speter
14118334Speterint flag_signed_bitfields = 1;
14218334Speter
14390075Sobrien/* Nonzero means enable obscure standard features and disable GNU
14490075Sobrien   extensions that might cause standard-compliant code to be
14590075Sobrien   miscompiled.  */
14618334Speter
14718334Speterint flag_ansi;
14818334Speter
14918334Speter/* Nonzero means do emit exported implementations of functions even if
15018334Speter   they can be inlined.  */
15118334Speter
15218334Speterint flag_implement_inlines = 1;
15318334Speter
15418334Speter/* Nonzero means do emit exported implementations of templates, instead of
15550397Sobrien   multiple static copies in each file that needs a definition.  */
15618334Speter
15718334Speterint flag_external_templates;
15818334Speter
15918334Speter/* Nonzero means that the decision to emit or not emit the implementation of a
16018334Speter   template depends on where the template is instantiated, rather than where
16118334Speter   it is defined.  */
16218334Speter
16318334Speterint flag_alt_external_templates;
16418334Speter
16518334Speter/* Nonzero means that implicit instantiations will be emitted if needed.  */
16618334Speter
16718334Speterint flag_implicit_templates = 1;
16818334Speter
16952284Sobrien/* Nonzero means that implicit instantiations of inline templates will be
17052284Sobrien   emitted if needed, even if instantiations of non-inline templates
17152284Sobrien   aren't.  */
17252284Sobrien
17352284Sobrienint flag_implicit_inline_templates = 1;
17452284Sobrien
17518334Speter/* Nonzero means warn about implicit declarations.  */
17618334Speter
17718334Speterint warn_implicit = 1;
17818334Speter
17950397Sobrien/* Nonzero means warn about usage of long long when `-pedantic'.  */
18050397Sobrien
18150397Sobrienint warn_long_long = 1;
18250397Sobrien
18318334Speter/* Nonzero means warn when all ctors or dtors are private, and the class
18418334Speter   has no friends.  */
18518334Speter
18618334Speterint warn_ctor_dtor_privacy = 1;
18718334Speter
18890075Sobrien/* Nonzero means generate separate instantiation control files and juggle
18990075Sobrien   them at link time.  */
19018334Speter
19118334Speterint flag_use_repository;
19218334Speter
19350397Sobrien/* Nonzero if we want to issue diagnostics that the standard says are not
19450397Sobrien   required.  */
19550397Sobrien
19650397Sobrienint flag_optional_diags = 1;
19750397Sobrien
19852284Sobrien/* Nonzero means give string constants the type `const char *', as mandated
19952284Sobrien   by the standard.  */
20018334Speter
20152284Sobrienint flag_const_strings = 1;
20252284Sobrien
20352284Sobrien/* Nonzero means warn about deprecated conversion from string constant to
20452284Sobrien   `char *'.  */
20552284Sobrien
20618334Speterint warn_write_strings;
20718334Speter
20818334Speter/* Nonzero means warn about pointer casts that can drop a type qualifier
20918334Speter   from the pointer target type.  */
21018334Speter
21118334Speterint warn_cast_qual;
21218334Speter
21318334Speter/* Nonzero means warn about sizeof(function) or addition/subtraction
21418334Speter   of function pointers.  */
21518334Speter
21650397Sobrienint warn_pointer_arith = 1;
21718334Speter
21818334Speter/* Nonzero means warn for any function def without prototype decl.  */
21918334Speter
22018334Speterint warn_missing_prototypes;
22118334Speter
22218334Speter/* Nonzero means warn about multiple (redundant) decls for the same single
22318334Speter   variable or function.  */
22418334Speter
22518334Speterint warn_redundant_decls;
22618334Speter
22718334Speter/* Warn if initializer is not completely bracketed.  */
22818334Speter
22918334Speterint warn_missing_braces;
23018334Speter
23150397Sobrien/* Warn about comparison of signed and unsigned values.  */
23218334Speter
23350397Sobrienint warn_sign_compare;
23450397Sobrien
23590075Sobrien/* Warn about testing equality of floating point numbers. */
23650397Sobrien
23790075Sobrienint warn_float_equal = 0;
23818334Speter
23990075Sobrien/* Warn about functions which might be candidates for format attributes.  */
24090075Sobrien
24190075Sobrienint warn_missing_format_attribute;
24290075Sobrien
24318334Speter/* Warn about a subscript that has type char.  */
24418334Speter
24518334Speterint warn_char_subscripts;
24618334Speter
24718334Speter/* Warn if a type conversion is done that might have confusing results.  */
24818334Speter
24918334Speterint warn_conversion;
25018334Speter
25118334Speter/* Warn if adding () is suggested.  */
25218334Speter
25318334Speterint warn_parentheses;
25418334Speter
25518334Speter/* Non-zero means warn in function declared in derived class has the
25618334Speter   same name as a virtual in the base class, but fails to match the
25718334Speter   type signature of any virtual function in the base class.  */
25890075Sobrien
25918334Speterint warn_overloaded_virtual;
26018334Speter
26118334Speter/* Non-zero means warn when declaring a class that has a non virtual
26250397Sobrien   destructor, when it really ought to have a virtual one.  */
26390075Sobrien
26418334Speterint warn_nonvdtor;
26518334Speter
26690075Sobrien/* Non-zero means warn when the compiler will reorder code.  */
26718334Speter
26818334Speterint warn_reorder;
26918334Speter
27018334Speter/* Non-zero means warn when synthesis behavior differs from Cfront's.  */
27190075Sobrien
27218334Speterint warn_synth;
27318334Speter
27450397Sobrien/* Non-zero means warn when we convert a pointer to member function
27550397Sobrien   into a pointer to (void or function).  */
27690075Sobrien
27750397Sobrienint warn_pmf2ptr = 1;
27818334Speter
27950397Sobrien/* Nonzero means warn about violation of some Effective C++ style rules.  */
28050397Sobrien
28150397Sobrienint warn_ecpp;
28250397Sobrien
28350397Sobrien/* Nonzero means warn where overload resolution chooses a promotion from
28450397Sobrien   unsigned to signed over a conversion to an unsigned of the same size.  */
28550397Sobrien
28650397Sobrienint warn_sign_promo;
28750397Sobrien
28850397Sobrien/* Nonzero means warn when an old-style cast is used.  */
28950397Sobrien
29050397Sobrienint warn_old_style_cast;
29150397Sobrien
29250397Sobrien/* Warn about #pragma directives that are not recognised.  */
29350397Sobrien
29450397Sobrienint warn_unknown_pragmas; /* Tri state variable.  */
29550397Sobrien
29650397Sobrien/* Nonzero means warn about use of multicharacter literals.  */
29750397Sobrien
29850397Sobrienint warn_multichar = 1;
29950397Sobrien
30052284Sobrien/* Nonzero means warn when non-templatized friend functions are
30152284Sobrien   declared within a template */
30252284Sobrien
30352284Sobrienint warn_nontemplate_friend = 1;
30452284Sobrien
30552284Sobrien/* Nonzero means complain about deprecated features.  */
30652284Sobrien
30752284Sobrienint warn_deprecated = 1;
30852284Sobrien
30950397Sobrien/* Nonzero means `$' can be in an identifier.  */
31050397Sobrien
31118334Speter#ifndef DOLLARS_IN_IDENTIFIERS
31218334Speter#define DOLLARS_IN_IDENTIFIERS 1
31318334Speter#endif
31418334Speterint dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
31518334Speter
31690075Sobrien/* Nonzero means allow Microsoft extensions without a pedwarn.  */
31718334Speter
31890075Sobrienint flag_ms_extensions;
31918334Speter
32018334Speter/* C++ specific flags.  */
32118334Speter
32252284Sobrien/* Nonzero means we should attempt to elide constructors when possible.  */
32318334Speter
32452284Sobrienint flag_elide_constructors = 1;
32518334Speter
32618334Speter/* Nonzero means that member functions defined in class scope are
32718334Speter   inline by default.  */
32818334Speter
32918334Speterint flag_default_inline = 1;
33018334Speter
33118334Speter/* Controls whether compiler generates 'type descriptor' that give
33218334Speter   run-time type information.  */
33390075Sobrien
33450397Sobrienint flag_rtti = 1;
33518334Speter
33618334Speter/* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes)
33750397Sobrien   objects.  */
33818334Speter
33918334Speterint flag_huge_objects;
34018334Speter
34118334Speter/* Nonzero if we want to conserve space in the .o files.  We do this
34218334Speter   by putting uninitialized data and runtime initialized data into
34318334Speter   .common instead of .data at the expense of not flagging multiple
34418334Speter   definitions.  */
34518334Speter
34618334Speterint flag_conserve_space;
34718334Speter
34818334Speter/* Nonzero if we want to obey access control semantics.  */
34918334Speter
35018334Speterint flag_access_control = 1;
35118334Speter
35218334Speter/* Nonzero if we want to understand the operator names, i.e. 'bitand'.  */
35318334Speter
35490075Sobrienint flag_operator_names = 1;
35518334Speter
35618334Speter/* Nonzero if we want to check the return value of new and avoid calling
35718334Speter   constructors if it is a null pointer.  */
35818334Speter
35918334Speterint flag_check_new;
36018334Speter
36190075Sobrien/* Nonzero if we want the new ISO rules for pushing a new scope for `for'
36218334Speter   initialization variables.
36318334Speter   0: Old rules, set by -fno-for-scope.
36490075Sobrien   2: New ISO rules, set by -ffor-scope.
36590075Sobrien   1: Try to implement new ISO rules, but with backup compatibility
36618334Speter   (and warnings).  This is the default, for now.  */
36718334Speter
36818334Speterint flag_new_for_scope = 1;
36918334Speter
37050397Sobrien/* Nonzero if we want to emit defined symbols with common-like linkage as
37150397Sobrien   weak symbols where possible, in order to conform to C++ semantics.
37250397Sobrien   Otherwise, emit them as local symbols.  */
37350397Sobrien
37450397Sobrienint flag_weak = 1;
37550397Sobrien
37690075Sobrien/* Nonzero to use __cxa_atexit, rather than atexit, to register
37790075Sobrien   destructors for local statics and global objects.  */
37850397Sobrien
37990075Sobrienint flag_use_cxa_atexit;
38050397Sobrien
38190075Sobrien/* Maximum template instantiation depth.  This limit is rather
38290075Sobrien   arbitrary, but it exists to limit the time it takes to notice
38390075Sobrien   infinite template instantiations.  */
38450397Sobrien
38590075Sobrienint max_tinst_depth = 500;
38650397Sobrien
38752284Sobrien/* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc.  */
38850397Sobrien
38952284Sobrienint flag_vtable_gc;
39052284Sobrien
39152284Sobrien/* Nonzero means make the default pedwarns warnings instead of errors.
39252284Sobrien   The value of this flag is ignored if -pedantic is specified.  */
39352284Sobrien
39452284Sobrienint flag_permissive;
39552284Sobrien
39690075Sobrien/* Nonzero means to implement standard semantics for exception
39790075Sobrien   specifications, calling unexpected if an exception is thrown that
39890075Sobrien   doesn't match the specification.  Zero means to treat them as
39990075Sobrien   assertions and optimize accordingly, but not check them.  */
40090075Sobrien
40190075Sobrienint flag_enforce_eh_specs = 1;
40290075Sobrien
40318334Speter/* Table of language-dependent -f options.
40418334Speter   STRING is the option name.  VARIABLE is the address of the variable.
40518334Speter   ON_VALUE is the value to store in VARIABLE
40618334Speter    if `-fSTRING' is seen as an option.
40718334Speter   (If `-fno-STRING' is seen as an option, the opposite value is stored.)  */
40818334Speter
40990075Sobrienstatic const struct { const char *const string; int *const variable; const int on_value;}
41052284Sobrienlang_f_options[] =
41118334Speter{
41252284Sobrien  /* C/C++ options.  */
41318334Speter  {"signed-char", &flag_signed_char, 1},
41418334Speter  {"unsigned-char", &flag_signed_char, 0},
41518334Speter  {"signed-bitfields", &flag_signed_bitfields, 1},
41618334Speter  {"unsigned-bitfields", &flag_signed_bitfields, 0},
41718334Speter  {"short-enums", &flag_short_enums, 1},
41818334Speter  {"short-double", &flag_short_double, 1},
41990075Sobrien  {"short-wchar", &flag_short_wchar, 1},
42018334Speter  {"asm", &flag_no_asm, 0},
42118334Speter  {"builtin", &flag_no_builtin, 0},
42252284Sobrien
42352284Sobrien  /* C++-only options.  */
42452284Sobrien  {"access-control", &flag_access_control, 1},
42552284Sobrien  {"check-new", &flag_check_new, 1},
42652284Sobrien  {"conserve-space", &flag_conserve_space, 1},
42752284Sobrien  {"const-strings", &flag_const_strings, 1},
42852284Sobrien  {"default-inline", &flag_default_inline, 1},
42952284Sobrien  {"dollars-in-identifiers", &dollars_in_ident, 1},
43018334Speter  {"elide-constructors", &flag_elide_constructors, 1},
43190075Sobrien  {"enforce-eh-specs", &flag_enforce_eh_specs, 1},
43252284Sobrien  {"external-templates", &flag_external_templates, 1},
43352284Sobrien  {"for-scope", &flag_new_for_scope, 2},
43452284Sobrien  {"gnu-keywords", &flag_no_gnu_keywords, 0},
43550397Sobrien  {"handle-exceptions", &flag_exceptions, 1},
43618334Speter  {"implement-inlines", &flag_implement_inlines, 1},
43752284Sobrien  {"implicit-inline-templates", &flag_implicit_inline_templates, 1},
43818334Speter  {"implicit-templates", &flag_implicit_templates, 1},
43990075Sobrien  {"ms-extensions", &flag_ms_extensions, 1},
44018334Speter  {"nonansi-builtins", &flag_no_nonansi_builtin, 0},
44118334Speter  {"operator-names", &flag_operator_names, 1},
44250397Sobrien  {"optional-diags", &flag_optional_diags, 1},
44352284Sobrien  {"permissive", &flag_permissive, 1},
44418334Speter  {"repo", &flag_use_repository, 1},
44552284Sobrien  {"rtti", &flag_rtti, 1},
44652284Sobrien  {"stats", &flag_detailed_statistics, 1},
44752284Sobrien  {"vtable-gc", &flag_vtable_gc, 1},
44890075Sobrien  {"use-cxa-atexit", &flag_use_cxa_atexit, 1},
44990075Sobrien  {"weak", &flag_weak, 1}
45018334Speter};
45118334Speter
45290075Sobrien/* The list of `-f' options that we no longer support.  The `-f'
45390075Sobrien   prefix is not given in this table.  The `-fno-' variants are not
45490075Sobrien   listed here.  This table must be kept in alphabetical order.  */
45590075Sobrienstatic const char * const unsupported_options[] = {
45690075Sobrien  "all-virtual",
45790075Sobrien  "cond-mismatch",
45890075Sobrien  "enum-int-equiv",
45990075Sobrien  "guiding-decls",
46090075Sobrien  "honor-std",
46190075Sobrien  "huge-objects",
46290075Sobrien  "labels-ok",
46390075Sobrien  "new-abi",
46490075Sobrien  "nonnull-objects",
46590075Sobrien  "squangle",
46690075Sobrien  "strict-prototype",
46790075Sobrien  "this-is-variable",
46890075Sobrien  "vtable-thunks",
46990075Sobrien  "xref"
47090075Sobrien};
47190075Sobrien
47290075Sobrien/* Compare two option strings, pointed two by P1 and P2, for use with
47390075Sobrien   bsearch.  */
47490075Sobrien
47590075Sobrienstatic int
47690075Sobriencompare_options (p1, p2)
47790075Sobrien     const PTR p1;
47890075Sobrien     const PTR p2;
47990075Sobrien{
48090075Sobrien  return strcmp (*((const char *const *) p1), *((const char *const *) p2));
48190075Sobrien}
48290075Sobrien
48318334Speter/* Decode the string P as a language-specific option.
48450397Sobrien   Return the number of strings consumed for a valid option.
48590075Sobrien   Otherwise return 0.  Should not complain if it does not
48690075Sobrien   recognise the option.  */
48718334Speter
48818334Speterint
48990075Sobriencxx_decode_option (argc, argv)
49090075Sobrien     int argc;
49150397Sobrien     char **argv;
49218334Speter{
49350397Sobrien  int strings_processed;
49490075Sobrien  const char *p = argv[0];
49550397Sobrien
49690075Sobrien  strings_processed = cpp_handle_option (parse_in, argc, argv, 0);
49790075Sobrien
49818334Speter  if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
49952284Sobrien    /* ignore */;
50018334Speter  else if (p[0] == '-' && p[1] == 'f')
50118334Speter    {
50218334Speter      /* Some kind of -f option.
50318334Speter	 P's value is the option sans `-f'.
50418334Speter	 Search for it in the table of options.  */
50590075Sobrien      const char *option_value = NULL;
50690075Sobrien      const char *positive_option;
50750397Sobrien      size_t j;
50818334Speter
50918334Speter      p += 2;
51018334Speter      /* Try special -f options.  */
51118334Speter
51290075Sobrien      /* See if this is one of the options no longer supported.  We
51390075Sobrien	 used to support these options, so we continue to accept them,
51490075Sobrien	 with a warning.  */
51590075Sobrien      if (strncmp (p, "no-", strlen ("no-")) == 0)
51690075Sobrien	positive_option = p + strlen ("no-");
51790075Sobrien      else
51890075Sobrien	positive_option = p;
51950397Sobrien
52090075Sobrien      /* If the option is present, issue a warning.  Indicate to our
52190075Sobrien	 caller that the option was processed successfully.  */
52290075Sobrien      if (bsearch (&positive_option,
52390075Sobrien		   unsupported_options,
52490075Sobrien		   (sizeof (unsupported_options)
52590075Sobrien		    / sizeof (unsupported_options[0])),
52690075Sobrien		   sizeof (unsupported_options[0]),
52790075Sobrien		   compare_options))
52818334Speter	{
52952284Sobrien	  warning ("-f%s is no longer supported", p);
53090075Sobrien	  return 1;
53118334Speter	}
53290075Sobrien
53390075Sobrien      if (!strcmp (p, "handle-exceptions")
53490075Sobrien	  || !strcmp (p, "no-handle-exceptions"))
53590075Sobrien	warning ("-fhandle-exceptions has been renamed to -fexceptions (and is now on by default)");
53650397Sobrien      else if (! strcmp (p, "alt-external-templates"))
53718334Speter	{
53850397Sobrien	  flag_external_templates = 1;
53950397Sobrien	  flag_alt_external_templates = 1;
54052284Sobrien          cp_deprecated ("-falt-external-templates");
54118334Speter	}
54250397Sobrien      else if (! strcmp (p, "no-alt-external-templates"))
54390075Sobrien	flag_alt_external_templates = 0;
54450397Sobrien      else if (!strcmp (p, "repo"))
54518334Speter	{
54650397Sobrien	  flag_use_repository = 1;
54750397Sobrien	  flag_implicit_templates = 0;
54818334Speter	}
54952284Sobrien      else if (!strcmp (p, "external-templates"))
55052284Sobrien        {
55152284Sobrien          flag_external_templates = 1;
55252284Sobrien          cp_deprecated ("-fexternal-templates");
55352284Sobrien        }
55490075Sobrien      else if ((option_value
55590075Sobrien                = skip_leading_substring (p, "template-depth-")))
55690075Sobrien	max_tinst_depth
55790075Sobrien	  = read_integral_parameter (option_value, p - 2, max_tinst_depth);
55890075Sobrien      else if ((option_value
55990075Sobrien                = skip_leading_substring (p, "name-mangling-version-")))
56060967Sobrien	{
56190075Sobrien	  warning ("-fname-mangling-version is no longer supported");
56290075Sobrien	  return 1;
56360967Sobrien	}
56490075Sobrien      else if (dump_switch_p (p))
56590075Sobrien	;
56690075Sobrien      else
56718334Speter	{
56890075Sobrien	  int found = 0;
56990075Sobrien
57090075Sobrien	  for (j = 0;
57190075Sobrien	       !found && j < (sizeof (lang_f_options)
57290075Sobrien			      / sizeof (lang_f_options[0]));
57390075Sobrien	       j++)
57418334Speter	    {
57590075Sobrien	      if (!strcmp (p, lang_f_options[j].string))
57690075Sobrien		{
57790075Sobrien		  *lang_f_options[j].variable = lang_f_options[j].on_value;
57890075Sobrien		  /* A goto here would be cleaner,
57990075Sobrien		     but breaks the VAX pcc.  */
58090075Sobrien		  found = 1;
58190075Sobrien		}
58290075Sobrien	      else if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
58390075Sobrien		       && ! strcmp (p+3, lang_f_options[j].string))
58490075Sobrien		{
58590075Sobrien		  *lang_f_options[j].variable = ! lang_f_options[j].on_value;
58690075Sobrien		  found = 1;
58790075Sobrien		}
58818334Speter	    }
58990075Sobrien
59090075Sobrien	  return found;
59118334Speter	}
59218334Speter    }
59318334Speter  else if (p[0] == '-' && p[1] == 'W')
59418334Speter    {
59518334Speter      int setting = 1;
59618334Speter
59718334Speter      /* The -W options control the warning behavior of the compiler.  */
59818334Speter      p += 2;
59918334Speter
60018334Speter      if (p[0] == 'n' && p[1] == 'o' && p[2] == '-')
60118334Speter	setting = 0, p += 3;
60218334Speter
60318334Speter      if (!strcmp (p, "implicit"))
60418334Speter	warn_implicit = setting;
60550397Sobrien      else if (!strcmp (p, "long-long"))
60650397Sobrien	warn_long_long = setting;
60718334Speter      else if (!strcmp (p, "return-type"))
60818334Speter	warn_return_type = setting;
60918334Speter      else if (!strcmp (p, "ctor-dtor-privacy"))
61018334Speter	warn_ctor_dtor_privacy = setting;
61118334Speter      else if (!strcmp (p, "write-strings"))
61218334Speter	warn_write_strings = setting;
61318334Speter      else if (!strcmp (p, "cast-qual"))
61418334Speter	warn_cast_qual = setting;
61518334Speter      else if (!strcmp (p, "char-subscripts"))
61618334Speter	warn_char_subscripts = setting;
61718334Speter      else if (!strcmp (p, "pointer-arith"))
61818334Speter	warn_pointer_arith = setting;
61918334Speter      else if (!strcmp (p, "missing-prototypes"))
62018334Speter	warn_missing_prototypes = setting;
62190075Sobrien      else if (!strcmp (p, "strict-prototypes"))
62290075Sobrien	{
62390075Sobrien	  if (setting == 0)
62490075Sobrien	    warning ("-Wno-strict-prototypes is not supported in C++");
62590075Sobrien	}
62618334Speter      else if (!strcmp (p, "redundant-decls"))
62718334Speter	warn_redundant_decls = setting;
62818334Speter      else if (!strcmp (p, "missing-braces"))
62918334Speter	warn_missing_braces = setting;
63050397Sobrien      else if (!strcmp (p, "sign-compare"))
63150397Sobrien	warn_sign_compare = setting;
63290075Sobrien      else if (!strcmp (p, "float-equal"))
63390075Sobrien	warn_float_equal = setting;
63418334Speter      else if (!strcmp (p, "format"))
63590075Sobrien	set_Wformat (setting);
63690075Sobrien      else if (!strcmp (p, "format=2"))
63790075Sobrien	set_Wformat (2);
63890075Sobrien      else if (!strcmp (p, "format-y2k"))
63990075Sobrien	warn_format_y2k = setting;
64090075Sobrien      else if (!strcmp (p, "format-extra-args"))
64190075Sobrien	warn_format_extra_args = setting;
64290075Sobrien      else if (!strcmp (p, "format-nonliteral"))
64390075Sobrien	warn_format_nonliteral = setting;
64490075Sobrien      else if (!strcmp (p, "format-security"))
64590075Sobrien	warn_format_security = setting;
64690075Sobrien      else if (!strcmp (p, "missing-format-attribute"))
64790075Sobrien	warn_missing_format_attribute = setting;
64818334Speter      else if (!strcmp (p, "conversion"))
64918334Speter	warn_conversion = setting;
65018334Speter      else if (!strcmp (p, "parentheses"))
65118334Speter	warn_parentheses = setting;
65218334Speter      else if (!strcmp (p, "non-virtual-dtor"))
65318334Speter	warn_nonvdtor = setting;
65418334Speter      else if (!strcmp (p, "reorder"))
65518334Speter	warn_reorder = setting;
65618334Speter      else if (!strcmp (p, "synth"))
65718334Speter	warn_synth = setting;
65850397Sobrien      else if (!strcmp (p, "pmf-conversions"))
65950397Sobrien	warn_pmf2ptr = setting;
66050397Sobrien      else if (!strcmp (p, "effc++"))
66150397Sobrien	warn_ecpp = setting;
66250397Sobrien      else if (!strcmp (p, "sign-promo"))
66350397Sobrien	warn_sign_promo = setting;
66450397Sobrien      else if (!strcmp (p, "old-style-cast"))
66550397Sobrien	warn_old_style_cast = setting;
66650397Sobrien      else if (!strcmp (p, "overloaded-virtual"))
66750397Sobrien	warn_overloaded_virtual = setting;
66850397Sobrien      else if (!strcmp (p, "multichar"))
66950397Sobrien	warn_multichar = setting;
67050397Sobrien      else if (!strcmp (p, "unknown-pragmas"))
67150397Sobrien	/* Set to greater than 1, so that even unknown pragmas in
67250397Sobrien	   system headers will be warned about.  */
67350397Sobrien	warn_unknown_pragmas = setting * 2;
67452284Sobrien      else if (!strcmp (p, "non-template-friend"))
67552284Sobrien	warn_nontemplate_friend = setting;
67652284Sobrien      else if (!strcmp (p, "deprecated"))
67752284Sobrien        warn_deprecated = setting;
67818334Speter      else if (!strcmp (p, "comment"))
67918334Speter	;			/* cpp handles this one.  */
68018334Speter      else if (!strcmp (p, "comments"))
68118334Speter	;			/* cpp handles this one.  */
68218334Speter      else if (!strcmp (p, "trigraphs"))
68318334Speter	;			/* cpp handles this one.  */
68418334Speter      else if (!strcmp (p, "import"))
68518334Speter	;			/* cpp handles this one.  */
68618334Speter      else if (!strcmp (p, "all"))
68718334Speter	{
68818334Speter	  warn_return_type = setting;
68990075Sobrien	  set_Wunused (setting);
69018334Speter	  warn_implicit = setting;
69118334Speter	  warn_switch = setting;
69290075Sobrien	  set_Wformat (setting);
69318334Speter	  warn_parentheses = setting;
69418334Speter	  warn_missing_braces = setting;
69550397Sobrien	  warn_sign_compare = setting;
69650397Sobrien	  warn_multichar = setting;
69718334Speter	  /* We save the value of warn_uninitialized, since if they put
69818334Speter	     -Wuninitialized on the command line, we need to generate a
69918334Speter	     warning about not using it without also specifying -O.  */
70018334Speter	  if (warn_uninitialized != 1)
70118334Speter	    warn_uninitialized = (setting ? 2 : 0);
70250397Sobrien	  /* Only warn about unknown pragmas that are not in system
70350397Sobrien	     headers.  */
70452284Sobrien	  warn_unknown_pragmas = 1;
70552284Sobrien
70652284Sobrien	  /* C++-specific warnings.  */
70752284Sobrien	  warn_ctor_dtor_privacy = setting;
70852284Sobrien	  warn_nonvdtor = setting;
70952284Sobrien	  warn_reorder = setting;
71052284Sobrien	  warn_nontemplate_friend = setting;
71118334Speter	}
71250397Sobrien      else return strings_processed;
71318334Speter    }
71418334Speter  else if (!strcmp (p, "-ansi"))
71550397Sobrien    flag_no_nonansi_builtin = 1, flag_ansi = 1,
71690075Sobrien    flag_noniso_default_format_attributes = 0, flag_no_gnu_keywords = 1;
71718334Speter#ifdef SPEW_DEBUG
71818334Speter  /* Undocumented, only ever used when you're invoking cc1plus by hand, since
71918334Speter     it's probably safe to assume no sane person would ever want to use this
72018334Speter     under normal circumstances.  */
72118334Speter  else if (!strcmp (p, "-spew-debug"))
72218334Speter    spew_debug = 1;
72318334Speter#endif
72418334Speter  else
72550397Sobrien    return strings_processed;
72618334Speter
72718334Speter  return 1;
72818334Speter}
72918334Speter
73018334Speter/* Incorporate `const' and `volatile' qualifiers for member functions.
73118334Speter   FUNCTION is a TYPE_DECL or a FUNCTION_DECL.
73290075Sobrien   QUALS is a list of qualifiers.  Returns any explicit
73390075Sobrien   top-level qualifiers of the method's this pointer, anything other than
73490075Sobrien   TYPE_UNQUALIFIED will be an extension.  */
73550397Sobrien
73690075Sobrienint
73718334Spetergrok_method_quals (ctype, function, quals)
73818334Speter     tree ctype, function, quals;
73918334Speter{
74018334Speter  tree fntype = TREE_TYPE (function);
74118334Speter  tree raises = TYPE_RAISES_EXCEPTIONS (fntype);
74252284Sobrien  int type_quals = TYPE_UNQUALIFIED;
74352284Sobrien  int dup_quals = TYPE_UNQUALIFIED;
74490075Sobrien  int this_quals = TYPE_UNQUALIFIED;
74518334Speter
74618334Speter  do
74718334Speter    {
74852284Sobrien      int tq = cp_type_qual_from_rid (TREE_VALUE (quals));
74952284Sobrien
75090075Sobrien      if ((type_quals | this_quals) & tq)
75152284Sobrien	dup_quals |= tq;
75290075Sobrien      else if (tq & TYPE_QUAL_RESTRICT)
75390075Sobrien        this_quals |= tq;
75418334Speter      else
75552284Sobrien	type_quals |= tq;
75618334Speter      quals = TREE_CHAIN (quals);
75752284Sobrien    }
75818334Speter  while (quals);
75952284Sobrien
76052284Sobrien  if (dup_quals != TYPE_UNQUALIFIED)
76190075Sobrien    error ("duplicate type qualifiers in %s declaration",
76252284Sobrien	      TREE_CODE (function) == FUNCTION_DECL
76352284Sobrien	      ? "member function" : "type");
76452284Sobrien
76552284Sobrien  ctype = cp_build_qualified_type (ctype, type_quals);
76618334Speter  fntype = build_cplus_method_type (ctype, TREE_TYPE (fntype),
76718334Speter				    (TREE_CODE (fntype) == METHOD_TYPE
76818334Speter				     ? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
76918334Speter				     : TYPE_ARG_TYPES (fntype)));
77018334Speter  if (raises)
77118334Speter    fntype = build_exception_variant (fntype, raises);
77218334Speter
77318334Speter  TREE_TYPE (function) = fntype;
77490075Sobrien  return this_quals;
77518334Speter}
77618334Speter
77718334Speter/* Warn when -fexternal-templates is used and #pragma
77818334Speter   interface/implementation is not used all the times it should be,
77918334Speter   inform the user.  */
78050397Sobrien
78118334Spetervoid
78218334Speterwarn_if_unknown_interface (decl)
78318334Speter     tree decl;
78418334Speter{
78518334Speter  static int already_warned = 0;
78618334Speter  if (already_warned++)
78718334Speter    return;
78818334Speter
78918334Speter  if (flag_alt_external_templates)
79018334Speter    {
79190075Sobrien      tree til = tinst_for_decl ();
79218334Speter      int sl = lineno;
79390075Sobrien      const char *sf = input_filename;
79418334Speter
79518334Speter      if (til)
79618334Speter	{
79790075Sobrien	  lineno = TINST_LINE (til);
79890075Sobrien	  input_filename = TINST_FILE (til);
79918334Speter	}
80090075Sobrien      warning ("template `%#D' instantiated in file without #pragma interface",
80118334Speter		  decl);
80218334Speter      lineno = sl;
80318334Speter      input_filename = sf;
80418334Speter    }
80518334Speter  else
80618334Speter    cp_warning_at ("template `%#D' defined in file without #pragma interface",
80718334Speter		   decl);
80818334Speter}
80918334Speter
81018334Speter/* A subroutine of the parser, to handle a component list.  */
81150397Sobrien
81252284Sobrienvoid
81352284Sobriengrok_x_components (specs)
81452284Sobrien     tree specs;
81518334Speter{
81652284Sobrien  tree t;
81718334Speter
81852284Sobrien  specs = strip_attrs (specs);
81918334Speter
82052284Sobrien  check_tag_decl (specs);
82190075Sobrien  t = groktypename (build_tree_list (specs, NULL_TREE));
82218334Speter
82352284Sobrien  /* The only case where we need to do anything additional here is an
82452284Sobrien     anonymous union field, e.g.: `struct S { union { int i; }; };'.  */
82590075Sobrien  if (t == NULL_TREE || !ANON_AGGR_TYPE_P (t))
82652284Sobrien    return;
82718334Speter
82890075Sobrien  fixup_anonymous_aggr (t);
82990075Sobrien  finish_member_declaration (build_decl (FIELD_DECL, NULL_TREE, t));
83090075Sobrien}
83118334Speter
83290075Sobrien/* Returns a PARM_DECL for a parameter of the indicated TYPE, with the
83390075Sobrien   indicated NAME.  */
83490075Sobrien
83590075Sobrientree
83690075Sobrienbuild_artificial_parm (name, type)
83790075Sobrien     tree name;
83890075Sobrien     tree type;
83990075Sobrien{
84090075Sobrien  tree parm;
84190075Sobrien
84290075Sobrien  parm = build_decl (PARM_DECL, name, type);
84390075Sobrien  DECL_ARTIFICIAL (parm) = 1;
84490075Sobrien  /* All our artificial parms are implicitly `const'; they cannot be
84590075Sobrien     assigned to.  */
84690075Sobrien  TREE_READONLY (parm) = 1;
84790075Sobrien  DECL_ARG_TYPE (parm) = type;
84890075Sobrien  return parm;
84918334Speter}
85018334Speter
85150397Sobrien/* Constructors for types with virtual baseclasses need an "in-charge" flag
85250397Sobrien   saying whether this constructor is responsible for initialization of
85350397Sobrien   virtual baseclasses or not.  All destructors also need this "in-charge"
85450397Sobrien   flag, which additionally determines whether or not the destructor should
85550397Sobrien   free the memory for the object.
85650397Sobrien
85750397Sobrien   This function adds the "in-charge" flag to member function FN if
85850397Sobrien   appropriate.  It is called from grokclassfn and tsubst.
85960967Sobrien   FN must be either a constructor or destructor.
86050397Sobrien
86190075Sobrien   The in-charge flag follows the 'this' parameter, and is followed by the
86290075Sobrien   VTT parm (if any), then the user-written parms.  */
86360967Sobrien
86450397Sobrienvoid
86550397Sobrienmaybe_retrofit_in_chrg (fn)
86650397Sobrien     tree fn;
86750397Sobrien{
86850397Sobrien  tree basetype, arg_types, parms, parm, fntype;
86950397Sobrien
87090075Sobrien  /* If we've already add the in-charge parameter don't do it again.  */
87190075Sobrien  if (DECL_HAS_IN_CHARGE_PARM_P (fn))
87260967Sobrien    return;
87360967Sobrien
87490075Sobrien  /* When processing templates we can't know, in general, whether or
87590075Sobrien     not we're going to have virtual baseclasses.  */
87690075Sobrien  if (uses_template_parms (fn))
87790075Sobrien    return;
87890075Sobrien
87990075Sobrien  /* We don't need an in-charge parameter for constructors that don't
88090075Sobrien     have virtual bases.  */
88150397Sobrien  if (DECL_CONSTRUCTOR_P (fn)
88290075Sobrien      && !TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
88350397Sobrien    return;
88450397Sobrien
88560967Sobrien  arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
88660967Sobrien  basetype = TREE_TYPE (TREE_VALUE (arg_types));
88760967Sobrien  arg_types = TREE_CHAIN (arg_types);
88860967Sobrien
88990075Sobrien  parms = TREE_CHAIN (DECL_ARGUMENTS (fn));
89090075Sobrien
89190075Sobrien  /* If this is a subobject constructor or destructor, our caller will
89290075Sobrien     pass us a pointer to our VTT.  */
89390075Sobrien  if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
89460967Sobrien    {
89590075Sobrien      parm = build_artificial_parm (vtt_parm_identifier, vtt_parm_type);
89660967Sobrien
89790075Sobrien      /* First add it to DECL_ARGUMENTS between 'this' and the real args...  */
89890075Sobrien      TREE_CHAIN (parm) = parms;
89990075Sobrien      parms = parm;
90090075Sobrien
90190075Sobrien      /* ...and then to TYPE_ARG_TYPES.  */
90290075Sobrien      arg_types = hash_tree_chain (vtt_parm_type, arg_types);
90390075Sobrien
90490075Sobrien      DECL_HAS_VTT_PARM_P (fn) = 1;
90560967Sobrien    }
90660967Sobrien
90790075Sobrien  /* Then add the in-charge parm (before the VTT parm).  */
90890075Sobrien  parm = build_artificial_parm (in_charge_identifier, integer_type_node);
90990075Sobrien  TREE_CHAIN (parm) = parms;
91090075Sobrien  parms = parm;
91190075Sobrien  arg_types = hash_tree_chain (integer_type_node, arg_types);
91250397Sobrien
91390075Sobrien  /* Insert our new parameter(s) into the list.  */
91490075Sobrien  TREE_CHAIN (DECL_ARGUMENTS (fn)) = parms;
91590075Sobrien
91690075Sobrien  /* And rebuild the function type.  */
91750397Sobrien  fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)),
91850397Sobrien				    arg_types);
91950397Sobrien  if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
92050397Sobrien    fntype = build_exception_variant (fntype,
92150397Sobrien				      TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)));
92250397Sobrien  TREE_TYPE (fn) = fntype;
92390075Sobrien
92490075Sobrien  /* Now we've got the in-charge parameter.  */
92590075Sobrien  DECL_HAS_IN_CHARGE_PARM_P (fn) = 1;
92650397Sobrien}
92750397Sobrien
92818334Speter/* Classes overload their constituent function names automatically.
92918334Speter   When a function name is declared in a record structure,
93018334Speter   its name is changed to it overloaded name.  Since names for
93118334Speter   constructors and destructors can conflict, we place a leading
93218334Speter   '$' for destructors.
93318334Speter
93418334Speter   CNAME is the name of the class we are grokking for.
93518334Speter
93618334Speter   FUNCTION is a FUNCTION_DECL.  It was created by `grokdeclarator'.
93718334Speter
93818334Speter   FLAGS contains bits saying what's special about today's
93918334Speter   arguments.  1 == DESTRUCTOR.  2 == OPERATOR.
94018334Speter
94118334Speter   If FUNCTION is a destructor, then we must add the `auto-delete' field
94218334Speter   as a second parameter.  There is some hair associated with the fact
94318334Speter   that we must "declare" this variable in the manner consistent with the
94418334Speter   way the rest of the arguments were declared.
94518334Speter
94618334Speter   QUALS are the qualifiers for the this pointer.  */
94718334Speter
94818334Spetervoid
94952284Sobriengrokclassfn (ctype, function, flags, quals)
95052284Sobrien     tree ctype, function;
95118334Speter     enum overload_flags flags;
95218334Speter     tree quals;
95318334Speter{
95418334Speter  tree fn_name = DECL_NAME (function);
95590075Sobrien  int this_quals = TYPE_UNQUALIFIED;
95618334Speter
95790075Sobrien  /* Even within an `extern "C"' block, members get C++ linkage.  See
95890075Sobrien     [dcl.link] for details.  */
95990075Sobrien  SET_DECL_LANGUAGE (function, lang_cplusplus);
96090075Sobrien
96118334Speter  if (fn_name == NULL_TREE)
96218334Speter    {
96318334Speter      error ("name missing for member function");
96418334Speter      fn_name = get_identifier ("<anonymous>");
96518334Speter      DECL_NAME (function) = fn_name;
96618334Speter    }
96718334Speter
96818334Speter  if (quals)
96990075Sobrien    this_quals = grok_method_quals (ctype, function, quals);
97018334Speter
97118334Speter  if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
97218334Speter    {
97318334Speter      /* Must add the class instance variable up front.  */
97418334Speter      /* Right now we just make this a pointer.  But later
97518334Speter	 we may wish to make it special.  */
97690075Sobrien      tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (function)));
97790075Sobrien      tree qual_type;
97890075Sobrien      tree parm;
97918334Speter
98090075Sobrien      /* The `this' parameter is implicitly `const'; it cannot be
98190075Sobrien	 assigned to.  */
98290075Sobrien      this_quals |= TYPE_QUAL_CONST;
98390075Sobrien      qual_type = cp_build_qualified_type (type, this_quals);
98490075Sobrien      parm = build_artificial_parm (this_identifier, qual_type);
98590075Sobrien      c_apply_type_quals_to_decl (this_quals, parm);
98618334Speter      TREE_CHAIN (parm) = last_function_parms;
98718334Speter      last_function_parms = parm;
98818334Speter    }
98918334Speter
99050397Sobrien  DECL_ARGUMENTS (function) = last_function_parms;
99150397Sobrien  DECL_CONTEXT (function) = ctype;
99250397Sobrien
99390075Sobrien  if (flags == DTOR_FLAG)
99490075Sobrien    DECL_DESTRUCTOR_P (function) = 1;
99590075Sobrien
99650397Sobrien  if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function))
99790075Sobrien    maybe_retrofit_in_chrg (function);
99850397Sobrien
99918334Speter  if (flags == DTOR_FLAG)
100018334Speter    {
100190075Sobrien      DECL_DESTRUCTOR_P (function) = 1;
100218334Speter      TYPE_HAS_DESTRUCTOR (ctype) = 1;
100318334Speter    }
100418334Speter}
100518334Speter
100618334Speter/* Create an ARRAY_REF, checking for the user doing things backwards
100718334Speter   along the way.  */
100850397Sobrien
100918334Spetertree
101018334Spetergrok_array_decl (array_expr, index_exp)
101118334Speter     tree array_expr, index_exp;
101218334Speter{
101318334Speter  tree type = TREE_TYPE (array_expr);
101418334Speter  tree p1, p2, i1, i2;
101518334Speter
101618334Speter  if (type == error_mark_node || index_exp == error_mark_node)
101718334Speter    return error_mark_node;
101850397Sobrien  if (processing_template_decl)
101950397Sobrien    return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE,
102050397Sobrien		      array_expr, index_exp);
102150397Sobrien
102218334Speter  if (type == NULL_TREE)
102318334Speter    {
102418334Speter      /* Something has gone very wrong.  Assume we are mistakenly reducing
102518334Speter	 an expression instead of a declaration.  */
102618334Speter      error ("parser may be lost: is there a '{' missing somewhere?");
102718334Speter      return NULL_TREE;
102818334Speter    }
102918334Speter
103018334Speter  if (TREE_CODE (type) == OFFSET_TYPE
103118334Speter      || TREE_CODE (type) == REFERENCE_TYPE)
103218334Speter    type = TREE_TYPE (type);
103318334Speter
103418334Speter  /* If they have an `operator[]', use that.  */
103550397Sobrien  if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp)))
103618334Speter    return build_opfncall (ARRAY_REF, LOOKUP_NORMAL,
103718334Speter			   array_expr, index_exp, NULL_TREE);
103818334Speter
103952284Sobrien  /* Otherwise, create an ARRAY_REF for a pointer or array type.  It
104052284Sobrien     is a little-known fact that, if `a' is an array and `i' is an
104152284Sobrien     int, you can write `i[a]', which means the same thing as `a[i]'.  */
104218334Speter
104318334Speter  if (TREE_CODE (type) == ARRAY_TYPE)
104418334Speter    p1 = array_expr;
104518334Speter  else
104618334Speter    p1 = build_expr_type_conversion (WANT_POINTER, array_expr, 0);
104718334Speter
104818334Speter  if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE)
104918334Speter    p2 = index_exp;
105018334Speter  else
105118334Speter    p2 = build_expr_type_conversion (WANT_POINTER, index_exp, 0);
105218334Speter
105318334Speter  i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr, 0);
105418334Speter  i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp, 0);
105518334Speter
105618334Speter  if ((p1 && i2) && (i1 && p2))
105718334Speter    error ("ambiguous conversion for array subscript");
105818334Speter
105918334Speter  if (p1 && i2)
106018334Speter    array_expr = p1, index_exp = i2;
106118334Speter  else if (i1 && p2)
106218334Speter    array_expr = p2, index_exp = i1;
106318334Speter  else
106418334Speter    {
106590075Sobrien      error ("invalid types `%T[%T]' for array subscript",
106618334Speter		type, TREE_TYPE (index_exp));
106718334Speter      return error_mark_node;
106818334Speter    }
106918334Speter
107018334Speter  if (array_expr == error_mark_node || index_exp == error_mark_node)
107118334Speter    error ("ambiguous conversion for array subscript");
107218334Speter
107318334Speter  return build_array_ref (array_expr, index_exp);
107418334Speter}
107518334Speter
107618334Speter/* Given the cast expression EXP, checking out its validity.   Either return
107718334Speter   an error_mark_node if there was an unavoidable error, return a cast to
107818334Speter   void for trying to delete a pointer w/ the value 0, or return the
107918334Speter   call to delete.  If DOING_VEC is 1, we handle things differently
108018334Speter   for doing an array delete.  If DOING_VEC is 2, they gave us the
108118334Speter   array size as an argument to delete.
108218334Speter   Implements ARM $5.3.4.  This is called from the parser.  */
108350397Sobrien
108418334Spetertree
108518334Speterdelete_sanity (exp, size, doing_vec, use_global_delete)
108618334Speter     tree exp, size;
108718334Speter     int doing_vec, use_global_delete;
108818334Speter{
108950397Sobrien  tree t, type;
109018334Speter  /* For a regular vector delete (aka, no size argument) we will pass
109118334Speter     this down as a NULL_TREE into build_vec_delete.  */
109218334Speter  tree maxindex = NULL_TREE;
109318334Speter
109450397Sobrien  if (exp == error_mark_node)
109550397Sobrien    return exp;
109650397Sobrien
109750397Sobrien  if (processing_template_decl)
109818334Speter    {
109950397Sobrien      t = build_min (DELETE_EXPR, void_type_node, exp, size);
110050397Sobrien      DELETE_EXPR_USE_GLOBAL (t) = use_global_delete;
110150397Sobrien      DELETE_EXPR_USE_VEC (t) = doing_vec;
110250397Sobrien      return t;
110350397Sobrien    }
110418334Speter
110550397Sobrien  if (TREE_CODE (exp) == OFFSET_REF)
110650397Sobrien    exp = resolve_offset_ref (exp);
110750397Sobrien  exp = convert_from_reference (exp);
110850397Sobrien  t = stabilize_reference (exp);
110950397Sobrien  t = build_expr_type_conversion (WANT_POINTER, t, 1);
111050397Sobrien
111150397Sobrien  if (t == NULL_TREE || t == error_mark_node)
111250397Sobrien    {
111390075Sobrien      error ("type `%#T' argument given to `delete', expected pointer",
111450397Sobrien		TREE_TYPE (exp));
111550397Sobrien      return error_mark_node;
111618334Speter    }
111718334Speter
111850397Sobrien  if (doing_vec == 2)
111918334Speter    {
112090075Sobrien      maxindex = cp_build_binary_op (MINUS_EXPR, size, integer_one_node);
112150397Sobrien      pedwarn ("anachronistic use of array size in vector delete");
112218334Speter    }
112318334Speter
112450397Sobrien  type = TREE_TYPE (t);
112550397Sobrien
112650397Sobrien  /* As of Valley Forge, you can delete a pointer to const.  */
112750397Sobrien
112850397Sobrien  /* You can't delete functions.  */
112950397Sobrien  if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
113018334Speter    {
113190075Sobrien      error ("cannot delete a function.  Only pointer-to-objects are valid arguments to `delete'");
113250397Sobrien      return error_mark_node;
113318334Speter    }
113418334Speter
113552284Sobrien  /* Deleting ptr to void is undefined behaviour [expr.delete/3].  */
113652284Sobrien  if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE)
113790075Sobrien    {
113890075Sobrien      warning ("deleting `%T' is undefined", type);
113990075Sobrien      doing_vec = 0;
114090075Sobrien    }
114190075Sobrien
114250397Sobrien  /* An array can't have been allocated by new, so complain.  */
114350397Sobrien  if (TREE_CODE (t) == ADDR_EXPR
114450397Sobrien      && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL
114550397Sobrien      && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == ARRAY_TYPE)
114690075Sobrien    warning ("deleting array `%#D'", TREE_OPERAND (t, 0));
114750397Sobrien
114850397Sobrien  /* Deleting a pointer with the value zero is valid and has no effect.  */
114950397Sobrien  if (integer_zerop (t))
115050397Sobrien    return build1 (NOP_EXPR, void_type_node, t);
115150397Sobrien
115218334Speter  if (doing_vec)
115390075Sobrien    return build_vec_delete (t, maxindex, sfk_deleting_destructor,
115490075Sobrien			     use_global_delete);
115518334Speter  else
115618334Speter    {
115718334Speter      if (IS_AGGR_TYPE (TREE_TYPE (type))
115818334Speter	  && TYPE_GETS_REG_DELETE (TREE_TYPE (type)))
115918334Speter	{
116018334Speter	  /* Only do access checking here; we'll be calling op delete
116118334Speter	     from the destructor.  */
116250397Sobrien	  tree tmp = build_op_delete_call (DELETE_EXPR, t, size_zero_node,
116350397Sobrien					   LOOKUP_NORMAL, NULL_TREE);
116418334Speter	  if (tmp == error_mark_node)
116518334Speter	    return error_mark_node;
116618334Speter	}
116718334Speter
116890075Sobrien      return build_delete (type, t, sfk_deleting_destructor,
116950397Sobrien			   LOOKUP_NORMAL, use_global_delete);
117018334Speter    }
117118334Speter}
117218334Speter
117350397Sobrien/* Report an error if the indicated template declaration is not the
117450397Sobrien   sort of thing that should be a member template.  */
117550397Sobrien
117650397Sobrienvoid
117750397Sobriencheck_member_template (tmpl)
117850397Sobrien     tree tmpl;
117950397Sobrien{
118050397Sobrien  tree decl;
118150397Sobrien
118250397Sobrien  my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0);
118350397Sobrien  decl = DECL_TEMPLATE_RESULT (tmpl);
118450397Sobrien
118550397Sobrien  if (TREE_CODE (decl) == FUNCTION_DECL
118650397Sobrien      || (TREE_CODE (decl) == TYPE_DECL
118750397Sobrien	  && IS_AGGR_TYPE (TREE_TYPE (decl))))
118850397Sobrien    {
118950397Sobrien      if (current_function_decl)
119050397Sobrien	/* 14.5.2.2 [temp.mem]
119150397Sobrien
119250397Sobrien	   A local class shall not have member templates. */
119390075Sobrien	error ("invalid declaration of member template `%#D' in local class",
119450397Sobrien		  decl);
119550397Sobrien
119650397Sobrien      if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))
119750397Sobrien	{
119850397Sobrien	  /* 14.5.2.3 [temp.mem]
119950397Sobrien
120050397Sobrien	     A member function template shall not be virtual.  */
120190075Sobrien	  error
120250397Sobrien	    ("invalid use of `virtual' in template declaration of `%#D'",
120350397Sobrien	     decl);
120450397Sobrien	  DECL_VIRTUAL_P (decl) = 0;
120550397Sobrien	}
120650397Sobrien
120750397Sobrien      /* The debug-information generating code doesn't know what to do
120850397Sobrien	 with member templates.  */
120950397Sobrien      DECL_IGNORED_P (tmpl) = 1;
121050397Sobrien    }
121150397Sobrien  else
121290075Sobrien    error ("template declaration of `%#D'", decl);
121350397Sobrien}
121450397Sobrien
121550397Sobrien/* Return true iff TYPE is a valid Java parameter or return type. */
121650397Sobrien
121752284Sobrienstatic int
121850397Sobrienacceptable_java_type (type)
121950397Sobrien     tree type;
122050397Sobrien{
122150397Sobrien  if (TREE_CODE (type) == VOID_TYPE || TYPE_FOR_JAVA (type))
122250397Sobrien    return 1;
122390075Sobrien  if (TREE_CODE (type) == POINTER_TYPE || TREE_CODE (type) == REFERENCE_TYPE)
122450397Sobrien    {
122550397Sobrien      type = TREE_TYPE (type);
122650397Sobrien      if (TREE_CODE (type) == RECORD_TYPE)
122750397Sobrien	{
122852284Sobrien	  tree args;  int i;
122952284Sobrien	  if (! TYPE_FOR_JAVA (type))
123052284Sobrien	    return 0;
123152284Sobrien	  if (! CLASSTYPE_TEMPLATE_INFO (type))
123252284Sobrien	    return 1;
123352284Sobrien	  args = CLASSTYPE_TI_ARGS (type);
123452284Sobrien	  i = TREE_VEC_LENGTH (args);
123552284Sobrien	  while (--i >= 0)
123652284Sobrien	    {
123752284Sobrien	      type = TREE_VEC_ELT (args, i);
123852284Sobrien	      if (TREE_CODE (type) == POINTER_TYPE)
123952284Sobrien		type = TREE_TYPE (type);
124052284Sobrien	      if (! TYPE_FOR_JAVA (type))
124152284Sobrien		return 0;
124252284Sobrien	    }
124352284Sobrien	  return 1;
124450397Sobrien	}
124550397Sobrien    }
124650397Sobrien  return 0;
124750397Sobrien}
124850397Sobrien
124950397Sobrien/* For a METHOD in a Java class CTYPE, return 1 if
125050397Sobrien   the parameter and return types are valid Java types.
125150397Sobrien   Otherwise, print appropriate error messages, and return 0.  */
125250397Sobrien
125350397Sobrienint
125452284Sobriencheck_java_method (method)
125552284Sobrien     tree method;
125650397Sobrien{
125750397Sobrien  int jerr = 0;
125850397Sobrien  tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
125950397Sobrien  tree ret_type = TREE_TYPE (TREE_TYPE (method));
126050397Sobrien  if (! acceptable_java_type (ret_type))
126150397Sobrien    {
126290075Sobrien      error ("Java method '%D' has non-Java return type `%T'",
126350397Sobrien		method, ret_type);
126450397Sobrien      jerr++;
126550397Sobrien    }
126650397Sobrien  for (; arg_types != NULL_TREE; arg_types = TREE_CHAIN (arg_types))
126750397Sobrien    {
126850397Sobrien      tree type = TREE_VALUE (arg_types);
126950397Sobrien      if (! acceptable_java_type (type))
127050397Sobrien	{
127190075Sobrien	  error ("Java method '%D' has non-Java parameter type `%T'",
127250397Sobrien		    method, type);
127350397Sobrien	  jerr++;
127450397Sobrien	}
127550397Sobrien    }
127650397Sobrien  return jerr ? 0 : 1;
127750397Sobrien}
127850397Sobrien
127918334Speter/* Sanity check: report error if this function FUNCTION is not
128018334Speter   really a member of the class (CTYPE) it is supposed to belong to.
128118334Speter   CNAME is the same here as it is for grokclassfn above.  */
128218334Speter
128318334Spetertree
128450397Sobriencheck_classfn (ctype, function)
128550397Sobrien     tree ctype, function;
128618334Speter{
128718334Speter  tree fn_name = DECL_NAME (function);
128850397Sobrien  tree fndecl, fndecls;
128950397Sobrien  tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype));
129018334Speter  tree *methods = 0;
129118334Speter  tree *end = 0;
129252284Sobrien
129352284Sobrien  if (DECL_USE_TEMPLATE (function)
129490075Sobrien      && !(TREE_CODE (function) == TEMPLATE_DECL
129590075Sobrien	   && DECL_TEMPLATE_SPECIALIZATION (function))
129652284Sobrien      && is_member_template (DECL_TI_TEMPLATE (function)))
129752284Sobrien    /* Since this is a specialization of a member template,
129852284Sobrien       we're not going to find the declaration in the class.
129952284Sobrien       For example, in:
130052284Sobrien
130152284Sobrien         struct S { template <typename T> void f(T); };
130252284Sobrien         template <> void S::f(int);
130352284Sobrien
130452284Sobrien       we're not going to find `S::f(int)', but there's no
130552284Sobrien       reason we should, either.  We let our callers know we didn't
130652284Sobrien       find the method, but we don't complain.  */
130752284Sobrien    return NULL_TREE;
130852284Sobrien
130918334Speter  if (method_vec != 0)
131018334Speter    {
131118334Speter      methods = &TREE_VEC_ELT (method_vec, 0);
131218334Speter      end = TREE_VEC_END (method_vec);
131318334Speter
131418334Speter      /* First suss out ctors and dtors.  */
131550397Sobrien      if (*methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))
131650397Sobrien	  && DECL_CONSTRUCTOR_P (function))
131718334Speter	goto got_it;
131850397Sobrien      if (*++methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))
131990075Sobrien	  && DECL_DESTRUCTOR_P (function))
132050397Sobrien	goto got_it;
132118334Speter
132252284Sobrien      while (++methods != end && *methods)
132318334Speter	{
132450397Sobrien	  fndecl = *methods;
132550397Sobrien	  if (fn_name == DECL_NAME (OVL_CURRENT (*methods)))
132618334Speter	    {
132718334Speter	    got_it:
132850397Sobrien	      for (fndecls = *methods; fndecls != NULL_TREE;
132950397Sobrien		   fndecls = OVL_NEXT (fndecls))
133018334Speter		{
133150397Sobrien		  fndecl = OVL_CURRENT (fndecls);
133250397Sobrien
133350397Sobrien		  /* We cannot simply call decls_match because this
133450397Sobrien		     doesn't work for static member functions that are
133550397Sobrien                     pretending to be methods, and because the name
133650397Sobrien		     may have been changed by asm("new_name").  */
133718334Speter		  if (DECL_NAME (function) == DECL_NAME (fndecl))
133818334Speter		    {
133918334Speter		      tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
134018334Speter		      tree p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
134118334Speter
134218334Speter		      /* Get rid of the this parameter on functions that become
134350397Sobrien			 static.  */
134418334Speter		      if (DECL_STATIC_FUNCTION_P (fndecl)
134518334Speter			  && TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
134618334Speter			p1 = TREE_CHAIN (p1);
134718334Speter
134852284Sobrien		      if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
134952284Sobrien				       TREE_TYPE (TREE_TYPE (fndecl)))
135052284Sobrien			  && compparms (p1, p2)
135150397Sobrien			  && (DECL_TEMPLATE_SPECIALIZATION (function)
135250397Sobrien			      == DECL_TEMPLATE_SPECIALIZATION (fndecl))
135350397Sobrien			  && (!DECL_TEMPLATE_SPECIALIZATION (function)
135450397Sobrien			      || (DECL_TI_TEMPLATE (function)
135550397Sobrien				  == DECL_TI_TEMPLATE (fndecl))))
135650397Sobrien			return fndecl;
135718334Speter		    }
135818334Speter		}
135918334Speter	      break;		/* loser */
136018334Speter	    }
136118334Speter	}
136218334Speter    }
136318334Speter
136452284Sobrien  if (methods != end && *methods)
136518334Speter    {
136618334Speter      tree fndecl = *methods;
136790075Sobrien      error ("prototype for `%#D' does not match any in class `%T'",
136818334Speter		function, ctype);
136950397Sobrien      cp_error_at ("candidate%s: %+#D", OVL_NEXT (fndecl) ? "s are" : " is",
137050397Sobrien		   OVL_CURRENT (fndecl));
137150397Sobrien      while (fndecl = OVL_NEXT (fndecl), fndecl)
137250397Sobrien	cp_error_at ("                %#D", OVL_CURRENT(fndecl));
137318334Speter    }
137418334Speter  else
137518334Speter    {
137618334Speter      methods = 0;
137790075Sobrien      if (!COMPLETE_TYPE_P (ctype))
137852284Sobrien        incomplete_type_error (function, ctype);
137952284Sobrien      else
138090075Sobrien        error ("no `%#D' member function declared in class `%T'",
138152284Sobrien		  function, ctype);
138218334Speter    }
138318334Speter
138450397Sobrien  /* If we did not find the method in the class, add it to avoid
138552284Sobrien     spurious errors (unless the CTYPE is not yet defined, in which
138652284Sobrien     case we'll only confuse ourselves when the function is declared
138752284Sobrien     properly within the class.  */
138890075Sobrien  if (COMPLETE_TYPE_P (ctype))
138990075Sobrien    add_method (ctype, function, /*error_p=*/1);
139018334Speter  return NULL_TREE;
139118334Speter}
139218334Speter
139352284Sobrien/* We have just processed the DECL, which is a static data member.
139452284Sobrien   Its initializer, if present, is INIT.  The ASMSPEC_TREE, if
139552284Sobrien   present, is the assembly-language name for the data member.
139690075Sobrien   FLAGS is as for cp_finish_decl.  */
139752284Sobrien
139852284Sobrienvoid
139990075Sobrienfinish_static_data_member_decl (decl, init, asmspec_tree, flags)
140052284Sobrien     tree decl;
140152284Sobrien     tree init;
140252284Sobrien     tree asmspec_tree;
140352284Sobrien     int flags;
140452284Sobrien{
140590075Sobrien  my_friendly_assert (TREE_PUBLIC (decl), 0);
140652284Sobrien
140790075Sobrien  DECL_CONTEXT (decl) = current_class_type;
140852284Sobrien
140952284Sobrien  /* We cannot call pushdecl here, because that would fill in the
141090075Sobrien     TREE_CHAIN of our decl.  Instead, we modify cp_finish_decl to do
141152284Sobrien     the right thing, namely, to put this decl out straight away.  */
141252284Sobrien  /* current_class_type can be NULL_TREE in case of error.  */
141390075Sobrien  if (!asmspec_tree && current_class_type)
141490075Sobrien    DECL_INITIAL (decl) = error_mark_node;
141590075Sobrien
141652284Sobrien  if (! processing_template_decl)
141752284Sobrien    {
141852284Sobrien      if (!pending_statics)
141952284Sobrien	VARRAY_TREE_INIT (pending_statics, 32, "pending_statics");
142090075Sobrien      VARRAY_PUSH_TREE (pending_statics, decl);
142152284Sobrien    }
142252284Sobrien
142390075Sobrien  if (LOCAL_CLASS_P (current_class_type))
142490075Sobrien    pedwarn ("local class `%#T' shall not have static data member `%#D'",
142590075Sobrien	     current_class_type, decl);
142690075Sobrien
142752284Sobrien  /* Static consts need not be initialized in the class definition.  */
142852284Sobrien  if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
142952284Sobrien    {
143090075Sobrien      static int explained = 0;
143152284Sobrien
143252284Sobrien      error ("initializer invalid for static member with constructor");
143390075Sobrien      if (!explained)
143490075Sobrien        {
143590075Sobrien	  error ("(an out of class initialization is required)");
143690075Sobrien	  explained = 1;
143790075Sobrien	}
143890075Sobrien      init = NULL_TREE;
143952284Sobrien    }
144052284Sobrien  /* Force the compiler to know when an uninitialized static const
144152284Sobrien     member is being used.  */
144252284Sobrien  if (CP_TYPE_CONST_P (TREE_TYPE (decl)) && init == 0)
144352284Sobrien    TREE_USED (decl) = 1;
144452284Sobrien  DECL_INITIAL (decl) = init;
144552284Sobrien  DECL_IN_AGGR_P (decl) = 1;
144652284Sobrien
144790075Sobrien  cp_finish_decl (decl, init, asmspec_tree, flags);
144852284Sobrien}
144952284Sobrien
145018334Speter/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)
145190075Sobrien   of a structure component, returning a _DECL node.
145218334Speter   QUALS is a list of type qualifiers for this decl (such as for declaring
145318334Speter   const member functions).
145418334Speter
145518334Speter   This is done during the parsing of the struct declaration.
145690075Sobrien   The _DECL nodes are chained together and the lot of them
145718334Speter   are ultimately passed to `build_struct' to make the RECORD_TYPE node.
145818334Speter
145918334Speter   If class A defines that certain functions in class B are friends, then
146018334Speter   the way I have set things up, it is B who is interested in permission
146118334Speter   granted by A.  However, it is in A's context that these declarations
146218334Speter   are parsed.  By returning a void_type_node, class A does not attempt
146318334Speter   to incorporate the declarations of the friends within its structure.
146418334Speter
146518334Speter   DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING
146618334Speter   CHANGES TO CODE IN `start_method'.  */
146718334Speter
146818334Spetertree
146950397Sobriengrokfield (declarator, declspecs, init, asmspec_tree, attrlist)
147050397Sobrien     tree declarator, declspecs, init, asmspec_tree, attrlist;
147118334Speter{
147290075Sobrien  tree value;
147390075Sobrien  const char *asmspec = 0;
147418334Speter  int flags = LOOKUP_ONLYCONVERTING;
147518334Speter
147618334Speter  /* Convert () initializers to = initializers.  */
147718334Speter  if (init == NULL_TREE && declarator != NULL_TREE
147818334Speter      && TREE_CODE (declarator) == CALL_EXPR
147918334Speter      && TREE_OPERAND (declarator, 0)
148018334Speter      && (TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE
148118334Speter	  || TREE_CODE (TREE_OPERAND (declarator, 0)) == SCOPE_REF)
148290075Sobrien      && parmlist_is_exprlist (CALL_DECLARATOR_PARMS (declarator)))
148318334Speter    {
148490075Sobrien      /* It's invalid to try to initialize a data member using a
148590075Sobrien	 functional notation, e.g.:
148690075Sobrien
148790075Sobrien            struct S {
148890075Sobrien	      static int i (3);
148990075Sobrien	    };
149090075Sobrien
149190075Sobrien	 Explain that to the user.  */
149290075Sobrien      static int explained;
149390075Sobrien
149490075Sobrien      error ("invalid data member initialization");
149590075Sobrien      if (!explained)
149690075Sobrien	{
149790075Sobrien	  error ("(use `=' to initialize static data members)");
149890075Sobrien	  explained = 1;
149990075Sobrien	}
150090075Sobrien
150118334Speter      declarator = TREE_OPERAND (declarator, 0);
150218334Speter      flags = 0;
150318334Speter    }
150418334Speter
150550397Sobrien  if (declspecs == NULL_TREE
150650397Sobrien      && TREE_CODE (declarator) == SCOPE_REF
150750397Sobrien      && TREE_CODE (TREE_OPERAND (declarator, 1)) == IDENTIFIER_NODE)
150850397Sobrien    {
150950397Sobrien      /* Access declaration */
151050397Sobrien      if (! IS_AGGR_TYPE_CODE (TREE_CODE (TREE_OPERAND (declarator, 0))))
151150397Sobrien	;
151250397Sobrien      else if (TREE_COMPLEXITY (declarator) == current_class_depth)
151352284Sobrien	pop_nested_class ();
151450397Sobrien      return do_class_using_decl (declarator);
151550397Sobrien    }
151650397Sobrien
151718334Speter  if (init
151818334Speter      && TREE_CODE (init) == TREE_LIST
151918334Speter      && TREE_VALUE (init) == error_mark_node
152018334Speter      && TREE_CHAIN (init) == NULL_TREE)
152150397Sobrien    init = NULL_TREE;
152218334Speter
152390075Sobrien  value = grokdeclarator (declarator, declspecs, FIELD, init != 0, &attrlist);
152452284Sobrien  if (! value || value == error_mark_node)
152552284Sobrien    /* friend or constructor went bad.  */
152652284Sobrien    return value;
152790075Sobrien  if (TREE_TYPE (value) == error_mark_node)
152890075Sobrien    return error_mark_node;
152918334Speter
153018334Speter  /* Pass friendly classes back.  */
153118334Speter  if (TREE_CODE (value) == VOID_TYPE)
153218334Speter    return void_type_node;
153318334Speter
153418334Speter  if (DECL_NAME (value) != NULL_TREE
153518334Speter      && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_'
153618334Speter      && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr"))
153790075Sobrien    error ("member `%D' conflicts with virtual function table field name",
153850397Sobrien	      value);
153918334Speter
154018334Speter  /* Stash away type declarations.  */
154118334Speter  if (TREE_CODE (value) == TYPE_DECL)
154218334Speter    {
154318334Speter      DECL_NONLOCAL (value) = 1;
154418334Speter      DECL_CONTEXT (value) = current_class_type;
154518334Speter
154690075Sobrien      if (CLASS_TYPE_P (TREE_TYPE (value)))
154790075Sobrien        CLASSTYPE_GOT_SEMICOLON (TREE_TYPE (value)) = 1;
154890075Sobrien
154990075Sobrien      if (processing_template_decl)
155090075Sobrien	value = push_template_decl (value);
155118334Speter
155218334Speter      return value;
155318334Speter    }
155418334Speter
155518334Speter  if (DECL_IN_AGGR_P (value))
155618334Speter    {
155790075Sobrien      error ("`%D' is already defined in `%T'", value,
155852284Sobrien		DECL_CONTEXT (value));
155918334Speter      return void_type_node;
156018334Speter    }
156118334Speter
156218334Speter  if (asmspec_tree)
156318334Speter    asmspec = TREE_STRING_POINTER (asmspec_tree);
156418334Speter
156518334Speter  if (init)
156618334Speter    {
156790075Sobrien      if (TREE_CODE (value) == FUNCTION_DECL)
156818334Speter	{
156918334Speter	  grok_function_init (value, init);
157018334Speter	  init = NULL_TREE;
157118334Speter	}
157218334Speter      else if (pedantic && TREE_CODE (value) != VAR_DECL)
157318334Speter	/* Already complained in grokdeclarator.  */
157418334Speter	init = NULL_TREE;
157518334Speter      else
157618334Speter	{
157718334Speter	  /* We allow initializers to become parameters to base
157818334Speter             initializers.  */
157918334Speter	  if (TREE_CODE (init) == TREE_LIST)
158018334Speter	    {
158118334Speter	      if (TREE_CHAIN (init) == NULL_TREE)
158218334Speter		init = TREE_VALUE (init);
158318334Speter	      else
158418334Speter		init = digest_init (TREE_TYPE (value), init, (tree *)0);
158518334Speter	    }
158618334Speter
158718334Speter	  if (TREE_CODE (init) == CONST_DECL)
158818334Speter	    init = DECL_INITIAL (init);
158918334Speter	  else if (TREE_READONLY_DECL_P (init))
159018334Speter	    init = decl_constant_value (init);
159118334Speter	  else if (TREE_CODE (init) == CONSTRUCTOR)
159218334Speter	    init = digest_init (TREE_TYPE (value), init, (tree *)0);
159318334Speter	  if (init == error_mark_node)
159418334Speter	    /* We must make this look different than `error_mark_node'
159518334Speter	       because `decl_const_value' would mis-interpret it
159618334Speter	       as only meaning that this VAR_DECL is defined.  */
159718334Speter	    init = build1 (NOP_EXPR, TREE_TYPE (value), init);
159850397Sobrien	  else if (processing_template_decl)
159950397Sobrien	    ;
160018334Speter	  else if (! TREE_CONSTANT (init))
160118334Speter	    {
160218334Speter	      /* We can allow references to things that are effectively
160318334Speter		 static, since references are initialized with the address.  */
160418334Speter	      if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE
160518334Speter		  || (TREE_STATIC (init) == 0
160690075Sobrien		      && (!DECL_P (init) || DECL_EXTERNAL (init) == 0)))
160718334Speter		{
160818334Speter		  error ("field initializer is not constant");
160918334Speter		  init = error_mark_node;
161018334Speter		}
161118334Speter	    }
161218334Speter	}
161318334Speter    }
161418334Speter
161550397Sobrien  if (processing_template_decl && ! current_function_decl
161650397Sobrien      && (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL))
161750397Sobrien    value = push_template_decl (value);
161850397Sobrien
161918336Speter  if (attrlist)
162090075Sobrien    cplus_decl_attributes (&value, attrlist, 0);
162118336Speter
162218334Speter  if (TREE_CODE (value) == VAR_DECL)
162318334Speter    {
162452284Sobrien      finish_static_data_member_decl (value, init, asmspec_tree,
162590075Sobrien				      flags);
162618334Speter      return value;
162718334Speter    }
162818334Speter  if (TREE_CODE (value) == FIELD_DECL)
162918334Speter    {
163018334Speter      if (asmspec)
163190075Sobrien	error ("`asm' specifiers are not permitted on non-static data members");
163218334Speter      if (DECL_INITIAL (value) == error_mark_node)
163318334Speter	init = error_mark_node;
163490075Sobrien      cp_finish_decl (value, init, NULL_TREE, flags);
163518334Speter      DECL_INITIAL (value) = init;
163618334Speter      DECL_IN_AGGR_P (value) = 1;
163718334Speter      return value;
163818334Speter    }
163918334Speter  if (TREE_CODE (value) == FUNCTION_DECL)
164018334Speter    {
164118334Speter      if (asmspec)
164218334Speter	{
164318334Speter	  /* This must override the asm specifier which was placed
164418334Speter	     by grokclassfn.  Lay this out fresh.  */
164590075Sobrien	  SET_DECL_RTL (value, NULL_RTX);
164690075Sobrien	  SET_DECL_ASSEMBLER_NAME (value, get_identifier (asmspec));
164718334Speter	}
164890075Sobrien      if (!DECL_FRIEND_P (value))
164990075Sobrien	grok_special_member_properties (value);
165090075Sobrien
165190075Sobrien      cp_finish_decl (value, init, asmspec_tree, flags);
165218334Speter
165318334Speter      /* Pass friends back this way.  */
165418334Speter      if (DECL_FRIEND_P (value))
165518334Speter	return void_type_node;
165618334Speter
165718334Speter      DECL_IN_AGGR_P (value) = 1;
165818334Speter      return value;
165918334Speter    }
166090075Sobrien  abort ();
166118334Speter  /* NOTREACHED */
166218334Speter  return NULL_TREE;
166318334Speter}
166418334Speter
166518334Speter/* Like `grokfield', but for bitfields.
166618334Speter   WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node.  */
166718334Speter
166818334Spetertree
166918334Spetergrokbitfield (declarator, declspecs, width)
167018334Speter     tree declarator, declspecs, width;
167118334Speter{
167218334Speter  register tree value = grokdeclarator (declarator, declspecs, BITFIELD,
167390075Sobrien					0, NULL);
167418334Speter
167518334Speter  if (! value) return NULL_TREE; /* friends went bad.  */
167618334Speter
167718334Speter  /* Pass friendly classes back.  */
167818334Speter  if (TREE_CODE (value) == VOID_TYPE)
167918334Speter    return void_type_node;
168018334Speter
168118334Speter  if (TREE_CODE (value) == TYPE_DECL)
168218334Speter    {
168390075Sobrien      error ("cannot declare `%D' to be a bit-field type", value);
168418334Speter      return NULL_TREE;
168518334Speter    }
168618334Speter
168790075Sobrien  /* Usually, finish_struct_1 catches bitfields with invalid types.
168852284Sobrien     But, in the case of bitfields with function type, we confuse
168952284Sobrien     ourselves into thinking they are member functions, so we must
169052284Sobrien     check here.  */
169152284Sobrien  if (TREE_CODE (value) == FUNCTION_DECL)
169252284Sobrien    {
169390075Sobrien      error ("cannot declare bit-field `%D' with function type",
169490075Sobrien	     DECL_NAME (value));
169552284Sobrien      return NULL_TREE;
169652284Sobrien    }
169752284Sobrien
169818334Speter  if (DECL_IN_AGGR_P (value))
169918334Speter    {
170090075Sobrien      error ("`%D' is already defined in the class %T", value,
170118334Speter		  DECL_CONTEXT (value));
170218334Speter      return void_type_node;
170318334Speter    }
170418334Speter
170518334Speter  GNU_xref_member (current_class_name, value);
170618334Speter
170718334Speter  if (TREE_STATIC (value))
170818334Speter    {
170990075Sobrien      error ("static member `%D' cannot be a bit-field", value);
171018334Speter      return NULL_TREE;
171118334Speter    }
171290075Sobrien  cp_finish_decl (value, NULL_TREE, NULL_TREE, 0);
171318334Speter
171418334Speter  if (width != error_mark_node)
171518334Speter    {
171650397Sobrien      constant_expression_warning (width);
171750397Sobrien      DECL_INITIAL (value) = width;
171852284Sobrien      SET_DECL_C_BIT_FIELD (value);
171918334Speter    }
172018334Speter
172118334Speter  DECL_IN_AGGR_P (value) = 1;
172218334Speter  return value;
172318334Speter}
172418334Speter
172518334Spetertree
172618334Spetergrokoptypename (declspecs, declarator)
172718334Speter     tree declspecs, declarator;
172818334Speter{
172990075Sobrien  tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL);
173090075Sobrien  return mangle_conv_op_name_for_type (t);
173118334Speter}
173218334Speter
173318334Speter/* When a function is declared with an initializer,
173418334Speter   do the right thing.  Currently, there are two possibilities:
173518334Speter
173618334Speter   class B
173718334Speter   {
173818334Speter    public:
173918334Speter     // initialization possibility #1.
174018334Speter     virtual void f () = 0;
174118334Speter     int g ();
174218334Speter   };
174318334Speter
174418334Speter   class D1 : B
174518334Speter   {
174618334Speter    public:
174718334Speter     int d1;
174818334Speter     // error, no f ();
174918334Speter   };
175018334Speter
175118334Speter   class D2 : B
175218334Speter   {
175318334Speter    public:
175418334Speter     int d2;
175518334Speter     void f ();
175618334Speter   };
175718334Speter
175818334Speter   class D3 : B
175918334Speter   {
176018334Speter    public:
176118334Speter     int d3;
176218334Speter     // initialization possibility #2
176318334Speter     void f () = B::f;
176418334Speter   };
176518334Speter
176618334Speter*/
176718334Speter
176818334Speterstatic void
176918334Spetergrok_function_init (decl, init)
177018334Speter     tree decl;
177118334Speter     tree init;
177218334Speter{
177318334Speter  /* An initializer for a function tells how this function should
177418334Speter     be inherited.  */
177518334Speter  tree type = TREE_TYPE (decl);
177618334Speter
177718334Speter  if (TREE_CODE (type) == FUNCTION_TYPE)
177890075Sobrien    error ("initializer specified for non-member function `%D'", decl);
177918334Speter  else if (integer_zerop (init))
178090075Sobrien    DECL_PURE_VIRTUAL_P (decl) = 1;
178118334Speter  else
178290075Sobrien    error ("invalid initializer for virtual method `%D'", decl);
178318334Speter}
178418334Speter
178518334Spetervoid
178690075Sobriencplus_decl_attributes (decl, attributes, flags)
178790075Sobrien     tree *decl, attributes;
178890075Sobrien     int flags;
178918334Speter{
179090075Sobrien  if (*decl == NULL_TREE || *decl == void_type_node)
179118334Speter    return;
179218334Speter
179390075Sobrien  if (TREE_CODE (*decl) == TEMPLATE_DECL)
179490075Sobrien    decl = &DECL_TEMPLATE_RESULT (*decl);
179518334Speter
179690075Sobrien  decl_attributes (decl, attributes, flags);
179718334Speter
179890075Sobrien  if (TREE_CODE (*decl) == TYPE_DECL)
179990075Sobrien    SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
180018334Speter}
180118334Speter
180218334Speter/* CONSTRUCTOR_NAME:
180318334Speter   Return the name for the constructor (or destructor) for the
180418334Speter   specified class.  Argument can be RECORD_TYPE, TYPE_DECL, or
180518334Speter   IDENTIFIER_NODE.  When given a template, this routine doesn't
180618334Speter   lose the specialization.  */
180750397Sobrien
180818334Spetertree
180918334Speterconstructor_name_full (thing)
181018334Speter     tree thing;
181118334Speter{
181250397Sobrien  if (TREE_CODE (thing) == TEMPLATE_TYPE_PARM
181390075Sobrien      || TREE_CODE (thing) == BOUND_TEMPLATE_TEMPLATE_PARM
181450397Sobrien      || TREE_CODE (thing) == TYPENAME_TYPE)
181550397Sobrien    thing = TYPE_NAME (thing);
181650397Sobrien  else if (IS_AGGR_TYPE_CODE (TREE_CODE (thing)))
181718334Speter    {
181818334Speter      if (TYPE_WAS_ANONYMOUS (thing) && TYPE_HAS_CONSTRUCTOR (thing))
181950397Sobrien	thing = DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (thing), 0)));
182018334Speter      else
182118334Speter	thing = TYPE_NAME (thing);
182218334Speter    }
182318334Speter  if (TREE_CODE (thing) == TYPE_DECL
182418334Speter      || (TREE_CODE (thing) == TEMPLATE_DECL
182550397Sobrien	  && TREE_CODE (DECL_TEMPLATE_RESULT (thing)) == TYPE_DECL))
182618334Speter    thing = DECL_NAME (thing);
182718334Speter  my_friendly_assert (TREE_CODE (thing) == IDENTIFIER_NODE, 197);
182818334Speter  return thing;
182918334Speter}
183018334Speter
183118334Speter/* CONSTRUCTOR_NAME:
183218334Speter   Return the name for the constructor (or destructor) for the
183318334Speter   specified class.  Argument can be RECORD_TYPE, TYPE_DECL, or
183418334Speter   IDENTIFIER_NODE.  When given a template, return the plain
183518334Speter   unspecialized name.  */
183650397Sobrien
183718334Spetertree
183818334Speterconstructor_name (thing)
183918334Speter     tree thing;
184018334Speter{
184118334Speter  tree t;
184218334Speter  thing = constructor_name_full (thing);
184318334Speter  t = IDENTIFIER_TEMPLATE (thing);
184418334Speter  if (!t)
184518334Speter    return thing;
184650397Sobrien  return t;
184718334Speter}
184818334Speter
184990075Sobrien/* Defer the compilation of the FN until the end of compilation.  */
185050397Sobrien
185118334Spetervoid
185290075Sobriendefer_fn (fn)
185390075Sobrien     tree fn;
185418334Speter{
185590075Sobrien  if (DECL_DEFERRED_FN (fn))
185618334Speter    return;
185790075Sobrien  DECL_DEFERRED_FN (fn) = 1;
185890075Sobrien  if (!deferred_fns)
185990075Sobrien    VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
186018334Speter
186190075Sobrien  VARRAY_PUSH_TREE (deferred_fns, fn);
186218334Speter}
186318334Speter
186450397Sobrien/* Hunts through the global anonymous union ANON_DECL, building
186550397Sobrien   appropriate VAR_DECLs.  Stores cleanups on the list of ELEMS, and
186650397Sobrien   returns a VAR_DECL whose size is the same as the size of the
186790075Sobrien   ANON_DECL, if one is available.
186850397Sobrien
186990075Sobrien   FIXME: we should really handle anonymous unions by binding the names
187090075Sobrien   of the members to COMPONENT_REFs rather than this kludge.  */
187190075Sobrien
187252284Sobrienstatic tree
187350397Sobrienbuild_anon_union_vars (anon_decl, elems, static_p, external_p)
187450397Sobrien     tree anon_decl;
187550397Sobrien     tree* elems;
187650397Sobrien     int static_p;
187750397Sobrien     int external_p;
187818334Speter{
187950397Sobrien  tree type = TREE_TYPE (anon_decl);
188050397Sobrien  tree main_decl = NULL_TREE;
188150397Sobrien  tree field;
188250397Sobrien
188390075Sobrien  /* Rather than write the code to handle the non-union case,
188490075Sobrien     just give an error.  */
188590075Sobrien  if (TREE_CODE (type) != UNION_TYPE)
188690075Sobrien    error ("anonymous struct not inside named type");
188790075Sobrien
188850397Sobrien  for (field = TYPE_FIELDS (type);
188950397Sobrien       field != NULL_TREE;
189050397Sobrien       field = TREE_CHAIN (field))
189150397Sobrien    {
189250397Sobrien      tree decl;
189352284Sobrien
189452284Sobrien      if (DECL_ARTIFICIAL (field))
189552284Sobrien	continue;
189650397Sobrien      if (TREE_CODE (field) != FIELD_DECL)
189752284Sobrien	{
189852284Sobrien	  cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members",
189952284Sobrien			 field);
190052284Sobrien	  continue;
190152284Sobrien	}
190250397Sobrien
190350397Sobrien      if (TREE_PRIVATE (field))
190450397Sobrien	cp_pedwarn_at ("private member `%#D' in anonymous union", field);
190550397Sobrien      else if (TREE_PROTECTED (field))
190650397Sobrien	cp_pedwarn_at ("protected member `%#D' in anonymous union", field);
190750397Sobrien
190850397Sobrien      if (DECL_NAME (field) == NULL_TREE
190990075Sobrien	  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
191050397Sobrien	{
191150397Sobrien	  decl = build_anon_union_vars (field, elems, static_p, external_p);
191250397Sobrien	  if (!decl)
191350397Sobrien	    continue;
191450397Sobrien	}
191552284Sobrien      else if (DECL_NAME (field) == NULL_TREE)
191652284Sobrien	continue;
191750397Sobrien      else
191850397Sobrien	{
191950397Sobrien	  decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
192050397Sobrien	  /* tell `pushdecl' that this is not tentative.  */
192150397Sobrien	  DECL_INITIAL (decl) = error_mark_node;
192250397Sobrien	  TREE_PUBLIC (decl) = 0;
192350397Sobrien	  TREE_STATIC (decl) = static_p;
192450397Sobrien	  DECL_EXTERNAL (decl) = external_p;
192550397Sobrien	  decl = pushdecl (decl);
192650397Sobrien	  DECL_INITIAL (decl) = NULL_TREE;
192750397Sobrien	}
192850397Sobrien
192990075Sobrien      /* Only write out one anon union element--choose the largest
193090075Sobrien	 one.  We used to try to find one the same size as the union,
193190075Sobrien	 but that fails if the ABI forces us to align the union more
193290075Sobrien	 strictly.  */
193350397Sobrien      if (main_decl == NULL_TREE
193490075Sobrien	  || tree_int_cst_lt (DECL_SIZE (main_decl), DECL_SIZE (decl)))
193590075Sobrien	{
193690075Sobrien	  if (main_decl)
193790075Sobrien	    TREE_ASM_WRITTEN (main_decl) = 1;
193890075Sobrien	  main_decl = decl;
193990075Sobrien	}
194050397Sobrien      else
194150397Sobrien	/* ??? This causes there to be no debug info written out
194250397Sobrien	   about this decl.  */
194350397Sobrien	TREE_ASM_WRITTEN (decl) = 1;
194450397Sobrien
194550397Sobrien      if (DECL_NAME (field) == NULL_TREE
194690075Sobrien	  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
194750397Sobrien	/* The remainder of the processing was already done in the
194850397Sobrien	   recursive call.  */
194950397Sobrien	continue;
195050397Sobrien
195150397Sobrien      /* If there's a cleanup to do, it belongs in the
195250397Sobrien	 TREE_PURPOSE of the following TREE_LIST.  */
195390075Sobrien      *elems = tree_cons (NULL_TREE, decl, *elems);
195450397Sobrien      TREE_TYPE (*elems) = type;
195550397Sobrien    }
195650397Sobrien
195750397Sobrien  return main_decl;
195818334Speter}
195918334Speter
196090075Sobrien/* Finish off the processing of a UNION_TYPE structure.  If the union is an
196190075Sobrien   anonymous union, then all members must be laid out together.  PUBLIC_P
196290075Sobrien   is nonzero if this union is not declared static.  */
196350397Sobrien
196418334Spetervoid
196518334Speterfinish_anon_union (anon_union_decl)
196618334Speter     tree anon_union_decl;
196718334Speter{
196818334Speter  tree type = TREE_TYPE (anon_union_decl);
196950397Sobrien  tree main_decl;
197018334Speter  int public_p = TREE_PUBLIC (anon_union_decl);
197118334Speter  int static_p = TREE_STATIC (anon_union_decl);
197218334Speter  int external_p = DECL_EXTERNAL (anon_union_decl);
197318334Speter
197490075Sobrien  /* The VAR_DECL's context is the same as the TYPE's context. */
197590075Sobrien  DECL_CONTEXT (anon_union_decl) = DECL_CONTEXT (TYPE_NAME (type));
197690075Sobrien
197750397Sobrien  if (TYPE_FIELDS (type) == NULL_TREE)
197818334Speter    return;
197918334Speter
198018334Speter  if (public_p)
198118334Speter    {
198290075Sobrien      error ("namespace-scope anonymous aggregates must be static");
198318334Speter      return;
198418334Speter    }
198518334Speter
198690075Sobrien  main_decl = build_anon_union_vars (anon_union_decl,
198790075Sobrien				     &DECL_ANON_UNION_ELEMS (anon_union_decl),
198850397Sobrien				     static_p, external_p);
198918334Speter
199052284Sobrien  if (main_decl == NULL_TREE)
199152284Sobrien    {
199290075Sobrien      warning ("anonymous aggregate with no members");
199352284Sobrien      return;
199452284Sobrien    }
199552284Sobrien
199618334Speter  if (static_p)
199718334Speter    {
199890075Sobrien      make_decl_rtl (main_decl, 0);
199990075Sobrien      COPY_DECL_RTL (main_decl, anon_union_decl);
200090075Sobrien      expand_anon_union_decl (anon_union_decl,
200190075Sobrien			      NULL_TREE,
200290075Sobrien			      DECL_ANON_UNION_ELEMS (anon_union_decl));
200318334Speter    }
200490075Sobrien  else
200590075Sobrien    add_decl_stmt (anon_union_decl);
200618334Speter}
200718334Speter
200818334Speter/* Finish processing a builtin type TYPE.  It's name is NAME,
200918334Speter   its fields are in the array FIELDS.  LEN is the number of elements
201018334Speter   in FIELDS minus one, or put another way, it is the maximum subscript
201118334Speter   used in FIELDS.
201218334Speter
201318334Speter   It is given the same alignment as ALIGN_TYPE.  */
201450397Sobrien
201518334Spetervoid
201618334Speterfinish_builtin_type (type, name, fields, len, align_type)
201718334Speter     tree type;
201852284Sobrien     const char *name;
201918334Speter     tree fields[];
202018334Speter     int len;
202118334Speter     tree align_type;
202218334Speter{
202318334Speter  register int i;
202418334Speter
202518334Speter  TYPE_FIELDS (type) = fields[0];
202618334Speter  for (i = 0; i < len; i++)
202718334Speter    {
202818334Speter      layout_type (TREE_TYPE (fields[i]));
202918334Speter      DECL_FIELD_CONTEXT (fields[i]) = type;
203018334Speter      TREE_CHAIN (fields[i]) = fields[i+1];
203118334Speter    }
203218334Speter  DECL_FIELD_CONTEXT (fields[i]) = type;
203318334Speter  TYPE_ALIGN (type) = TYPE_ALIGN (align_type);
203490075Sobrien  TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (align_type);
203518334Speter  layout_type (type);
203618334Speter#if 0 /* not yet, should get fixed properly later */
203718334Speter  TYPE_NAME (type) = make_type_decl (get_identifier (name), type);
203818334Speter#else
203918334Speter  TYPE_NAME (type) = build_decl (TYPE_DECL, get_identifier (name), type);
204018334Speter#endif
204150397Sobrien  TYPE_STUB_DECL (type) = TYPE_NAME (type);
204218334Speter  layout_decl (TYPE_NAME (type), 0);
204318334Speter}
204418334Speter
204518334Speter/* Auxiliary functions to make type signatures for
204618334Speter   `operator new' and `operator delete' correspond to
204718334Speter   what compiler will be expecting.  */
204818334Speter
204918334Spetertree
205018334Spetercoerce_new_type (type)
205118334Speter     tree type;
205218334Speter{
205390075Sobrien  int e = 0;
205490075Sobrien  tree args = TYPE_ARG_TYPES (type);
205518334Speter
205690075Sobrien  my_friendly_assert (TREE_CODE (type) == FUNCTION_TYPE, 20001107);
205790075Sobrien
205890075Sobrien  if (!same_type_p (TREE_TYPE (type), ptr_type_node))
205990075Sobrien    e = 1, error ("`operator new' must return type `%T'", ptr_type_node);
206018334Speter
206190075Sobrien  if (!args || args == void_list_node
206290075Sobrien      || !same_type_p (TREE_VALUE (args), c_size_type_node))
206390075Sobrien    {
206490075Sobrien      e = 2;
206590075Sobrien      if (args && args != void_list_node)
206690075Sobrien        args = TREE_CHAIN (args);
206790075Sobrien      pedwarn ("`operator new' takes type `size_t' (`%T') as first parameter", c_size_type_node);
206890075Sobrien    }
206990075Sobrien  switch (e)
207090075Sobrien  {
207190075Sobrien    case 2:
207290075Sobrien      args = tree_cons (NULL_TREE, c_size_type_node, args);
207390075Sobrien      /* FALLTHROUGH */
207490075Sobrien    case 1:
207590075Sobrien      type = build_exception_variant
207690075Sobrien              (build_function_type (ptr_type_node, args),
207790075Sobrien               TYPE_RAISES_EXCEPTIONS (type));
207890075Sobrien      /* FALLTHROUGH */
207990075Sobrien    default:;
208090075Sobrien  }
208118334Speter  return type;
208218334Speter}
208318334Speter
208418334Spetertree
208518334Spetercoerce_delete_type (type)
208618334Speter     tree type;
208718334Speter{
208890075Sobrien  int e = 0;
208990075Sobrien  tree args = TYPE_ARG_TYPES (type);
209090075Sobrien
209190075Sobrien  my_friendly_assert (TREE_CODE (type) == FUNCTION_TYPE, 20001107);
209218334Speter
209390075Sobrien  if (!same_type_p (TREE_TYPE (type), void_type_node))
209490075Sobrien    e = 1, error ("`operator delete' must return type `%T'", void_type_node);
209550397Sobrien
209690075Sobrien  if (!args || args == void_list_node
209790075Sobrien      || !same_type_p (TREE_VALUE (args), ptr_type_node))
209818334Speter    {
209990075Sobrien      e = 2;
210090075Sobrien      if (args && args != void_list_node)
210190075Sobrien        args = TREE_CHAIN (args);
210290075Sobrien      error ("`operator delete' takes type `%T' as first parameter", ptr_type_node);
210318334Speter    }
210490075Sobrien  switch (e)
210590075Sobrien  {
210690075Sobrien    case 2:
210790075Sobrien      args = tree_cons (NULL_TREE, ptr_type_node, args);
210890075Sobrien      /* FALLTHROUGH */
210990075Sobrien    case 1:
211090075Sobrien      type = build_exception_variant
211190075Sobrien              (build_function_type (void_type_node, args),
211290075Sobrien               TYPE_RAISES_EXCEPTIONS (type));
211390075Sobrien      /* FALLTHROUGH */
211490075Sobrien    default:;
211590075Sobrien  }
211650397Sobrien
211718334Speter  return type;
211818334Speter}
211918334Speter
212018334Speterstatic void
212118334Spetermark_vtable_entries (decl)
212218334Speter     tree decl;
212318334Speter{
212418334Speter  tree entries = CONSTRUCTOR_ELTS (DECL_INITIAL (decl));
212518334Speter
212652284Sobrien  for (; entries; entries = TREE_CHAIN (entries))
212750397Sobrien    {
212890075Sobrien      tree fnaddr = TREE_VALUE (entries);
212952284Sobrien      tree fn;
213090075Sobrien
213190075Sobrien      if (TREE_CODE (fnaddr) != ADDR_EXPR
213290075Sobrien	  && TREE_CODE (fnaddr) != FDESC_EXPR)
213390075Sobrien	/* This entry is an offset: a virtual base class offset, a
213490075Sobrien	   virtual call offset, an RTTI offset, etc.  */
213552284Sobrien	continue;
213652284Sobrien
213752284Sobrien      fn = TREE_OPERAND (fnaddr, 0);
213818334Speter      TREE_ADDRESSABLE (fn) = 1;
213990075Sobrien      /* When we don't have vcall offsets, we output thunks whenever
214090075Sobrien	 we output the vtables that contain them.  With vcall offsets,
214190075Sobrien	 we know all the thunks we'll need when we emit a virtual
214290075Sobrien	 function, so we emit the thunks there instead.  */
214390075Sobrien      if (DECL_THUNK_P (fn))
214490075Sobrien	use_thunk (fn, /*emit_p=*/0);
214550397Sobrien      mark_used (fn);
214618334Speter    }
214718334Speter}
214818334Speter
214950397Sobrien/* Set DECL up to have the closest approximation of "initialized common"
215050397Sobrien   linkage available.  */
215150397Sobrien
215250397Sobrienvoid
215350397Sobriencomdat_linkage (decl)
215450397Sobrien     tree decl;
215550397Sobrien{
215650397Sobrien  if (flag_weak)
215750397Sobrien    make_decl_one_only (decl);
215890075Sobrien  else if (TREE_CODE (decl) == FUNCTION_DECL
215990075Sobrien	   || (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)))
216090075Sobrien    /* We can just emit function and compiler-generated variables
216190075Sobrien       statically; having multiple copies is (for the most part) only
216290075Sobrien       a waste of space.
216390075Sobrien
216490075Sobrien       There are two correctness issues, however: the address of a
216590075Sobrien       template instantiation with external linkage should be the
216690075Sobrien       same, independent of what translation unit asks for the
216790075Sobrien       address, and this will not hold when we emit multiple copies of
216890075Sobrien       the function.  However, there's little else we can do.
216990075Sobrien
217090075Sobrien       Also, by default, the typeinfo implementation assumes that
217190075Sobrien       there will be only one copy of the string used as the name for
217290075Sobrien       each type.  Therefore, if weak symbols are unavailable, the
217390075Sobrien       run-time library should perform a more conservative check; it
217490075Sobrien       should perform a string comparison, rather than an address
217590075Sobrien       comparison.  */
217652284Sobrien    TREE_PUBLIC (decl) = 0;
217750397Sobrien  else
217852284Sobrien    {
217952284Sobrien      /* Static data member template instantiations, however, cannot
218052284Sobrien	 have multiple copies.  */
218152284Sobrien      if (DECL_INITIAL (decl) == 0
218252284Sobrien	  || DECL_INITIAL (decl) == error_mark_node)
218352284Sobrien	DECL_COMMON (decl) = 1;
218452284Sobrien      else if (EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
218552284Sobrien	{
218652284Sobrien	  DECL_COMMON (decl) = 1;
218752284Sobrien	  DECL_INITIAL (decl) = error_mark_node;
218852284Sobrien	}
218952284Sobrien      else
219052284Sobrien	{
219152284Sobrien	  /* We can't do anything useful; leave vars for explicit
219252284Sobrien	     instantiation.  */
219352284Sobrien	  DECL_EXTERNAL (decl) = 1;
219452284Sobrien	  DECL_NOT_REALLY_EXTERN (decl) = 0;
219552284Sobrien	}
219652284Sobrien    }
219750397Sobrien
219850397Sobrien  if (DECL_LANG_SPECIFIC (decl))
219950397Sobrien    DECL_COMDAT (decl) = 1;
220050397Sobrien}
220150397Sobrien
220250397Sobrien/* For win32 we also want to put explicit instantiations in
220350397Sobrien   linkonce sections, so that they will be merged with implicit
220450397Sobrien   instantiations; otherwise we get duplicate symbol errors.  */
220550397Sobrien
220650397Sobrienvoid
220750397Sobrienmaybe_make_one_only (decl)
220850397Sobrien     tree decl;
220950397Sobrien{
221056385Sobrien  /* We used to say that this was not necessary on targets that support weak
221156385Sobrien     symbols, because the implicit instantiations will defer to the explicit
221256385Sobrien     one.  However, that's not actually the case in SVR4; a strong definition
221356385Sobrien     after a weak one is an error.  Also, not making explicit
221456385Sobrien     instantiations one_only means that we can end up with two copies of
221556385Sobrien     some template instantiations. */
221690075Sobrien  if (! flag_weak)
221750397Sobrien    return;
221850397Sobrien
221950397Sobrien  /* We can't set DECL_COMDAT on functions, or finish_file will think
222052284Sobrien     we can get away with not emitting them if they aren't used.  We need
222152284Sobrien     to for variables so that cp_finish_decl will update their linkage,
222252284Sobrien     because their DECL_INITIAL may not have been set properly yet.  */
222350397Sobrien
222452284Sobrien  make_decl_one_only (decl);
222552284Sobrien
222652284Sobrien  if (TREE_CODE (decl) == VAR_DECL && DECL_LANG_SPECIFIC (decl))
222752284Sobrien    DECL_COMDAT (decl) = 1;
222850397Sobrien}
222950397Sobrien
223090075Sobrien/* Returns the virtual function with which the vtable for TYPE is
223190075Sobrien   emitted, or NULL_TREE if that heuristic is not applicable to TYPE.  */
223290075Sobrien
223390075Sobrienstatic tree
223490075Sobrienkey_method (type)
223590075Sobrien     tree type;
223690075Sobrien{
223790075Sobrien  tree method;
223890075Sobrien
223990075Sobrien  if (TYPE_FOR_JAVA (type)
224090075Sobrien      || CLASSTYPE_TEMPLATE_INSTANTIATION (type)
224190075Sobrien      || CLASSTYPE_INTERFACE_KNOWN (type))
224290075Sobrien    return NULL_TREE;
224390075Sobrien
224490075Sobrien  for (method = TYPE_METHODS (type); method != NULL_TREE;
224590075Sobrien       method = TREE_CHAIN (method))
224690075Sobrien    if (DECL_VINDEX (method) != NULL_TREE
224790075Sobrien	&& ! DECL_DECLARED_INLINE_P (method)
224890075Sobrien	&& (! DECL_PURE_VIRTUAL_P (method)
224990075Sobrien#if 0
225090075Sobrien	    /* This would be nice, but we didn't think of it in time.  */
225190075Sobrien	    || DECL_DESTRUCTOR_P (method)
225290075Sobrien#endif
225390075Sobrien	    ))
225490075Sobrien      return method;
225590075Sobrien
225690075Sobrien  return NULL_TREE;
225790075Sobrien}
225890075Sobrien
225918334Speter/* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL,
226018334Speter   based on TYPE and other static flags.
226118334Speter
226218334Speter   Note that anything public is tagged TREE_PUBLIC, whether
226318334Speter   it's public in this file or in another one.  */
226418334Speter
226518334Spetervoid
226618334Speterimport_export_vtable (decl, type, final)
226718334Speter     tree decl, type;
226818334Speter     int final;
226918334Speter{
227018334Speter  if (DECL_INTERFACE_KNOWN (decl))
227118334Speter    return;
227218334Speter
227352284Sobrien  if (TYPE_FOR_JAVA (type))
227418334Speter    {
227518334Speter      TREE_PUBLIC (decl) = 1;
227652284Sobrien      DECL_EXTERNAL (decl) = 1;
227718334Speter      DECL_INTERFACE_KNOWN (decl) = 1;
227818334Speter    }
227918334Speter  else if (CLASSTYPE_INTERFACE_KNOWN (type))
228018334Speter    {
228118334Speter      TREE_PUBLIC (decl) = 1;
228290075Sobrien      DECL_EXTERNAL (decl) = CLASSTYPE_INTERFACE_ONLY (type);
228318334Speter      DECL_INTERFACE_KNOWN (decl) = 1;
228418334Speter    }
228518334Speter  else
228618334Speter    {
228718334Speter      /* We can only wait to decide if we have real non-inline virtual
228818334Speter	 functions in our class, or if we come from a template.  */
228918334Speter
229090075Sobrien      int found = (CLASSTYPE_TEMPLATE_INSTANTIATION (type)
229190075Sobrien		   || key_method (type));
229218334Speter
229318334Speter      if (final || ! found)
229418334Speter	{
229550397Sobrien	  comdat_linkage (decl);
229618334Speter	  DECL_EXTERNAL (decl) = 0;
229718334Speter	}
229818334Speter      else
229918334Speter	{
230018334Speter	  TREE_PUBLIC (decl) = 1;
230118334Speter	  DECL_EXTERNAL (decl) = 1;
230218334Speter	}
230318334Speter    }
230418334Speter}
230518334Speter
230650397Sobrien/* Determine whether or not we want to specifically import or export CTYPE,
230750397Sobrien   using various heuristics.  */
230850397Sobrien
230990075Sobrienstatic void
231050397Sobrienimport_export_class (ctype)
231150397Sobrien     tree ctype;
231218334Speter{
231350397Sobrien  /* -1 for imported, 1 for exported.  */
231450397Sobrien  int import_export = 0;
231518334Speter
231690075Sobrien  /* It only makes sense to call this function at EOF.  The reason is
231790075Sobrien     that this function looks at whether or not the first non-inline
231890075Sobrien     non-abstract virtual member function has been defined in this
231990075Sobrien     translation unit.  But, we can't possibly know that until we've
232090075Sobrien     seen the entire translation unit.  */
232190075Sobrien  my_friendly_assert (at_eof, 20000226);
232290075Sobrien
232350397Sobrien  if (CLASSTYPE_INTERFACE_KNOWN (ctype))
232450397Sobrien    return;
232550397Sobrien
232652284Sobrien  /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma interface,
232752284Sobrien     we will have CLASSTYPE_INTERFACE_ONLY set but not
232852284Sobrien     CLASSTYPE_INTERFACE_KNOWN.  In that case, we don't want to use this
232952284Sobrien     heuristic because someone will supply a #pragma implementation
233052284Sobrien     elsewhere, and deducing it here would produce a conflict.  */
233152284Sobrien  if (CLASSTYPE_INTERFACE_ONLY (ctype))
233252284Sobrien    return;
233352284Sobrien
233450397Sobrien  if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype)))
233550397Sobrien    import_export = -1;
233652284Sobrien  else if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype)))
233752284Sobrien    import_export = 1;
233850397Sobrien
233950397Sobrien  /* If we got -fno-implicit-templates, we import template classes that
234050397Sobrien     weren't explicitly instantiated.  */
234150397Sobrien  if (import_export == 0
234250397Sobrien      && CLASSTYPE_IMPLICIT_INSTANTIATION (ctype)
234350397Sobrien      && ! flag_implicit_templates)
234450397Sobrien    import_export = -1;
234550397Sobrien
234650397Sobrien  /* Base our import/export status on that of the first non-inline,
234790075Sobrien     non-pure virtual function, if any.  */
234850397Sobrien  if (import_export == 0
234990075Sobrien      && TYPE_POLYMORPHIC_P (ctype))
235018334Speter    {
235190075Sobrien      tree method = key_method (ctype);
235290075Sobrien      if (method)
235390075Sobrien	import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1);
235418334Speter    }
235552284Sobrien
235652284Sobrien#ifdef MULTIPLE_SYMBOL_SPACES
235752284Sobrien  if (import_export == -1)
235852284Sobrien    import_export = 0;
235950397Sobrien#endif
236018334Speter
236150397Sobrien  if (import_export)
236218334Speter    {
236350397Sobrien      SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
236450397Sobrien      CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0);
236518334Speter    }
236618334Speter}
236718334Speter
236852284Sobrien/* We need to describe to the assembler the relationship between
236952284Sobrien   a vtable and the vtable of the parent class.  */
237052284Sobrien
237152284Sobrienstatic void
237252284Sobrienoutput_vtable_inherit (vars)
237352284Sobrien     tree vars;
237452284Sobrien{
237552284Sobrien  tree parent;
237690075Sobrien  rtx child_rtx, parent_rtx;
237752284Sobrien
237890075Sobrien  child_rtx = XEXP (DECL_RTL (vars), 0);	  /* strip the mem ref  */
237952284Sobrien
238052284Sobrien  parent = binfo_for_vtable (vars);
238152284Sobrien
238252284Sobrien  if (parent == TYPE_BINFO (DECL_CONTEXT (vars)))
238390075Sobrien    parent_rtx = const0_rtx;
238452284Sobrien  else if (parent)
238552284Sobrien    {
238690075Sobrien      parent = get_vtbl_decl_for_binfo (TYPE_BINFO (BINFO_TYPE (parent)));
238790075Sobrien      parent_rtx = XEXP (DECL_RTL (parent), 0);  /* strip the mem ref  */
238852284Sobrien    }
238952284Sobrien  else
239090075Sobrien    abort ();
239152284Sobrien
239290075Sobrien  assemble_vtable_inherit (child_rtx, parent_rtx);
239352284Sobrien}
239452284Sobrien
239550397Sobrienstatic int
239652284Sobrienfinish_vtable_vardecl (t, data)
239752284Sobrien     tree *t;
239852284Sobrien     void *data ATTRIBUTE_UNUSED;
239918334Speter{
240052284Sobrien  tree vars = *t;
240150397Sobrien  tree ctype = DECL_CONTEXT (vars);
240250397Sobrien  import_export_class (ctype);
240350397Sobrien  import_export_vtable (vars, ctype, 1);
240450397Sobrien
240552284Sobrien  if (! DECL_EXTERNAL (vars)
240690075Sobrien      && DECL_NEEDED_P (vars)
240750397Sobrien      && ! TREE_ASM_WRITTEN (vars))
240818334Speter    {
240990075Sobrien      if (TREE_TYPE (vars) == void_type_node)
241090075Sobrien        /* It is a dummy vtable made by get_vtable_decl. Ignore it.  */
241190075Sobrien        return 0;
241290075Sobrien
241318334Speter      /* Write it out.  */
241418334Speter      mark_vtable_entries (vars);
241518334Speter      if (TREE_TYPE (DECL_INITIAL (vars)) == 0)
241618334Speter	store_init_value (vars, DECL_INITIAL (vars));
241718334Speter
241850397Sobrien      if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG)
241918334Speter	{
242018334Speter	  /* Mark the VAR_DECL node representing the vtable itself as a
242118334Speter	     "gratuitous" one, thereby forcing dwarfout.c to ignore it.
242218334Speter	     It is rather important that such things be ignored because
242318334Speter	     any effort to actually generate DWARF for them will run
242418334Speter	     into trouble when/if we encounter code like:
242518334Speter
242618334Speter		#pragma interface
242718334Speter		struct S { virtual void member (); };
242818334Speter
242918334Speter	      because the artificial declaration of the vtable itself (as
243018334Speter	      manufactured by the g++ front end) will say that the vtable
243118334Speter	      is a static member of `S' but only *after* the debug output
243218334Speter	      for the definition of `S' has already been output.  This causes
243318334Speter	      grief because the DWARF entry for the definition of the vtable
243418334Speter	      will try to refer back to an earlier *declaration* of the
243518334Speter	      vtable as a static member of `S' and there won't be one.
243618334Speter	      We might be able to arrange to have the "vtable static member"
243718334Speter	      attached to the member list for `S' before the debug info for
243818334Speter	      `S' get written (which would solve the problem) but that would
243918334Speter	      require more intrusive changes to the g++ front end.  */
244018334Speter
244118334Speter	  DECL_IGNORED_P (vars) = 1;
244218334Speter	}
244318334Speter
244452284Sobrien      /* Always make vtables weak.  */
244552284Sobrien      if (flag_weak)
244652284Sobrien	comdat_linkage (vars);
244752284Sobrien
244890075Sobrien      rest_of_decl_compilation (vars, NULL, 1, 1);
244952284Sobrien
245052284Sobrien      if (flag_vtable_gc)
245152284Sobrien	output_vtable_inherit (vars);
245252284Sobrien
245390075Sobrien      /* Because we're only doing syntax-checking, we'll never end up
245490075Sobrien	 actually marking the variable as written.  */
245590075Sobrien      if (flag_syntax_only)
245690075Sobrien	TREE_ASM_WRITTEN (vars) = 1;
245790075Sobrien
245890075Sobrien      /* Since we're writing out the vtable here, also write the debug
245990075Sobrien	 info.  */
246090075Sobrien      note_debug_info_needed (ctype);
246190075Sobrien
246250397Sobrien      return 1;
246318334Speter    }
246418334Speter
246590075Sobrien  /* If the references to this class' vtables were optimized away, still
246690075Sobrien     emit the appropriate debugging information.  See dfs_debug_mark.  */
246790075Sobrien  if (DECL_COMDAT (vars)
246890075Sobrien      && CLASSTYPE_DEBUG_REQUESTED (ctype))
246990075Sobrien    note_debug_info_needed (ctype);
247090075Sobrien
247150397Sobrien  return 0;
247218334Speter}
247318334Speter
247450397Sobrienstatic int
247552284Sobrienprune_vtable_vardecl (t, data)
247652284Sobrien     tree *t;
247752284Sobrien     void *data ATTRIBUTE_UNUSED;
247818334Speter{
247952284Sobrien  *t = TREE_CHAIN (*t);
248050397Sobrien  return 1;
248118334Speter}
248218334Speter
248318334Speter/* Determines the proper settings of TREE_PUBLIC and DECL_EXTERNAL for an
248450397Sobrien   inline function or template instantiation at end-of-file.  */
248518334Speter
248618334Spetervoid
248750397Sobrienimport_export_decl (decl)
248818334Speter     tree decl;
248918334Speter{
249018334Speter  if (DECL_INTERFACE_KNOWN (decl))
249118334Speter    return;
249218334Speter
249352284Sobrien  if (DECL_TEMPLATE_INSTANTIATION (decl)
249452284Sobrien      || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl))
249518334Speter    {
249650397Sobrien      DECL_NOT_REALLY_EXTERN (decl) = 1;
249752284Sobrien      if ((DECL_IMPLICIT_INSTANTIATION (decl)
249852284Sobrien	   || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl))
249952284Sobrien	  && (flag_implicit_templates
250090075Sobrien	      || (flag_implicit_inline_templates
250190075Sobrien		  && DECL_DECLARED_INLINE_P (decl))))
250218334Speter	{
250350397Sobrien	  if (!TREE_PUBLIC (decl))
250450397Sobrien	    /* Templates are allowed to have internal linkage.  See
250550397Sobrien	       [basic.link].  */
250650397Sobrien	    ;
250752284Sobrien	  else
250850397Sobrien	    comdat_linkage (decl);
250918334Speter	}
251018334Speter      else
251118334Speter	DECL_NOT_REALLY_EXTERN (decl) = 0;
251218334Speter    }
251318334Speter  else if (DECL_FUNCTION_MEMBER_P (decl))
251418334Speter    {
251590075Sobrien      if (!DECL_DECLARED_INLINE_P (decl))
251618334Speter	{
251790075Sobrien	  tree ctype = DECL_CONTEXT (decl);
251890075Sobrien	  import_export_class (ctype);
251990075Sobrien	  if (CLASSTYPE_INTERFACE_KNOWN (ctype))
252090075Sobrien	    {
252190075Sobrien	      DECL_NOT_REALLY_EXTERN (decl)
252290075Sobrien		= ! (CLASSTYPE_INTERFACE_ONLY (ctype)
252390075Sobrien		     || (DECL_DECLARED_INLINE_P (decl)
252490075Sobrien			 && ! flag_implement_inlines
252590075Sobrien			 && !DECL_VINDEX (decl)));
252652284Sobrien
252790075Sobrien	      /* Always make artificials weak.  */
252890075Sobrien	      if (DECL_ARTIFICIAL (decl) && flag_weak)
252990075Sobrien		comdat_linkage (decl);
253090075Sobrien	      else
253190075Sobrien		maybe_make_one_only (decl);
253290075Sobrien	    }
253318334Speter	}
253418334Speter      else
253550397Sobrien	comdat_linkage (decl);
253618334Speter    }
253790075Sobrien  else if (tinfo_decl_p (decl, 0))
253850397Sobrien    {
253950397Sobrien      tree ctype = TREE_TYPE (DECL_NAME (decl));
254050397Sobrien
254150397Sobrien      if (IS_AGGR_TYPE (ctype))
254250397Sobrien	import_export_class (ctype);
254350397Sobrien
254450397Sobrien      if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype)
254590075Sobrien	  && TYPE_POLYMORPHIC_P (ctype)
254690075Sobrien	  /* If -fno-rtti, we're not necessarily emitting this stuff with
254790075Sobrien	     the class, so go ahead and emit it now.  This can happen
254890075Sobrien	     when a class is used in exception handling.  */
254990075Sobrien	  && flag_rtti
255050397Sobrien	  /* If the type is a cv-qualified variant of a type, then we
255150397Sobrien	     must emit the tinfo function in this translation unit
255250397Sobrien	     since it will not be emitted when the vtable for the type
255350397Sobrien	     is output (which is when the unqualified version is
255450397Sobrien	     generated).  */
255552284Sobrien	  && same_type_p (ctype, TYPE_MAIN_VARIANT (ctype)))
255650397Sobrien	{
255750397Sobrien	  DECL_NOT_REALLY_EXTERN (decl)
255850397Sobrien	    = ! (CLASSTYPE_INTERFACE_ONLY (ctype)
255990075Sobrien		 || (DECL_DECLARED_INLINE_P (decl)
256090075Sobrien		     && ! flag_implement_inlines
256152284Sobrien		     && !DECL_VINDEX (decl)));
256250397Sobrien
256352284Sobrien	  /* Always make artificials weak.  */
256452284Sobrien	  if (flag_weak)
256552284Sobrien	    comdat_linkage (decl);
256650397Sobrien	}
256752284Sobrien      else if (TYPE_BUILT_IN (ctype)
256852284Sobrien	       && same_type_p (ctype, TYPE_MAIN_VARIANT (ctype)))
256950397Sobrien	DECL_NOT_REALLY_EXTERN (decl) = 0;
257050397Sobrien      else
257150397Sobrien	comdat_linkage (decl);
257250397Sobrien    }
257318334Speter  else
257450397Sobrien    comdat_linkage (decl);
257518334Speter
257618334Speter  DECL_INTERFACE_KNOWN (decl) = 1;
257718334Speter}
257818334Speter
257950397Sobrientree
258050397Sobrienbuild_cleanup (decl)
258150397Sobrien     tree decl;
258250397Sobrien{
258350397Sobrien  tree temp;
258450397Sobrien  tree type = TREE_TYPE (decl);
258550397Sobrien
258650397Sobrien  if (TREE_CODE (type) == ARRAY_TYPE)
258750397Sobrien    temp = decl;
258850397Sobrien  else
258950397Sobrien    {
259050397Sobrien      mark_addressable (decl);
259150397Sobrien      temp = build1 (ADDR_EXPR, build_pointer_type (type), decl);
259250397Sobrien    }
259350397Sobrien  temp = build_delete (TREE_TYPE (temp), temp,
259490075Sobrien		       sfk_complete_destructor,
259550397Sobrien		       LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
259650397Sobrien  return temp;
259750397Sobrien}
259850397Sobrien
259990075Sobrien/* Returns the initialization guard variable for the variable DECL,
260090075Sobrien   which has static storage duration.  */
260118334Speter
260290075Sobrientree
260390075Sobrienget_guard (decl)
260490075Sobrien     tree decl;
260550397Sobrien{
260690075Sobrien  tree sname;
260790075Sobrien  tree guard;
260890075Sobrien
260990075Sobrien  sname = mangle_guard_variable (decl);
261090075Sobrien  guard = IDENTIFIER_GLOBAL_VALUE (sname);
261190075Sobrien  if (! guard)
261250397Sobrien    {
261390075Sobrien      tree guard_type;
261490075Sobrien
261590075Sobrien      /* We use a type that is big enough to contain a mutex as well
261690075Sobrien	 as an integer counter.  */
261790075Sobrien      guard_type = long_long_integer_type_node;
261890075Sobrien      guard = build_decl (VAR_DECL, sname, guard_type);
261990075Sobrien
262090075Sobrien      /* The guard should have the same linkage as what it guards. */
262190075Sobrien      TREE_PUBLIC (guard) = TREE_PUBLIC (decl);
262290075Sobrien      TREE_STATIC (guard) = TREE_STATIC (decl);
262390075Sobrien      DECL_COMMON (guard) = DECL_COMMON (decl);
262490075Sobrien      DECL_ONE_ONLY (guard) = DECL_ONE_ONLY (decl);
262590075Sobrien      if (TREE_PUBLIC (decl))
262690075Sobrien        DECL_WEAK (guard) = DECL_WEAK (decl);
262790075Sobrien
262890075Sobrien      DECL_ARTIFICIAL (guard) = 1;
262990075Sobrien      TREE_USED (guard) = 1;
263090075Sobrien      pushdecl_top_level (guard);
263190075Sobrien      cp_finish_decl (guard, NULL_TREE, NULL_TREE, 0);
263250397Sobrien    }
263390075Sobrien  return guard;
263450397Sobrien}
263518334Speter
263690075Sobrien/* Return those bits of the GUARD variable that should be set when the
263790075Sobrien   guarded entity is actually initialized.  */
263890075Sobrien
263990075Sobrienstatic tree
264090075Sobrienget_guard_bits (guard)
264190075Sobrien     tree guard;
264290075Sobrien{
264390075Sobrien  /* We only set the first byte of the guard, in order to leave room
264490075Sobrien     for a mutex in the high-order bits.  */
264590075Sobrien  guard = build1 (ADDR_EXPR,
264690075Sobrien		  build_pointer_type (TREE_TYPE (guard)),
264790075Sobrien		  guard);
264890075Sobrien  guard = build1 (NOP_EXPR,
264990075Sobrien		  build_pointer_type (char_type_node),
265090075Sobrien		  guard);
265190075Sobrien  guard = build1 (INDIRECT_REF, char_type_node, guard);
265290075Sobrien
265390075Sobrien  return guard;
265490075Sobrien}
265590075Sobrien
265690075Sobrien/* Return an expression which determines whether or not the GUARD
265790075Sobrien   variable has already been initialized.  */
265890075Sobrien
265990075Sobrientree
266090075Sobrienget_guard_cond (guard)
266190075Sobrien     tree guard;
266290075Sobrien{
266390075Sobrien  tree guard_value;
266490075Sobrien
266590075Sobrien  /* Check to see if the GUARD is zero.  */
266690075Sobrien  guard = get_guard_bits (guard);
266790075Sobrien  guard_value = integer_zero_node;
266890075Sobrien  if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard)))
266990075Sobrien    guard_value = convert (TREE_TYPE (guard), guard_value);
267090075Sobrien  return cp_build_binary_op (EQ_EXPR, guard, guard_value);
267190075Sobrien}
267290075Sobrien
267390075Sobrien/* Return an expression which sets the GUARD variable, indicating that
267490075Sobrien   the variable being guarded has been initialized.  */
267590075Sobrien
267690075Sobrientree
267790075Sobrienset_guard (guard)
267890075Sobrien     tree guard;
267990075Sobrien{
268090075Sobrien  tree guard_init;
268190075Sobrien
268290075Sobrien  /* Set the GUARD to one.  */
268390075Sobrien  guard = get_guard_bits (guard);
268490075Sobrien  guard_init = integer_one_node;
268590075Sobrien  if (!same_type_p (TREE_TYPE (guard_init), TREE_TYPE (guard)))
268690075Sobrien    guard_init = convert (TREE_TYPE (guard), guard_init);
268790075Sobrien  return build_modify_expr (guard, NOP_EXPR, guard_init);
268890075Sobrien}
268990075Sobrien
269050397Sobrien/* Start the process of running a particular set of global constructors
269150397Sobrien   or destructors.  Subroutine of do_[cd]tors.  */
269250397Sobrien
269390075Sobrienstatic tree
269452284Sobrienstart_objects (method_type, initp)
269552284Sobrien     int method_type, initp;
269650397Sobrien{
269750397Sobrien  tree fnname;
269890075Sobrien  tree body;
269952284Sobrien  char type[10];
270050397Sobrien
270150397Sobrien  /* Make ctor or dtor function.  METHOD_TYPE may be 'I' or 'D'.  */
270250397Sobrien
270352284Sobrien  if (initp != DEFAULT_INIT_PRIORITY)
270452284Sobrien    {
270552284Sobrien      char joiner;
270650397Sobrien
270752284Sobrien#ifdef JOINER
270852284Sobrien      joiner = JOINER;
270952284Sobrien#else
271052284Sobrien      joiner = '_';
271152284Sobrien#endif
271252284Sobrien
271352284Sobrien      sprintf (type, "%c%c%.5u", method_type, joiner, initp);
271452284Sobrien    }
271552284Sobrien  else
271652284Sobrien    sprintf (type, "%c", method_type);
271752284Sobrien
271852284Sobrien  fnname = get_file_function_name_long (type);
271952284Sobrien
272050397Sobrien  start_function (void_list_node,
272150397Sobrien		  make_call_declarator (fnname, void_list_node, NULL_TREE,
272250397Sobrien					NULL_TREE),
272390075Sobrien		  NULL_TREE, SF_DEFAULT);
272450397Sobrien
272550397Sobrien  /* It can be a static function as long as collect2 does not have
272650397Sobrien     to scan the object file to find its ctor/dtor routine.  */
272790075Sobrien  TREE_PUBLIC (current_function_decl) = ! targetm.have_ctors_dtors;
272850397Sobrien
272990075Sobrien  /* Mark this declaration as used to avoid spurious warnings.  */
273090075Sobrien  TREE_USED (current_function_decl) = 1;
273152284Sobrien
273290075Sobrien  /* Mark this function as a global constructor or destructor.  */
273390075Sobrien  if (method_type == 'I')
273490075Sobrien    DECL_GLOBAL_CTOR_P (current_function_decl) = 1;
273590075Sobrien  else
273690075Sobrien    DECL_GLOBAL_DTOR_P (current_function_decl) = 1;
273790075Sobrien  GLOBAL_INIT_PRIORITY (current_function_decl) = initp;
273890075Sobrien
273990075Sobrien  body = begin_compound_stmt (/*has_no_scope=*/0);
274090075Sobrien
274152284Sobrien  /* We cannot allow these functions to be elided, even if they do not
274252284Sobrien     have external linkage.  And, there's no point in deferring
274352284Sobrien     copmilation of thes functions; they're all going to have to be
274452284Sobrien     out anyhow.  */
274552284Sobrien  current_function_cannot_inline
274652284Sobrien    = "static constructors and destructors cannot be inlined";
274790075Sobrien
274890075Sobrien  return body;
274950397Sobrien}
275050397Sobrien
275150397Sobrien/* Finish the process of running a particular set of global constructors
275250397Sobrien   or destructors.  Subroutine of do_[cd]tors.  */
275350397Sobrien
275450397Sobrienstatic void
275590075Sobrienfinish_objects (method_type, initp, body)
275652284Sobrien     int method_type, initp;
275790075Sobrien     tree body;
275850397Sobrien{
275990075Sobrien  tree fn;
276050397Sobrien
276190075Sobrien  /* Finish up.  */
276290075Sobrien  finish_compound_stmt (/*has_no_scope=*/0, body);
276390075Sobrien  fn = finish_function (0);
276490075Sobrien  expand_body (fn);
276550397Sobrien
276690075Sobrien  /* When only doing semantic analysis, and no RTL generation, we
276790075Sobrien     can't call functions that directly emit assembly code; there is
276890075Sobrien     no assembly file in which to put the code.  */
276990075Sobrien  if (flag_syntax_only)
277090075Sobrien    return;
277190075Sobrien
277290075Sobrien  if (targetm.have_ctors_dtors)
277352284Sobrien    {
277490075Sobrien      rtx fnsym = XEXP (DECL_RTL (fn), 0);
277552284Sobrien      if (method_type == 'I')
277690075Sobrien	(* targetm.asm_out.constructor) (fnsym, initp);
277752284Sobrien      else
277890075Sobrien	(* targetm.asm_out.destructor) (fnsym, initp);
277952284Sobrien    }
278050397Sobrien}
278150397Sobrien
278252284Sobrien/* The names of the parameters to the function created to handle
278352284Sobrien   initializations and destructions for objects with static storage
278452284Sobrien   duration.  */
278552284Sobrien#define INITIALIZE_P_IDENTIFIER "__initialize_p"
278652284Sobrien#define PRIORITY_IDENTIFIER "__priority"
278750397Sobrien
278852284Sobrien/* The name of the function we create to handle initializations and
278952284Sobrien   destructions for objects with static storage duration.  */
279052284Sobrien#define SSDF_IDENTIFIER "__static_initialization_and_destruction"
279152284Sobrien
279252284Sobrien/* The declaration for the __INITIALIZE_P argument.  */
279352284Sobrienstatic tree initialize_p_decl;
279452284Sobrien
279552284Sobrien/* The declaration for the __PRIORITY argument.  */
279652284Sobrienstatic tree priority_decl;
279752284Sobrien
279852284Sobrien/* The declaration for the static storage duration function.  */
279952284Sobrienstatic tree ssdf_decl;
280052284Sobrien
280152284Sobrien/* All the static storage duration functions created in this
280252284Sobrien   translation unit.  */
280352284Sobrienstatic varray_type ssdf_decls;
280452284Sobrien
280552284Sobrien/* A map from priority levels to information about that priority
280652284Sobrien   level.  There may be many such levels, so efficient lookup is
280752284Sobrien   important.  */
280852284Sobrienstatic splay_tree priority_info_map;
280952284Sobrien
281052284Sobrien/* Begins the generation of the function that will handle all
281152284Sobrien   initialization and destruction of objects with static storage
281252284Sobrien   duration.  The function generated takes two parameters of type
281352284Sobrien   `int': __INITIALIZE_P and __PRIORITY.  If __INITIALIZE_P is
281452284Sobrien   non-zero, it performs initializations.  Otherwise, it performs
281552284Sobrien   destructions.  It only performs those initializations or
281652284Sobrien   destructions with the indicated __PRIORITY.  The generated function
281752284Sobrien   returns no value.
281852284Sobrien
281952284Sobrien   It is assumed that this function will only be called once per
282052284Sobrien   translation unit.  */
282152284Sobrien
282290075Sobrienstatic tree
282352284Sobrienstart_static_storage_duration_function ()
282450397Sobrien{
282552284Sobrien  static unsigned ssdf_number;
282650397Sobrien
282752284Sobrien  tree parm_types;
282852284Sobrien  tree type;
282990075Sobrien  tree body;
283052284Sobrien  char id[sizeof (SSDF_IDENTIFIER) + 1 /* '\0' */ + 32];
283152284Sobrien
283252284Sobrien  /* Create the identifier for this function.  It will be of the form
283352284Sobrien     SSDF_IDENTIFIER_<number>.  */
283452284Sobrien  sprintf (id, "%s_%u", SSDF_IDENTIFIER, ssdf_number++);
283552284Sobrien  if (ssdf_number == 0)
283650397Sobrien    {
283752284Sobrien      /* Overflow occurred.  That means there are at least 4 billion
283852284Sobrien	 initialization functions.  */
283952284Sobrien      sorry ("too many initialization functions required");
284090075Sobrien      abort ();
284152284Sobrien    }
284250397Sobrien
284352284Sobrien  /* Create the parameters.  */
284452284Sobrien  parm_types = void_list_node;
284590075Sobrien  parm_types = tree_cons (NULL_TREE, integer_type_node, parm_types);
284690075Sobrien  parm_types = tree_cons (NULL_TREE, integer_type_node, parm_types);
284752284Sobrien  type = build_function_type (void_type_node, parm_types);
284850397Sobrien
284952284Sobrien  /* Create the FUNCTION_DECL itself.  */
285052284Sobrien  ssdf_decl = build_lang_decl (FUNCTION_DECL,
285152284Sobrien			       get_identifier (id),
285252284Sobrien			       type);
285352284Sobrien  TREE_PUBLIC (ssdf_decl) = 0;
285452284Sobrien  DECL_ARTIFICIAL (ssdf_decl) = 1;
285550397Sobrien
285652284Sobrien  /* Put this function in the list of functions to be called from the
285752284Sobrien     static constructors and destructors.  */
285852284Sobrien  if (!ssdf_decls)
285952284Sobrien    {
286052284Sobrien      VARRAY_TREE_INIT (ssdf_decls, 32, "ssdf_decls");
286150397Sobrien
286252284Sobrien      /* Take this opportunity to initialize the map from priority
286352284Sobrien	 numbers to information about that priority level. */
286452284Sobrien      priority_info_map = splay_tree_new (splay_tree_compare_ints,
286552284Sobrien					  /*delete_key_fn=*/0,
286652284Sobrien					  /*delete_value_fn=*/
286752284Sobrien					  (splay_tree_delete_value_fn) &free);
286850397Sobrien
286952284Sobrien      /* We always need to generate functions for the
287052284Sobrien	 DEFAULT_INIT_PRIORITY so enter it now.  That way when we walk
287152284Sobrien	 priorities later, we'll be sure to find the
287252284Sobrien	 DEFAULT_INIT_PRIORITY.  */
287352284Sobrien      get_priority_info (DEFAULT_INIT_PRIORITY);
287450397Sobrien    }
287550397Sobrien
287690075Sobrien  VARRAY_PUSH_TREE (ssdf_decls, ssdf_decl);
287752284Sobrien
287852284Sobrien  /* Create the argument list.  */
287952284Sobrien  initialize_p_decl = build_decl (PARM_DECL,
288052284Sobrien				  get_identifier (INITIALIZE_P_IDENTIFIER),
288152284Sobrien				  integer_type_node);
288252284Sobrien  DECL_CONTEXT (initialize_p_decl) = ssdf_decl;
288352284Sobrien  DECL_ARG_TYPE (initialize_p_decl) = integer_type_node;
288452284Sobrien  TREE_USED (initialize_p_decl) = 1;
288552284Sobrien  priority_decl = build_decl (PARM_DECL, get_identifier (PRIORITY_IDENTIFIER),
288652284Sobrien			      integer_type_node);
288752284Sobrien  DECL_CONTEXT (priority_decl) = ssdf_decl;
288852284Sobrien  DECL_ARG_TYPE (priority_decl) = integer_type_node;
288952284Sobrien  TREE_USED (priority_decl) = 1;
289052284Sobrien
289152284Sobrien  TREE_CHAIN (initialize_p_decl) = priority_decl;
289252284Sobrien  DECL_ARGUMENTS (ssdf_decl) = initialize_p_decl;
289352284Sobrien
289490075Sobrien  /* Put the function in the global scope.  */
289590075Sobrien  pushdecl (ssdf_decl);
289690075Sobrien
289752284Sobrien  /* Start the function itself.  This is equivalent to declarating the
289852284Sobrien     function as:
289952284Sobrien
290052284Sobrien       static void __ssdf (int __initialize_p, init __priority_p);
290152284Sobrien
290252284Sobrien     It is static because we only need to call this function from the
290352284Sobrien     various constructor and destructor functions for this module.  */
290452284Sobrien  start_function (/*specs=*/NULL_TREE,
290552284Sobrien		  ssdf_decl,
290652284Sobrien		  /*attrs=*/NULL_TREE,
290790075Sobrien		  SF_PRE_PARSED);
290852284Sobrien
290952284Sobrien  /* Set up the scope of the outermost block in the function.  */
291090075Sobrien  body = begin_compound_stmt (/*has_no_scope=*/0);
291152284Sobrien
291252284Sobrien  /* This function must not be deferred because we are depending on
291352284Sobrien     its compilation to tell us what is TREE_SYMBOL_REFERENCED.  */
291452284Sobrien  current_function_cannot_inline
291552284Sobrien    = "static storage duration functions cannot be inlined";
291650397Sobrien
291790075Sobrien  return body;
291852284Sobrien}
291950397Sobrien
292052284Sobrien/* Finish the generation of the function which performs initialization
292152284Sobrien   and destruction of objects with static storage duration.  After
292252284Sobrien   this point, no more such objects can be created.  */
292350397Sobrien
292452284Sobrienstatic void
292590075Sobrienfinish_static_storage_duration_function (body)
292690075Sobrien     tree body;
292752284Sobrien{
292852284Sobrien  /* Close out the function.  */
292990075Sobrien  finish_compound_stmt (/*has_no_scope=*/0, body);
293090075Sobrien  expand_body (finish_function (0));
293152284Sobrien}
293250397Sobrien
293352284Sobrien/* Return the information about the indicated PRIORITY level.  If no
293452284Sobrien   code to handle this level has yet been generated, generate the
293552284Sobrien   appropriate prologue.  */
293650397Sobrien
293752284Sobrienstatic priority_info
293852284Sobrienget_priority_info (priority)
293952284Sobrien     int priority;
294052284Sobrien{
294152284Sobrien  priority_info pi;
294252284Sobrien  splay_tree_node n;
294352284Sobrien
294452284Sobrien  n = splay_tree_lookup (priority_info_map,
294552284Sobrien			 (splay_tree_key) priority);
294652284Sobrien  if (!n)
294752284Sobrien    {
294852284Sobrien      /* Create a new priority information structure, and insert it
294952284Sobrien	 into the map.  */
295052284Sobrien      pi = (priority_info) xmalloc (sizeof (struct priority_info_s));
295152284Sobrien      pi->initializations_p = 0;
295252284Sobrien      pi->destructions_p = 0;
295352284Sobrien      splay_tree_insert (priority_info_map,
295452284Sobrien			 (splay_tree_key) priority,
295552284Sobrien			 (splay_tree_value) pi);
295650397Sobrien    }
295752284Sobrien  else
295852284Sobrien    pi = (priority_info) n->value;
295950397Sobrien
296052284Sobrien  return pi;
296150397Sobrien}
296250397Sobrien
296390075Sobrien/* Set up to handle the initialization or destruction of DECL.  If
296490075Sobrien   INITP is non-zero, we are initializing the variable.  Otherwise, we
296590075Sobrien   are destroying it.  */
296618334Speter
296790075Sobrienstatic tree
296890075Sobrienstart_static_initialization_or_destruction (decl, initp)
296952284Sobrien     tree decl;
297090075Sobrien     int initp;
297118334Speter{
297290075Sobrien  tree guard_if_stmt = NULL_TREE;
297390075Sobrien  int priority;
297490075Sobrien  tree cond;
297590075Sobrien  tree guard;
297690075Sobrien  tree init_cond;
297752284Sobrien  priority_info pi;
297818334Speter
297990075Sobrien  /* Figure out the priority for this declaration.  */
298090075Sobrien  priority = DECL_INIT_PRIORITY (decl);
298190075Sobrien  if (!priority)
298290075Sobrien    priority = DEFAULT_INIT_PRIORITY;
298390075Sobrien
298490075Sobrien  /* Remember that we had an initialization or finalization at this
298590075Sobrien     priority.  */
298652284Sobrien  pi = get_priority_info (priority);
298790075Sobrien  if (initp)
298890075Sobrien    pi->initializations_p = 1;
298952284Sobrien  else
299090075Sobrien    pi->destructions_p = 1;
299118334Speter
299290075Sobrien  /* Trick the compiler into thinking we are at the file and line
299390075Sobrien     where DECL was declared so that error-messages make sense, and so
299490075Sobrien     that the debugger will show somewhat sensible file and line
299590075Sobrien     information.  */
299690075Sobrien  input_filename = DECL_SOURCE_FILE (decl);
299790075Sobrien  lineno = DECL_SOURCE_LINE (decl);
299818334Speter
299990075Sobrien  /* Because of:
300052284Sobrien
300190075Sobrien       [class.access.spec]
300290075Sobrien
300390075Sobrien       Access control for implicit calls to the constructors,
300490075Sobrien       the conversion functions, or the destructor called to
300590075Sobrien       create and destroy a static data member is performed as
300690075Sobrien       if these calls appeared in the scope of the member's
300790075Sobrien       class.
300890075Sobrien
300990075Sobrien     we pretend we are in a static member function of the class of
301090075Sobrien     which the DECL is a member.  */
301190075Sobrien  if (member_p (decl))
301290075Sobrien    {
301390075Sobrien      DECL_CONTEXT (current_function_decl) = DECL_CONTEXT (decl);
301490075Sobrien      DECL_STATIC_FUNCTION_P (current_function_decl) = 1;
301590075Sobrien    }
301652284Sobrien
301790075Sobrien  /* Conditionalize this initialization on being in the right priority
301890075Sobrien     and being initializing/finalizing appropriately.  */
301990075Sobrien  guard_if_stmt = begin_if_stmt ();
302090075Sobrien  cond = cp_build_binary_op (EQ_EXPR,
302190075Sobrien			     priority_decl,
302290075Sobrien			     build_int_2 (priority, 0));
302390075Sobrien  init_cond = initp ? integer_one_node : integer_zero_node;
302490075Sobrien  init_cond = cp_build_binary_op (EQ_EXPR,
302590075Sobrien				  initialize_p_decl,
302690075Sobrien				  init_cond);
302790075Sobrien  cond = cp_build_binary_op (TRUTH_ANDIF_EXPR, cond, init_cond);
302852284Sobrien
302990075Sobrien  /* Assume we don't need a guard.  */
303090075Sobrien  guard = NULL_TREE;
303190075Sobrien  /* We need a guard if this is an object with external linkage that
303290075Sobrien     might be initialized in more than one place.  (For example, a
303390075Sobrien     static data member of a template, when the data member requires
303490075Sobrien     construction.)  */
303590075Sobrien  if (TREE_PUBLIC (decl) && (DECL_COMMON (decl)
303690075Sobrien			     || DECL_ONE_ONLY (decl)
303790075Sobrien			     || DECL_WEAK (decl)))
303890075Sobrien    {
303990075Sobrien      tree guard_cond;
304052284Sobrien
304190075Sobrien      guard = get_guard (decl);
304252284Sobrien
304390075Sobrien      /* When using __cxa_atexit, we just check the GUARD as we would
304490075Sobrien	 for a local static.  */
304590075Sobrien      if (flag_use_cxa_atexit)
304690075Sobrien	{
304790075Sobrien	  /* When using __cxa_atexit, we never try to destroy
304890075Sobrien	     anything from a static destructor.  */
304990075Sobrien	  my_friendly_assert (initp, 20000629);
305090075Sobrien	  guard_cond = get_guard_cond (guard);
305190075Sobrien	}
305290075Sobrien      /* If we don't have __cxa_atexit, then we will be running
305390075Sobrien	 destructors from .fini sections, or their equivalents.  So,
305490075Sobrien	 we need to know how many times we've tried to initialize this
305590075Sobrien	 object.  We do initializations only if the GUARD is zero,
305690075Sobrien	 i.e., if we are the first to initialize the variable.  We do
305790075Sobrien	 destructions only if the GUARD is one, i.e., if we are the
305890075Sobrien	 last to destroy the variable.  */
305990075Sobrien      else if (initp)
306090075Sobrien	guard_cond
306190075Sobrien	  = cp_build_binary_op (EQ_EXPR,
306290075Sobrien				build_unary_op (PREINCREMENT_EXPR,
306390075Sobrien						guard,
306490075Sobrien						/*noconvert=*/1),
306590075Sobrien				integer_one_node);
306690075Sobrien      else
306790075Sobrien	guard_cond
306890075Sobrien	  = cp_build_binary_op (EQ_EXPR,
306990075Sobrien				build_unary_op (PREDECREMENT_EXPR,
307090075Sobrien						guard,
307190075Sobrien						/*noconvert=*/1),
307290075Sobrien				integer_zero_node);
307352284Sobrien
307490075Sobrien      cond = cp_build_binary_op (TRUTH_ANDIF_EXPR, cond, guard_cond);
307590075Sobrien    }
307690075Sobrien
307790075Sobrien  finish_if_stmt_cond (cond, guard_if_stmt);
307890075Sobrien
307990075Sobrien  /* If we're using __cxa_atexit, we have not already set the GUARD,
308090075Sobrien     so we must do so now.  */
308190075Sobrien  if (guard && initp && flag_use_cxa_atexit)
308290075Sobrien    finish_expr_stmt (set_guard (guard));
308390075Sobrien
308490075Sobrien  return guard_if_stmt;
308552284Sobrien}
308652284Sobrien
308790075Sobrien/* We've just finished generating code to do an initialization or
308890075Sobrien   finalization.  GUARD_IF_STMT is the if-statement we used to guard
308990075Sobrien   the initialization.  */
309052284Sobrien
309152284Sobrienstatic void
309290075Sobrienfinish_static_initialization_or_destruction (guard_if_stmt)
309390075Sobrien     tree guard_if_stmt;
309452284Sobrien{
309590075Sobrien  finish_then_clause (guard_if_stmt);
309690075Sobrien  finish_if_stmt ();
309752284Sobrien
309890075Sobrien  /* Now that we're done with DECL we don't need to pretend to be a
309990075Sobrien     member of its class any longer.  */
310090075Sobrien  DECL_CONTEXT (current_function_decl) = NULL_TREE;
310190075Sobrien  DECL_STATIC_FUNCTION_P (current_function_decl) = 0;
310290075Sobrien}
310318334Speter
310490075Sobrien/* Generate code to do the static initialization of DECL.  The
310590075Sobrien   initialization is INIT.  If DECL may be initialized more than once
310690075Sobrien   in different object files, GUARD is the guard variable to
310790075Sobrien   check.  PRIORITY is the priority for the initialization.  */
310850397Sobrien
310990075Sobrienstatic void
311090075Sobriendo_static_initialization (decl, init)
311190075Sobrien     tree decl;
311290075Sobrien     tree init;
311390075Sobrien{
311490075Sobrien  tree expr;
311590075Sobrien  tree guard_if_stmt;
311690075Sobrien
311790075Sobrien  /* Set up for the initialization.  */
311890075Sobrien  guard_if_stmt
311990075Sobrien    = start_static_initialization_or_destruction (decl,
312090075Sobrien						  /*initp=*/1);
312152284Sobrien
312290075Sobrien  /* Do the initialization itself.  */
312390075Sobrien  if (IS_AGGR_TYPE (TREE_TYPE (decl))
312490075Sobrien      || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
312590075Sobrien    expr = build_aggr_init (decl, init, 0);
312690075Sobrien  else
312790075Sobrien    {
312890075Sobrien      expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
312990075Sobrien      TREE_SIDE_EFFECTS (expr) = 1;
313090075Sobrien    }
313190075Sobrien  finish_expr_stmt (expr);
313218334Speter
313390075Sobrien  /* If we're using __cxa_atexit, register a a function that calls the
313490075Sobrien     destructor for the object.  */
313590075Sobrien  if (flag_use_cxa_atexit)
313690075Sobrien    register_dtor_fn (decl);
313718334Speter
313890075Sobrien  /* Finsh up.  */
313990075Sobrien  finish_static_initialization_or_destruction (guard_if_stmt);
314052284Sobrien}
314150397Sobrien
314290075Sobrien/* Generate code to do the static destruction of DECL.  If DECL may be
314390075Sobrien   initialized more than once in different object files, GUARD is the
314490075Sobrien   guard variable to check.  PRIORITY is the priority for the
314590075Sobrien   destruction.  */
314650397Sobrien
314752284Sobrienstatic void
314890075Sobriendo_static_destruction (decl)
314952284Sobrien     tree decl;
315052284Sobrien{
315190075Sobrien  tree guard_if_stmt;
315250397Sobrien
315390075Sobrien  /* If we're using __cxa_atexit, then destructors are registered
315490075Sobrien     immediately after objects are initialized.  */
315590075Sobrien  my_friendly_assert (!flag_use_cxa_atexit, 20000121);
315690075Sobrien
315790075Sobrien  /* If we don't need a destructor, there's nothing to do.  */
315890075Sobrien  if (TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
315952284Sobrien    return;
316050397Sobrien
316190075Sobrien  /* Actually do the destruction.  */
316290075Sobrien  guard_if_stmt = start_static_initialization_or_destruction (decl,
316390075Sobrien							       /*initp=*/0);
316490075Sobrien  finish_expr_stmt (build_cleanup (decl));
316590075Sobrien  finish_static_initialization_or_destruction (guard_if_stmt);
316690075Sobrien}
316752284Sobrien
316890075Sobrien/* VARS is a list of variables with static storage duration which may
316990075Sobrien   need initialization and/or finalization.  Remove those variables
317090075Sobrien   that don't really need to be initialized or finalized, and return
317190075Sobrien   the resulting list.  The order in which the variables appear in
317290075Sobrien   VARS is in reverse order of the order in which they should actually
317390075Sobrien   be initialized.  The list we return is in the unreversed order;
317490075Sobrien   i.e., the first variable should be initialized first.  */
317552284Sobrien
317690075Sobrienstatic tree
317790075Sobrienprune_vars_needing_no_initialization (vars)
317890075Sobrien     tree vars;
317990075Sobrien{
318090075Sobrien  tree var;
318190075Sobrien  tree result;
318252284Sobrien
318390075Sobrien  for (var = vars, result = NULL_TREE;
318490075Sobrien       var;
318590075Sobrien       var = TREE_CHAIN (var))
318690075Sobrien    {
318790075Sobrien      tree decl = TREE_VALUE (var);
318890075Sobrien      tree init = TREE_PURPOSE (var);
318952284Sobrien
319090075Sobrien      /* Deal gracefully with error.  */
319190075Sobrien      if (decl == error_mark_node)
319290075Sobrien	continue;
319352284Sobrien
319490075Sobrien      /* The only things that can be initialized are variables.  */
319590075Sobrien      my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 19990420);
319652284Sobrien
319790075Sobrien      /* If this object is not defined, we don't need to do anything
319890075Sobrien	 here.  */
319990075Sobrien      if (DECL_EXTERNAL (decl))
320090075Sobrien	continue;
320152284Sobrien
320290075Sobrien      /* Also, if the initializer already contains errors, we can bail
320390075Sobrien	 out now.  */
320490075Sobrien      if (init && TREE_CODE (init) == TREE_LIST
320590075Sobrien	  && value_member (error_mark_node, init))
320690075Sobrien	continue;
320790075Sobrien
320890075Sobrien      /* This variable is going to need initialization and/or
320990075Sobrien	 finalization, so we add it to the list.  */
321090075Sobrien      result = tree_cons (init, decl, result);
321150397Sobrien    }
321250397Sobrien
321390075Sobrien  return result;
321490075Sobrien}
321550397Sobrien
321690075Sobrien/* Make sure we have told the back end about all the variables in
321790075Sobrien   VARS.  */
321890075Sobrien
321990075Sobrienstatic void
322090075Sobrienwrite_out_vars (vars)
322190075Sobrien     tree vars;
322290075Sobrien{
322390075Sobrien  tree v;
322490075Sobrien
322590075Sobrien  for (v = vars; v; v = TREE_CHAIN (v))
322690075Sobrien    if (! TREE_ASM_WRITTEN (TREE_VALUE (v)))
322790075Sobrien      rest_of_decl_compilation (TREE_VALUE (v), 0, 1, 1);
322852284Sobrien}
322950397Sobrien
323052284Sobrien/* Generate a static constructor (if CONSTRUCTOR_P) or destructor
323152284Sobrien   (otherwise) that will initialize all gobal objects with static
323252284Sobrien   storage duration having the indicated PRIORITY.  */
323318334Speter
323452284Sobrienstatic void
323552284Sobriengenerate_ctor_or_dtor_function (constructor_p, priority)
323652284Sobrien     int constructor_p;
323752284Sobrien     int priority;
323852284Sobrien{
323952284Sobrien  char function_key;
324052284Sobrien  tree arguments;
324190075Sobrien  tree body;
324252284Sobrien  size_t i;
324318334Speter
324452284Sobrien  /* We use `I' to indicate initialization and `D' to indicate
324552284Sobrien     destruction.  */
324652284Sobrien  if (constructor_p)
324752284Sobrien    function_key = 'I';
324852284Sobrien  else
324952284Sobrien    function_key = 'D';
325018334Speter
325152284Sobrien  /* Begin the function.  */
325290075Sobrien  body = start_objects (function_key, priority);
325318334Speter
325452284Sobrien  /* Call the static storage duration function with appropriate
325552284Sobrien     arguments.  */
325690075Sobrien  for (i = 0; i < ssdf_decls->elements_used; ++i)
325718334Speter    {
325852284Sobrien      arguments = tree_cons (NULL_TREE, build_int_2 (priority, 0),
325952284Sobrien			     NULL_TREE);
326052284Sobrien      arguments = tree_cons (NULL_TREE, build_int_2 (constructor_p, 0),
326152284Sobrien			     arguments);
326290075Sobrien      finish_expr_stmt (build_function_call (VARRAY_TREE (ssdf_decls, i),
326352284Sobrien					     arguments));
326418334Speter    }
326518334Speter
326652284Sobrien  /* If we're generating code for the DEFAULT_INIT_PRIORITY, throw in
326752284Sobrien     calls to any functions marked with attributes indicating that
326852284Sobrien     they should be called at initialization- or destruction-time.  */
326952284Sobrien  if (priority == DEFAULT_INIT_PRIORITY)
327018334Speter    {
327152284Sobrien      tree fns;
327252284Sobrien
327352284Sobrien      for (fns = constructor_p ? static_ctors : static_dtors;
327452284Sobrien	   fns;
327552284Sobrien	   fns = TREE_CHAIN (fns))
327690075Sobrien	finish_expr_stmt (build_function_call (TREE_VALUE (fns), NULL_TREE));
327718334Speter    }
327818334Speter
327952284Sobrien  /* Close out the function.  */
328090075Sobrien  finish_objects (function_key, priority, body);
328152284Sobrien}
328218334Speter
328352284Sobrien/* Generate constructor and destructor functions for the priority
328452284Sobrien   indicated by N.  */
328518334Speter
328652284Sobrienstatic int
328752284Sobriengenerate_ctor_and_dtor_functions_for_priority (n, data)
328852284Sobrien     splay_tree_node n;
328952284Sobrien     void *data ATTRIBUTE_UNUSED;
329052284Sobrien{
329152284Sobrien  int priority = (int) n->key;
329252284Sobrien  priority_info pi = (priority_info) n->value;
329350397Sobrien
329452284Sobrien  /* Generate the functions themselves, but only if they are really
329552284Sobrien     needed.  */
329652284Sobrien  if (pi->initializations_p
329752284Sobrien      || (priority == DEFAULT_INIT_PRIORITY && static_ctors))
329852284Sobrien    generate_ctor_or_dtor_function (/*constructor_p=*/1,
329952284Sobrien				    priority);
330052284Sobrien  if (pi->destructions_p
330152284Sobrien      || (priority == DEFAULT_INIT_PRIORITY && static_dtors))
330252284Sobrien    generate_ctor_or_dtor_function (/*constructor_p=*/0,
330352284Sobrien				    priority);
330450397Sobrien
330552284Sobrien  /* Keep iterating.  */
330652284Sobrien  return 0;
330752284Sobrien}
330850397Sobrien
330952284Sobrien/* This routine is called from the last rule in yyparse ().
331052284Sobrien   Its job is to create all the code needed to initialize and
331152284Sobrien   destroy the global aggregates.  We do the destruction
331252284Sobrien   first, since that way we only need to reverse the decls once.  */
331318334Speter
331452284Sobrienvoid
331552284Sobrienfinish_file ()
331652284Sobrien{
331752284Sobrien  tree vars;
331852284Sobrien  int reconsider;
331952284Sobrien  size_t i;
332052284Sobrien
332152284Sobrien  at_eof = 1;
332252284Sobrien
332352284Sobrien  /* Bad parse errors.  Just forget about it.  */
332452284Sobrien  if (! global_bindings_p () || current_class_type || decl_namespace_list)
332552284Sobrien    return;
332652284Sobrien
332752284Sobrien  /* Otherwise, GDB can get confused, because in only knows
332852284Sobrien     about source for LINENO-1 lines.  */
332952284Sobrien  lineno -= 1;
333052284Sobrien
333152284Sobrien  interface_unknown = 1;
333252284Sobrien  interface_only = 0;
333352284Sobrien
333452284Sobrien  /* We now have to write out all the stuff we put off writing out.
333552284Sobrien     These include:
333652284Sobrien
333752284Sobrien       o Template specializations that we have not yet instantiated,
333852284Sobrien         but which are needed.
333952284Sobrien       o Initialization and destruction for non-local objects with
334052284Sobrien         static storage duration.  (Local objects with static storage
334152284Sobrien	 duration are initialized when their scope is first entered,
334252284Sobrien	 and are cleaned up via atexit.)
334352284Sobrien       o Virtual function tables.
334452284Sobrien
334552284Sobrien     All of these may cause others to be needed.  For example,
334652284Sobrien     instantiating one function may cause another to be needed, and
334752284Sobrien     generating the intiailzer for an object may cause templates to be
334852284Sobrien     instantiated, etc., etc.  */
334952284Sobrien
335090075Sobrien  timevar_push (TV_VARCONST);
335118334Speter
335290075Sobrien  emit_support_tinfos ();
335390075Sobrien
335452284Sobrien  do
335518334Speter    {
335652284Sobrien      reconsider = 0;
335750397Sobrien
335852284Sobrien      /* If there are templates that we've put off instantiating, do
335952284Sobrien	 them now.  */
336052284Sobrien      instantiate_pending_templates ();
336118334Speter
336290075Sobrien      /* Write out virtual tables as required.  Note that writing out
336390075Sobrien	 the virtual table for a template class may cause the
336490075Sobrien	 instantiation of members of that class.  */
336552284Sobrien      if (walk_globals (vtable_decl_p,
336652284Sobrien			finish_vtable_vardecl,
336752284Sobrien			/*data=*/0))
336852284Sobrien	reconsider = 1;
336952284Sobrien
337090075Sobrien      /* Write out needed type info variables. Writing out one variable
337190075Sobrien         might cause others to be needed.  */
337290075Sobrien      if (walk_globals (tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
337370635Sobrien	reconsider = 1;
337470635Sobrien
337552284Sobrien      /* The list of objects with static storage duration is built up
337690075Sobrien	 in reverse order.  We clear STATIC_AGGREGATES so that any new
337790075Sobrien	 aggregates added during the initialization of these will be
337890075Sobrien	 initialized in the correct order when we next come around the
337990075Sobrien	 loop.  */
338090075Sobrien      vars = prune_vars_needing_no_initialization (static_aggregates);
338152284Sobrien      static_aggregates = NULL_TREE;
338290075Sobrien
338390075Sobrien      if (vars)
338452284Sobrien	{
338590075Sobrien	  tree v;
338690075Sobrien
338790075Sobrien	  /* We need to start a new initialization function each time
338890075Sobrien	     through the loop.  That's because we need to know which
338990075Sobrien	     vtables have been referenced, and TREE_SYMBOL_REFERENCED
339090075Sobrien	     isn't computed until a function is finished, and written
339190075Sobrien	     out.  That's a deficiency in the back-end.  When this is
339290075Sobrien	     fixed, these initialization functions could all become
339390075Sobrien	     inline, with resulting performance improvements.  */
339490075Sobrien	  tree ssdf_body = start_static_storage_duration_function ();
339590075Sobrien
339690075Sobrien	  /* Make sure the back end knows about all the variables.  */
339790075Sobrien	  write_out_vars (vars);
339890075Sobrien
339990075Sobrien	  /* First generate code to do all the initializations.  */
340090075Sobrien	  for (v = vars; v; v = TREE_CHAIN (v))
340190075Sobrien	    do_static_initialization (TREE_VALUE (v),
340290075Sobrien				      TREE_PURPOSE (v));
340390075Sobrien
340490075Sobrien	  /* Then, generate code to do all the destructions.  Do these
340590075Sobrien	     in reverse order so that the most recently constructed
340690075Sobrien	     variable is the first destroyed.  If we're using
340790075Sobrien	     __cxa_atexit, then we don't need to do this; functions
340890075Sobrien	     were registered at initialization time to destroy the
340990075Sobrien	     local statics.  */
341090075Sobrien	  if (!flag_use_cxa_atexit)
341152284Sobrien	    {
341290075Sobrien	      vars = nreverse (vars);
341390075Sobrien	      for (v = vars; v; v = TREE_CHAIN (v))
341490075Sobrien		do_static_destruction (TREE_VALUE (v));
341552284Sobrien	    }
341690075Sobrien	  else
341790075Sobrien	    vars = NULL_TREE;
341818334Speter
341990075Sobrien	  /* Finish up the static storage duration function for this
342090075Sobrien	     round.  */
342190075Sobrien	  finish_static_storage_duration_function (ssdf_body);
342290075Sobrien
342390075Sobrien	  /* All those initializations and finalizations might cause
342490075Sobrien	     us to need more inline functions, more template
342590075Sobrien	     instantiations, etc.  */
342652284Sobrien	  reconsider = 1;
342752284Sobrien	}
342852284Sobrien
342952284Sobrien      /* Go through the various inline functions, and see if any need
343052284Sobrien	 synthesizing.  */
343190075Sobrien      for (i = 0; i < deferred_fns_used; ++i)
343252284Sobrien	{
343390075Sobrien	  tree decl = VARRAY_TREE (deferred_fns, i);
343452284Sobrien	  import_export_decl (decl);
343552284Sobrien	  if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl)
343652284Sobrien	      && TREE_USED (decl)
343752284Sobrien	      && (! DECL_REALLY_EXTERN (decl) || DECL_INLINE (decl)))
343852284Sobrien	    {
343952284Sobrien	      /* Even though we're already at the top-level, we push
344052284Sobrien		 there again.  That way, when we pop back a few lines
344152284Sobrien		 hence, all of our state is restored.  Otherwise,
344252284Sobrien		 finish_function doesn't clean things up, and we end
344352284Sobrien		 up with CURRENT_FUNCTION_DECL set.  */
344452284Sobrien	      push_to_top_level ();
344590075Sobrien	      synthesize_method (decl);
344652284Sobrien	      pop_from_top_level ();
344752284Sobrien	      reconsider = 1;
344852284Sobrien	    }
344952284Sobrien	}
345050397Sobrien
345152284Sobrien      /* We lie to the back-end, pretending that some functions are
345252284Sobrien	 not defined when they really are.  This keeps these functions
345390075Sobrien	 from being put out unnecessarily.  But, we must stop lying
345452284Sobrien	 when the functions are referenced, or if they are not comdat
345552284Sobrien	 since they need to be put out now.  */
345690075Sobrien      for (i = 0; i < deferred_fns_used; ++i)
345752284Sobrien	{
345890075Sobrien	  tree decl = VARRAY_TREE (deferred_fns, i);
345952284Sobrien
346052284Sobrien	  if (DECL_NOT_REALLY_EXTERN (decl)
346152284Sobrien	      && DECL_INITIAL (decl)
346290075Sobrien	      && DECL_NEEDED_P (decl))
346352284Sobrien	    DECL_EXTERNAL (decl) = 0;
346490075Sobrien
346590075Sobrien	  /* If we're going to need to write this function out, and
346690075Sobrien	     there's already a body for it, create RTL for it now.
346790075Sobrien	     (There might be no body if this is a method we haven't
346890075Sobrien	     gotten around to synthesizing yet.)  */
346990075Sobrien	  if (!DECL_EXTERNAL (decl)
347090075Sobrien	      && DECL_NEEDED_P (decl)
347190075Sobrien	      && DECL_SAVED_TREE (decl)
347290075Sobrien	      && !TREE_ASM_WRITTEN (decl))
347390075Sobrien	    {
347490075Sobrien	      int saved_not_really_extern;
347590075Sobrien
347690075Sobrien	      /* When we call finish_function in expand_body, it will
347790075Sobrien		 try to reset DECL_NOT_REALLY_EXTERN so we save and
347890075Sobrien		 restore it here.  */
347990075Sobrien	      saved_not_really_extern = DECL_NOT_REALLY_EXTERN (decl);
348090075Sobrien	      /* Generate RTL for this function now that we know we
348190075Sobrien		 need it.  */
348290075Sobrien	      expand_body (decl);
348390075Sobrien	      /* Undo the damage done by finish_function.  */
348490075Sobrien	      DECL_EXTERNAL (decl) = 0;
348590075Sobrien	      DECL_NOT_REALLY_EXTERN (decl) = saved_not_really_extern;
348690075Sobrien	      /* If we're compiling -fsyntax-only pretend that this
348790075Sobrien		 function has been written out so that we don't try to
348890075Sobrien		 expand it again.  */
348990075Sobrien	      if (flag_syntax_only)
349090075Sobrien		TREE_ASM_WRITTEN (decl) = 1;
349190075Sobrien	      reconsider = 1;
349290075Sobrien	    }
349352284Sobrien	}
349418334Speter
349590075Sobrien      if (deferred_fns_used
349690075Sobrien	  && wrapup_global_declarations (&VARRAY_TREE (deferred_fns, 0),
349790075Sobrien					 deferred_fns_used))
349852284Sobrien	reconsider = 1;
349952284Sobrien      if (walk_namespaces (wrapup_globals_for_namespace, /*data=*/0))
350052284Sobrien	reconsider = 1;
350118334Speter
350252284Sobrien      /* Static data members are just like namespace-scope globals.  */
350352284Sobrien      for (i = 0; i < pending_statics_used; ++i)
350452284Sobrien	{
350552284Sobrien	  tree decl = VARRAY_TREE (pending_statics, i);
350652284Sobrien	  if (TREE_ASM_WRITTEN (decl))
350752284Sobrien	    continue;
350852284Sobrien	  import_export_decl (decl);
350952284Sobrien	  if (DECL_NOT_REALLY_EXTERN (decl) && ! DECL_IN_AGGR_P (decl))
351052284Sobrien	    DECL_EXTERNAL (decl) = 0;
351152284Sobrien	}
351252284Sobrien      if (pending_statics
351352284Sobrien	  && wrapup_global_declarations (&VARRAY_TREE (pending_statics, 0),
351452284Sobrien					 pending_statics_used))
351552284Sobrien	reconsider = 1;
351652284Sobrien    }
351752284Sobrien  while (reconsider);
351818334Speter
351952284Sobrien  /* We give C linkage to static constructors and destructors.  */
352052284Sobrien  push_lang_context (lang_name_c);
352150397Sobrien
352252284Sobrien  /* Generate initialization and destruction functions for all
352352284Sobrien     priorities for which they are required.  */
352452284Sobrien  if (priority_info_map)
352552284Sobrien    splay_tree_foreach (priority_info_map,
352652284Sobrien			generate_ctor_and_dtor_functions_for_priority,
352752284Sobrien			/*data=*/0);
352850397Sobrien
352952284Sobrien  /* We're done with the splay-tree now.  */
353052284Sobrien  if (priority_info_map)
353152284Sobrien    splay_tree_delete (priority_info_map);
353250397Sobrien
353352284Sobrien  /* We're done with static constructors, so we can go back to "C++"
353452284Sobrien     linkage now.  */
353552284Sobrien  pop_lang_context ();
353618334Speter
353718334Speter  /* Now delete from the chain of variables all virtual function tables.
353852284Sobrien     We output them all ourselves, because each will be treated
353990075Sobrien     specially.  We don't do this if we're just doing semantic
354090075Sobrien     analysis, and not code-generation.  */
354190075Sobrien  if (!flag_syntax_only)
354290075Sobrien    walk_globals (vtable_decl_p, prune_vtable_vardecl, /*data=*/0);
354318334Speter
354452284Sobrien  /* Now, issue warnings about static, but not defined, functions,
354590075Sobrien     etc., and emit debugging information.  */
354652284Sobrien  walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider);
354790075Sobrien  if (pending_statics)
354890075Sobrien    check_global_declarations (&VARRAY_TREE (pending_statics, 0),
354990075Sobrien			       pending_statics_used);
355018334Speter
355118334Speter  finish_repo ();
355218334Speter
355390075Sobrien  /* The entire file is now complete.  If requested, dump everything
355490075Sobrien     to a file.   */
355590075Sobrien  {
355690075Sobrien    int flags;
355790075Sobrien    FILE *stream = dump_begin (TDI_all, &flags);
355818334Speter
355990075Sobrien    if (stream)
356090075Sobrien      {
356190075Sobrien	dump_node (global_namespace, flags & ~TDF_SLIM, stream);
356290075Sobrien	dump_end (TDI_all, stream);
356390075Sobrien      }
356490075Sobrien  }
356590075Sobrien
356690075Sobrien  timevar_pop (TV_VARCONST);
356790075Sobrien
356818334Speter  if (flag_detailed_statistics)
356950397Sobrien    {
357050397Sobrien      dump_tree_statistics ();
357150397Sobrien      dump_time_statistics ();
357250397Sobrien    }
357318334Speter}
357418334Speter
357518334Speter/* This is something of the form 'A()()()()()+1' that has turned out to be an
357618334Speter   expr.  Since it was parsed like a type, we need to wade through and fix
357718334Speter   that.  Unfortunately, since operator() is left-associative, we can't use
357818334Speter   tail recursion.  In the above example, TYPE is `A', and DECL is
357918334Speter   `()()()()()'.
358018334Speter
358118334Speter   Maybe this shouldn't be recursive, but how often will it actually be
358218334Speter   used?  (jason) */
358350397Sobrien
358418334Spetertree
358518334Speterreparse_absdcl_as_expr (type, decl)
358618334Speter     tree type, decl;
358718334Speter{
358818334Speter  /* do build_functional_cast (type, NULL_TREE) at bottom */
358918334Speter  if (TREE_OPERAND (decl, 0) == NULL_TREE)
359018334Speter    return build_functional_cast (type, NULL_TREE);
359118334Speter
359218334Speter  /* recurse */
359352284Sobrien  decl = reparse_absdcl_as_expr (type, TREE_OPERAND (decl, 0));
359418334Speter
359550397Sobrien  decl = build_x_function_call (decl, NULL_TREE, current_class_ref);
359618334Speter
359752284Sobrien  if (TREE_CODE (decl) == CALL_EXPR
359852284Sobrien      && (! TREE_TYPE (decl)
359952284Sobrien          || TREE_CODE (TREE_TYPE (decl)) != VOID_TYPE))
360018334Speter    decl = require_complete_type (decl);
360118334Speter
360218334Speter  return decl;
360318334Speter}
360418334Speter
360518334Speter/* This is something of the form `int ((int)(int)(int)1)' that has turned
360618334Speter   out to be an expr.  Since it was parsed like a type, we need to wade
360718334Speter   through and fix that.  Since casts are right-associative, we are
360818334Speter   reversing the order, so we don't have to recurse.
360918334Speter
361018334Speter   In the above example, DECL is the `(int)(int)(int)', and EXPR is the
361118334Speter   `1'.  */
361250397Sobrien
361318334Spetertree
361418334Speterreparse_absdcl_as_casts (decl, expr)
361518334Speter     tree decl, expr;
361618334Speter{
361718334Speter  tree type;
361890075Sobrien  int non_void_p = 0;
361918334Speter
362050397Sobrien  if (TREE_CODE (expr) == CONSTRUCTOR
362150397Sobrien      && TREE_TYPE (expr) == 0)
362218334Speter    {
362390075Sobrien      type = groktypename (TREE_VALUE (CALL_DECLARATOR_PARMS (decl)));
362418334Speter      decl = TREE_OPERAND (decl, 0);
362518334Speter
362690075Sobrien      if (processing_template_decl)
362790075Sobrien	TREE_TYPE (expr) = type;
362890075Sobrien      else
362918334Speter	{
363090075Sobrien	  expr = digest_init (type, expr, (tree *) 0);
363190075Sobrien	  if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
363290075Sobrien	    {
363390075Sobrien	      int failure = complete_array_type (type, expr, 1);
363490075Sobrien	      my_friendly_assert (!failure, 78);
363590075Sobrien	    }
363618334Speter	}
363718334Speter    }
363818334Speter
363918334Speter  while (decl)
364018334Speter    {
364190075Sobrien      type = groktypename (TREE_VALUE (CALL_DECLARATOR_PARMS (decl)));
364218334Speter      decl = TREE_OPERAND (decl, 0);
364390075Sobrien      if (!VOID_TYPE_P (type))
364490075Sobrien	non_void_p = 1;
364550397Sobrien      expr = build_c_cast (type, expr);
364618334Speter    }
364718334Speter
364852284Sobrien  if (warn_old_style_cast && ! in_system_header
364990075Sobrien      && non_void_p && current_lang_name != lang_name_c)
365050397Sobrien    warning ("use of old-style cast");
365150397Sobrien
365218334Speter  return expr;
365318334Speter}
365418334Speter
365550397Sobrien/* Given plain tree nodes for an expression, build up the full semantics.  */
365650397Sobrien
365750397Sobrientree
365850397Sobrienbuild_expr_from_tree (t)
365950397Sobrien     tree t;
366018334Speter{
366150397Sobrien  if (t == NULL_TREE || t == error_mark_node)
366250397Sobrien    return t;
366350397Sobrien
366450397Sobrien  switch (TREE_CODE (t))
366518334Speter    {
366618334Speter    case IDENTIFIER_NODE:
366750397Sobrien      return do_identifier (t, 0, NULL_TREE);
366850397Sobrien
366950397Sobrien    case LOOKUP_EXPR:
367050397Sobrien      if (LOOKUP_EXPR_GLOBAL (t))
367150397Sobrien	return do_scoped_id (TREE_OPERAND (t, 0), 0);
367250397Sobrien      else
367350397Sobrien	return do_identifier (TREE_OPERAND (t, 0), 0, NULL_TREE);
367450397Sobrien
367550397Sobrien    case TEMPLATE_ID_EXPR:
367650397Sobrien      return (lookup_template_function
367750397Sobrien	      (build_expr_from_tree (TREE_OPERAND (t, 0)),
367850397Sobrien	       build_expr_from_tree (TREE_OPERAND (t, 1))));
367950397Sobrien
368018334Speter    case INDIRECT_REF:
368118334Speter      return build_x_indirect_ref
368250397Sobrien	(build_expr_from_tree (TREE_OPERAND (t, 0)), "unary *");
368350397Sobrien
368450397Sobrien    case CAST_EXPR:
368550397Sobrien      return build_functional_cast
368650397Sobrien	(TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
368750397Sobrien
368850397Sobrien    case REINTERPRET_CAST_EXPR:
368950397Sobrien      return build_reinterpret_cast
369050397Sobrien	(TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
369150397Sobrien
369250397Sobrien    case CONST_CAST_EXPR:
369350397Sobrien      return build_const_cast
369450397Sobrien	(TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
369550397Sobrien
369650397Sobrien    case DYNAMIC_CAST_EXPR:
369750397Sobrien      return build_dynamic_cast
369850397Sobrien	(TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
369950397Sobrien
370050397Sobrien    case STATIC_CAST_EXPR:
370150397Sobrien      return build_static_cast
370250397Sobrien	(TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
370350397Sobrien
370450397Sobrien    case PREDECREMENT_EXPR:
370550397Sobrien    case PREINCREMENT_EXPR:
370650397Sobrien    case POSTDECREMENT_EXPR:
370750397Sobrien    case POSTINCREMENT_EXPR:
370850397Sobrien    case NEGATE_EXPR:
370950397Sobrien    case BIT_NOT_EXPR:
371050397Sobrien    case ABS_EXPR:
371150397Sobrien    case TRUTH_NOT_EXPR:
371218334Speter    case ADDR_EXPR:
371350397Sobrien    case CONVERT_EXPR:      /* Unary + */
371490075Sobrien    case REALPART_EXPR:
371590075Sobrien    case IMAGPART_EXPR:
371650397Sobrien      if (TREE_TYPE (t))
371750397Sobrien	return t;
371850397Sobrien      return build_x_unary_op (TREE_CODE (t),
371950397Sobrien			       build_expr_from_tree (TREE_OPERAND (t, 0)));
372050397Sobrien
372150397Sobrien    case PLUS_EXPR:
372250397Sobrien    case MINUS_EXPR:
372350397Sobrien    case MULT_EXPR:
372450397Sobrien    case TRUNC_DIV_EXPR:
372550397Sobrien    case CEIL_DIV_EXPR:
372650397Sobrien    case FLOOR_DIV_EXPR:
372750397Sobrien    case ROUND_DIV_EXPR:
372850397Sobrien    case EXACT_DIV_EXPR:
372950397Sobrien    case BIT_AND_EXPR:
373050397Sobrien    case BIT_ANDTC_EXPR:
373150397Sobrien    case BIT_IOR_EXPR:
373250397Sobrien    case BIT_XOR_EXPR:
373350397Sobrien    case TRUNC_MOD_EXPR:
373450397Sobrien    case FLOOR_MOD_EXPR:
373550397Sobrien    case TRUTH_ANDIF_EXPR:
373650397Sobrien    case TRUTH_ORIF_EXPR:
373750397Sobrien    case TRUTH_AND_EXPR:
373850397Sobrien    case TRUTH_OR_EXPR:
373950397Sobrien    case RSHIFT_EXPR:
374050397Sobrien    case LSHIFT_EXPR:
374150397Sobrien    case RROTATE_EXPR:
374250397Sobrien    case LROTATE_EXPR:
374350397Sobrien    case EQ_EXPR:
374450397Sobrien    case NE_EXPR:
374550397Sobrien    case MAX_EXPR:
374650397Sobrien    case MIN_EXPR:
374750397Sobrien    case LE_EXPR:
374850397Sobrien    case GE_EXPR:
374950397Sobrien    case LT_EXPR:
375050397Sobrien    case GT_EXPR:
375150397Sobrien    case MEMBER_REF:
375250397Sobrien      return build_x_binary_op
375350397Sobrien	(TREE_CODE (t),
375450397Sobrien	 build_expr_from_tree (TREE_OPERAND (t, 0)),
375550397Sobrien	 build_expr_from_tree (TREE_OPERAND (t, 1)));
375650397Sobrien
375750397Sobrien    case DOTSTAR_EXPR:
375850397Sobrien      return build_m_component_ref
375950397Sobrien	(build_expr_from_tree (TREE_OPERAND (t, 0)),
376050397Sobrien	 build_expr_from_tree (TREE_OPERAND (t, 1)));
376150397Sobrien
376218334Speter    case SCOPE_REF:
376350397Sobrien      return build_offset_ref (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1));
376450397Sobrien
376518334Speter    case ARRAY_REF:
376650397Sobrien      if (TREE_OPERAND (t, 0) == NULL_TREE)
376750397Sobrien	/* new-type-id */
376890075Sobrien	return build_nt (ARRAY_REF, NULL_TREE,
376990075Sobrien			 build_expr_from_tree (TREE_OPERAND (t, 1)));
377050397Sobrien      return grok_array_decl (build_expr_from_tree (TREE_OPERAND (t, 0)),
377150397Sobrien			      build_expr_from_tree (TREE_OPERAND (t, 1)));
377250397Sobrien
377350397Sobrien    case SIZEOF_EXPR:
377450397Sobrien    case ALIGNOF_EXPR:
377550397Sobrien      {
377650397Sobrien	tree r = build_expr_from_tree (TREE_OPERAND (t, 0));
377790075Sobrien	if (!TYPE_P (r))
377890075Sobrien	  return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r);
377990075Sobrien	else
378090075Sobrien	  return TREE_CODE (t) == SIZEOF_EXPR ? c_sizeof (r) : c_alignof (r);
378150397Sobrien      }
378250397Sobrien
378350397Sobrien    case MODOP_EXPR:
378450397Sobrien      return build_x_modify_expr
378550397Sobrien	(build_expr_from_tree (TREE_OPERAND (t, 0)),
378650397Sobrien	 TREE_CODE (TREE_OPERAND (t, 1)),
378750397Sobrien	 build_expr_from_tree (TREE_OPERAND (t, 2)));
378850397Sobrien
378950397Sobrien    case ARROW_EXPR:
379050397Sobrien      return build_x_arrow
379150397Sobrien	(build_expr_from_tree (TREE_OPERAND (t, 0)));
379250397Sobrien
379350397Sobrien    case NEW_EXPR:
379450397Sobrien      return build_new
379550397Sobrien	(build_expr_from_tree (TREE_OPERAND (t, 0)),
379650397Sobrien	 build_expr_from_tree (TREE_OPERAND (t, 1)),
379750397Sobrien	 build_expr_from_tree (TREE_OPERAND (t, 2)),
379850397Sobrien	 NEW_EXPR_USE_GLOBAL (t));
379950397Sobrien
380050397Sobrien    case DELETE_EXPR:
380150397Sobrien      return delete_sanity
380250397Sobrien	(build_expr_from_tree (TREE_OPERAND (t, 0)),
380350397Sobrien	 build_expr_from_tree (TREE_OPERAND (t, 1)),
380450397Sobrien	 DELETE_EXPR_USE_VEC (t), DELETE_EXPR_USE_GLOBAL (t));
380550397Sobrien
380650397Sobrien    case COMPOUND_EXPR:
380750397Sobrien      if (TREE_OPERAND (t, 1) == NULL_TREE)
380850397Sobrien	return build_x_compound_expr
380950397Sobrien	  (build_expr_from_tree (TREE_OPERAND (t, 0)));
381050397Sobrien      else
381190075Sobrien	abort ();
381250397Sobrien
381350397Sobrien    case METHOD_CALL_EXPR:
381450397Sobrien      if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF)
381550397Sobrien	{
381650397Sobrien	  tree ref = TREE_OPERAND (t, 0);
381790075Sobrien	  tree name = TREE_OPERAND (ref, 1);
381890075Sobrien
381990075Sobrien	  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
382090075Sobrien	    name = build_nt (TEMPLATE_ID_EXPR,
382190075Sobrien	                     TREE_OPERAND (name, 0),
382290075Sobrien	                     build_expr_from_tree (TREE_OPERAND (name, 1)));
382390075Sobrien
382450397Sobrien	  return build_scoped_method_call
382550397Sobrien	    (build_expr_from_tree (TREE_OPERAND (t, 1)),
382650397Sobrien	     build_expr_from_tree (TREE_OPERAND (ref, 0)),
382790075Sobrien	     name,
382850397Sobrien	     build_expr_from_tree (TREE_OPERAND (t, 2)));
382950397Sobrien	}
383052284Sobrien      else
383152284Sobrien	{
383252284Sobrien	  tree fn = TREE_OPERAND (t, 0);
383350397Sobrien
383452284Sobrien	  /* We can get a TEMPLATE_ID_EXPR here on code like:
383552284Sobrien
383652284Sobrien	       x->f<2>();
383752284Sobrien
383852284Sobrien	     so we must resolve that.  However, we can also get things
383952284Sobrien	     like a BIT_NOT_EXPR here, when referring to a destructor,
384052284Sobrien	     and things like that are not correctly resolved by
384152284Sobrien	     build_expr_from_tree.  So, just use build_expr_from_tree
384252284Sobrien	     when we really need it.  */
384352284Sobrien	  if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
384452284Sobrien	    fn = lookup_template_function
384552284Sobrien	      (TREE_OPERAND (fn, 0),
384652284Sobrien	       build_expr_from_tree (TREE_OPERAND (fn, 1)));
384752284Sobrien
384852284Sobrien	  return build_method_call
384952284Sobrien	    (build_expr_from_tree (TREE_OPERAND (t, 1)),
385052284Sobrien	     fn,
385152284Sobrien	     build_expr_from_tree (TREE_OPERAND (t, 2)),
385252284Sobrien	     NULL_TREE, LOOKUP_NORMAL);
385352284Sobrien	}
385452284Sobrien
385550397Sobrien    case CALL_EXPR:
385650397Sobrien      if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF)
385750397Sobrien	{
385850397Sobrien	  tree ref = TREE_OPERAND (t, 0);
385990075Sobrien	  tree name = TREE_OPERAND (ref, 1);
386090075Sobrien
386190075Sobrien	  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
386290075Sobrien	    name = build_nt (TEMPLATE_ID_EXPR,
386390075Sobrien	                     TREE_OPERAND (name, 0),
386490075Sobrien	                     build_expr_from_tree (TREE_OPERAND (name, 1)));
386590075Sobrien
386650397Sobrien	  return build_member_call
386750397Sobrien	    (build_expr_from_tree (TREE_OPERAND (ref, 0)),
386890075Sobrien	     name,
386950397Sobrien	     build_expr_from_tree (TREE_OPERAND (t, 1)));
387050397Sobrien	}
387150397Sobrien      else
387250397Sobrien	{
387350397Sobrien	  tree name = TREE_OPERAND (t, 0);
387450397Sobrien          tree id;
387550397Sobrien          tree args = build_expr_from_tree (TREE_OPERAND (t, 1));
387650397Sobrien          if (args != NULL_TREE && TREE_CODE (name) == LOOKUP_EXPR
387750397Sobrien              && !LOOKUP_EXPR_GLOBAL (name)
387850397Sobrien              && TREE_CODE ((id = TREE_OPERAND (name, 0))) == IDENTIFIER_NODE
387950397Sobrien              && (!current_class_type
388050397Sobrien                  || !lookup_member (current_class_type, id, 0, 0)))
388150397Sobrien            {
388250397Sobrien              /* Do Koenig lookup if there are no class members. */
388350397Sobrien              name = do_identifier (id, 0, args);
388450397Sobrien            }
388550397Sobrien          else if (TREE_CODE (name) == TEMPLATE_ID_EXPR
388650397Sobrien	      || ! really_overloaded_fn (name))
388750397Sobrien	    name = build_expr_from_tree (name);
388850397Sobrien	  return build_x_function_call (name, args, current_class_ref);
388950397Sobrien	}
389050397Sobrien
389150397Sobrien    case COND_EXPR:
389250397Sobrien      return build_x_conditional_expr
389350397Sobrien	(build_expr_from_tree (TREE_OPERAND (t, 0)),
389450397Sobrien	 build_expr_from_tree (TREE_OPERAND (t, 1)),
389550397Sobrien	 build_expr_from_tree (TREE_OPERAND (t, 2)));
389650397Sobrien
389790075Sobrien    case PSEUDO_DTOR_EXPR:
389890075Sobrien      return (finish_pseudo_destructor_call_expr
389990075Sobrien	      (build_expr_from_tree (TREE_OPERAND (t, 0)),
390090075Sobrien	       build_expr_from_tree (TREE_OPERAND (t, 1)),
390190075Sobrien	       build_expr_from_tree (TREE_OPERAND (t, 2))));
390290075Sobrien
390350397Sobrien    case TREE_LIST:
390450397Sobrien      {
390550397Sobrien	tree purpose, value, chain;
390650397Sobrien
390750397Sobrien	if (t == void_list_node)
390850397Sobrien	  return t;
390950397Sobrien
391050397Sobrien	purpose = TREE_PURPOSE (t);
391150397Sobrien	if (purpose)
391250397Sobrien	  purpose = build_expr_from_tree (purpose);
391350397Sobrien	value = TREE_VALUE (t);
391450397Sobrien	if (value)
391550397Sobrien	  value = build_expr_from_tree (value);
391650397Sobrien	chain = TREE_CHAIN (t);
391750397Sobrien	if (chain && chain != void_type_node)
391850397Sobrien	  chain = build_expr_from_tree (chain);
391990075Sobrien	return tree_cons (purpose, value, chain);
392050397Sobrien      }
392150397Sobrien
392250397Sobrien    case COMPONENT_REF:
392352284Sobrien      {
392452284Sobrien	tree object = build_expr_from_tree (TREE_OPERAND (t, 0));
392552284Sobrien	tree field = TREE_OPERAND (t, 1);
392652284Sobrien
392752284Sobrien	/* We use a COMPONENT_REF to indicate things of the form `x.b'
392852284Sobrien	   and `x.A::b'.  We must distinguish between those cases
392952284Sobrien	   here.  */
393052284Sobrien	if (TREE_CODE (field) == SCOPE_REF)
393152284Sobrien	  return build_object_ref (object,
393252284Sobrien				   TREE_OPERAND (field, 0),
393352284Sobrien				   TREE_OPERAND (field, 1));
393452284Sobrien	else
393552284Sobrien	  return build_x_component_ref (object, field,
393652284Sobrien					NULL_TREE, 1);
393752284Sobrien      }
393852284Sobrien
393950397Sobrien    case THROW_EXPR:
394050397Sobrien      return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0)));
394150397Sobrien
394250397Sobrien    case CONSTRUCTOR:
394350397Sobrien      {
394450397Sobrien	tree r;
394590075Sobrien	tree elts;
394690075Sobrien	tree type = TREE_TYPE (t);
394790075Sobrien	bool purpose_p;
394850397Sobrien
394950397Sobrien	/* digest_init will do the wrong thing if we let it.  */
395090075Sobrien	if (type && TYPE_PTRMEMFUNC_P (type))
395150397Sobrien	  return t;
395250397Sobrien
395390075Sobrien	r = NULL_TREE;
395490075Sobrien	/* We do not want to process the purpose of aggregate
395590075Sobrien	   initializers as they are identifier nodes which will be
395690075Sobrien	   looked up by digest_init.  */
395790075Sobrien	purpose_p = !(type && IS_AGGR_TYPE (type));
395890075Sobrien	for (elts = CONSTRUCTOR_ELTS (t); elts; elts = TREE_CHAIN (elts))
395990075Sobrien	  {
396090075Sobrien	    tree purpose = TREE_PURPOSE (elts);
396190075Sobrien	    tree value = TREE_VALUE (elts);
396290075Sobrien
396390075Sobrien	    if (purpose && purpose_p)
396490075Sobrien	      purpose = build_expr_from_tree (purpose);
396590075Sobrien	    value = build_expr_from_tree (value);
396690075Sobrien	    r = tree_cons (purpose, value, r);
396790075Sobrien	  }
396890075Sobrien
396990075Sobrien	r = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (r));
397052284Sobrien	TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
397150397Sobrien
397290075Sobrien	if (type)
397390075Sobrien	  return digest_init (type, r, 0);
397450397Sobrien	return r;
397550397Sobrien      }
397650397Sobrien
397750397Sobrien    case TYPEID_EXPR:
397890075Sobrien      if (TYPE_P (TREE_OPERAND (t, 0)))
397950397Sobrien	return get_typeid (TREE_OPERAND (t, 0));
398090075Sobrien      return build_typeid (build_expr_from_tree (TREE_OPERAND (t, 0)));
398150397Sobrien
398250397Sobrien    case VAR_DECL:
398350397Sobrien      return convert_from_reference (t);
398450397Sobrien
398590075Sobrien    case VA_ARG_EXPR:
398690075Sobrien      return build_va_arg (build_expr_from_tree (TREE_OPERAND (t, 0)),
398790075Sobrien			   TREE_TYPE (t));
398890075Sobrien
398918334Speter    default:
399050397Sobrien      return t;
399118334Speter    }
399218334Speter}
399318334Speter
399418334Speter/* This is something of the form `int (*a)++' that has turned out to be an
399518334Speter   expr.  It was only converted into parse nodes, so we need to go through
399618334Speter   and build up the semantics.  Most of the work is done by
399750397Sobrien   build_expr_from_tree, above.
399818334Speter
399918334Speter   In the above example, TYPE is `int' and DECL is `*a'.  */
400050397Sobrien
400118334Spetertree
400218334Speterreparse_decl_as_expr (type, decl)
400318334Speter     tree type, decl;
400418334Speter{
400550397Sobrien  decl = build_expr_from_tree (decl);
400618334Speter  if (type)
400790075Sobrien    return build_functional_cast (type, build_tree_list (NULL_TREE, decl));
400818334Speter  else
400918334Speter    return decl;
401018334Speter}
401118334Speter
401218334Speter/* This is something of the form `int (*a)' that has turned out to be a
401318334Speter   decl.  It was only converted into parse nodes, so we need to do the
401450397Sobrien   checking that make_{pointer,reference}_declarator do.  */
401518334Speter
401618334Spetertree
401718334Speterfinish_decl_parsing (decl)
401818334Speter     tree decl;
401918334Speter{
402018334Speter  switch (TREE_CODE (decl))
402118334Speter    {
402218334Speter    case IDENTIFIER_NODE:
402318334Speter      return decl;
402418334Speter    case INDIRECT_REF:
402518334Speter      return make_pointer_declarator
402618334Speter	(NULL_TREE, finish_decl_parsing (TREE_OPERAND (decl, 0)));
402718334Speter    case ADDR_EXPR:
402818334Speter      return make_reference_declarator
402918334Speter	(NULL_TREE, finish_decl_parsing (TREE_OPERAND (decl, 0)));
403018334Speter    case BIT_NOT_EXPR:
403118334Speter      TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0));
403218334Speter      return decl;
403318334Speter    case SCOPE_REF:
403418334Speter      push_nested_class (TREE_TYPE (TREE_OPERAND (decl, 0)), 3);
403518334Speter      TREE_COMPLEXITY (decl) = current_class_depth;
403618334Speter      return decl;
403718334Speter    case ARRAY_REF:
403818334Speter      TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0));
403918334Speter      return decl;
404052284Sobrien    case TREE_LIST:
404152284Sobrien      /* For attribute handling.  */
404252284Sobrien      TREE_VALUE (decl) = finish_decl_parsing (TREE_VALUE (decl));
404352284Sobrien      return decl;
404490075Sobrien    case TEMPLATE_ID_EXPR:
404590075Sobrien      return decl;
404618334Speter    default:
404790075Sobrien      abort ();
404818334Speter      return NULL_TREE;
404918334Speter    }
405018334Speter}
405118334Speter
405250397Sobrien/* Return 1 if root encloses child. */
405318334Speter
405450397Sobrienstatic int
405550397Sobrienis_namespace_ancestor (root, child)
405650397Sobrien     tree root, child;
405750397Sobrien{
405850397Sobrien  if (root == child)
405950397Sobrien    return 1;
406050397Sobrien  if (root == global_namespace)
406150397Sobrien    return 1;
406250397Sobrien  if (child == global_namespace)
406350397Sobrien    return 0;
406450397Sobrien  return is_namespace_ancestor (root, CP_DECL_CONTEXT (child));
406550397Sobrien}
406650397Sobrien
406750397Sobrien
406850397Sobrien/* Return the namespace that is the common ancestor
406950397Sobrien   of two given namespaces. */
407050397Sobrien
407118334Spetertree
407250397Sobriennamespace_ancestor (ns1, ns2)
407350397Sobrien     tree ns1, ns2;
407418334Speter{
407550397Sobrien  if (is_namespace_ancestor (ns1, ns2))
407650397Sobrien    return ns1;
407750397Sobrien  return namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2);
407818334Speter}
407918334Speter
408050397Sobrien/* Insert used into the using list of user. Set indirect_flag if this
408150397Sobrien   directive is not directly from the source. Also find the common
408250397Sobrien   ancestor and let our users know about the new namespace */
408350397Sobrienstatic void
408450397Sobrienadd_using_namespace (user, used, indirect)
408550397Sobrien     tree user;
408650397Sobrien     tree used;
408750397Sobrien     int indirect;
408850397Sobrien{
408950397Sobrien  tree t;
409050397Sobrien  /* Using oneself is a no-op. */
409150397Sobrien  if (user == used)
409250397Sobrien    return;
409350397Sobrien  my_friendly_assert (TREE_CODE (user) == NAMESPACE_DECL, 380);
409450397Sobrien  my_friendly_assert (TREE_CODE (used) == NAMESPACE_DECL, 380);
409550397Sobrien  /* Check if we already have this. */
409650397Sobrien  t = purpose_member (used, DECL_NAMESPACE_USING (user));
409750397Sobrien  if (t != NULL_TREE)
409850397Sobrien    {
409950397Sobrien      if (!indirect)
410050397Sobrien	/* Promote to direct usage. */
410150397Sobrien	TREE_INDIRECT_USING (t) = 0;
410250397Sobrien      return;
410350397Sobrien    }
410450397Sobrien
410550397Sobrien  /* Add used to the user's using list. */
410650397Sobrien  DECL_NAMESPACE_USING (user)
410790075Sobrien    = tree_cons (used, namespace_ancestor (user, used),
410890075Sobrien		 DECL_NAMESPACE_USING (user));
410950397Sobrien
411050397Sobrien  TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
411150397Sobrien
411250397Sobrien  /* Add user to the used's users list. */
411350397Sobrien  DECL_NAMESPACE_USERS (used)
411490075Sobrien    = tree_cons (user, 0, DECL_NAMESPACE_USERS (used));
411550397Sobrien
411650397Sobrien  /* Recursively add all namespaces used. */
411750397Sobrien  for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t))
411850397Sobrien    /* indirect usage */
411950397Sobrien    add_using_namespace (user, TREE_PURPOSE (t), 1);
412050397Sobrien
412150397Sobrien  /* Tell everyone using us about the new used namespaces. */
412250397Sobrien  for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t))
412350397Sobrien    add_using_namespace (TREE_PURPOSE (t), used, 1);
412450397Sobrien}
412550397Sobrien
412650397Sobrien/* Combines two sets of overloaded functions into an OVERLOAD chain, removing
412750397Sobrien   duplicates.  The first list becomes the tail of the result.
412850397Sobrien
412952284Sobrien   The algorithm is O(n^2).  We could get this down to O(n log n) by
413052284Sobrien   doing a sort on the addresses of the functions, if that becomes
413152284Sobrien   necessary.  */
413250397Sobrien
413350397Sobrienstatic tree
413450397Sobrienmerge_functions (s1, s2)
413550397Sobrien     tree s1;
413650397Sobrien     tree s2;
413750397Sobrien{
413850397Sobrien  for (; s2; s2 = OVL_NEXT (s2))
413950397Sobrien    {
414090075Sobrien      tree fn2 = OVL_CURRENT (s2);
414190075Sobrien      tree fns1;
414290075Sobrien
414390075Sobrien      for (fns1 = s1; fns1; fns1 = OVL_NEXT (fns1))
414490075Sobrien	{
414590075Sobrien	  tree fn1 = OVL_CURRENT (fns1);
414690075Sobrien
414790075Sobrien	  /* If the function from S2 is already in S1, there is no
414890075Sobrien	     need to add it again.  For `extern "C"' functions, we
414990075Sobrien	     might have two FUNCTION_DECLs for the same function, in
415090075Sobrien	     different namespaces; again, we only need one of them.  */
415190075Sobrien	  if (fn1 == fn2
415290075Sobrien	      || (DECL_EXTERN_C_P (fn1) && DECL_EXTERN_C_P (fn2)
415390075Sobrien		  && DECL_NAME (fn1) == DECL_NAME (fn2)))
415490075Sobrien	    break;
415590075Sobrien	}
415690075Sobrien
415790075Sobrien      /* If we exhausted all of the functions in S1, FN2 is new.  */
415890075Sobrien      if (!fns1)
415990075Sobrien	s1 = build_overload (fn2, s1);
416050397Sobrien    }
416150397Sobrien  return s1;
416250397Sobrien}
416350397Sobrien
416450397Sobrien/* This should return an error not all definitions define functions.
416550397Sobrien   It is not an error if we find two functions with exactly the
416650397Sobrien   same signature, only if these are selected in overload resolution.
416750397Sobrien   old is the current set of bindings, new the freshly-found binding.
416850397Sobrien   XXX Do we want to give *all* candidates in case of ambiguity?
416950397Sobrien   XXX In what way should I treat extern declarations?
417050397Sobrien   XXX I don't want to repeat the entire duplicate_decls here */
417150397Sobrien
417250397Sobrienstatic tree
417350397Sobrienambiguous_decl (name, old, new, flags)
417418334Speter     tree name;
417550397Sobrien     tree old;
417650397Sobrien     tree new;
417750397Sobrien     int flags;
417818334Speter{
417950397Sobrien  tree val, type;
418050397Sobrien  my_friendly_assert (old != NULL_TREE, 393);
418150397Sobrien  /* Copy the value. */
418250397Sobrien  val = BINDING_VALUE (new);
418350397Sobrien  if (val)
418450397Sobrien    switch (TREE_CODE (val))
418550397Sobrien      {
418650397Sobrien      case TEMPLATE_DECL:
418750397Sobrien        /* If we expect types or namespaces, and not templates,
418850397Sobrien           or this is not a template class. */
418950397Sobrien        if (LOOKUP_QUALIFIERS_ONLY (flags)
419052284Sobrien            && !DECL_CLASS_TEMPLATE_P (val))
419150397Sobrien          val = NULL_TREE;
419250397Sobrien        break;
419350397Sobrien      case TYPE_DECL:
419450397Sobrien        if (LOOKUP_NAMESPACES_ONLY (flags))
419550397Sobrien          val = NULL_TREE;
419650397Sobrien        break;
419750397Sobrien      case NAMESPACE_DECL:
419850397Sobrien        if (LOOKUP_TYPES_ONLY (flags))
419950397Sobrien          val = NULL_TREE;
420050397Sobrien        break;
420150397Sobrien      default:
420250397Sobrien        if (LOOKUP_QUALIFIERS_ONLY (flags))
420350397Sobrien          val = NULL_TREE;
420450397Sobrien      }
420550397Sobrien
420650397Sobrien  if (!BINDING_VALUE (old))
420750397Sobrien    BINDING_VALUE (old) = val;
420850397Sobrien  else if (val && val != BINDING_VALUE (old))
420950397Sobrien    {
421050397Sobrien      if (is_overloaded_fn (BINDING_VALUE (old))
421150397Sobrien	  && is_overloaded_fn (val))
421250397Sobrien	{
421350397Sobrien	  BINDING_VALUE (old) = merge_functions (BINDING_VALUE (old),
421450397Sobrien						 val);
421550397Sobrien	}
421650397Sobrien      else
421750397Sobrien	{
421850397Sobrien	  /* Some declarations are functions, some are not. */
421950397Sobrien          if (flags & LOOKUP_COMPLAIN)
422050397Sobrien            {
422152284Sobrien	      /* If we've already given this error for this lookup,
422252284Sobrien		 BINDING_VALUE (old) is error_mark_node, so let's not
422352284Sobrien		 repeat ourselves.  */
422452284Sobrien	      if (BINDING_VALUE (old) != error_mark_node)
422552284Sobrien		{
422690075Sobrien		  error ("use of `%D' is ambiguous", name);
422752284Sobrien		  cp_error_at ("  first declared as `%#D' here",
422852284Sobrien			       BINDING_VALUE (old));
422952284Sobrien		}
423050397Sobrien              cp_error_at ("  also declared as `%#D' here", val);
423150397Sobrien            }
423290075Sobrien	  BINDING_VALUE (old) = error_mark_node;
423350397Sobrien	}
423450397Sobrien    }
423550397Sobrien  /* ... and copy the type. */
423650397Sobrien  type = BINDING_TYPE (new);
423750397Sobrien  if (LOOKUP_NAMESPACES_ONLY (flags))
423850397Sobrien    type = NULL_TREE;
423950397Sobrien  if (!BINDING_TYPE (old))
424050397Sobrien    BINDING_TYPE (old) = type;
424150397Sobrien  else if (type && BINDING_TYPE (old) != type)
424250397Sobrien    {
424350397Sobrien      if (flags & LOOKUP_COMPLAIN)
424450397Sobrien        {
424590075Sobrien          error ("`%D' denotes an ambiguous type",name);
424650397Sobrien          cp_error_at ("  first type here", BINDING_TYPE (old));
424750397Sobrien          cp_error_at ("  other type here", type);
424850397Sobrien        }
424950397Sobrien    }
425050397Sobrien  return old;
425150397Sobrien}
425218334Speter
425390075Sobrien/* Subroutine of unualified_namespace_lookup:
425490075Sobrien   Add the bindings of NAME in used namespaces to VAL.
425590075Sobrien   We are currently looking for names in namespace SCOPE, so we
425690075Sobrien   look through USINGS for using-directives of namespaces
425790075Sobrien   which have SCOPE as a common ancestor with the current scope.
425850397Sobrien   Returns zero on errors. */
425918334Speter
426050397Sobrienint
426190075Sobrienlookup_using_namespace (name, val, usings, scope, flags, spacesp)
426250397Sobrien     tree name, val, usings, scope;
426350397Sobrien     int flags;
426490075Sobrien     tree *spacesp;
426550397Sobrien{
426650397Sobrien  tree iter;
426750397Sobrien  tree val1;
426850397Sobrien  /* Iterate over all used namespaces in current, searching for using
426950397Sobrien     directives of scope. */
427050397Sobrien  for (iter = usings; iter; iter = TREE_CHAIN (iter))
427150397Sobrien    if (TREE_VALUE (iter) == scope)
427250397Sobrien      {
427390075Sobrien	if (spacesp)
427490075Sobrien	  *spacesp = tree_cons (TREE_PURPOSE (iter), NULL_TREE,
427590075Sobrien				*spacesp);
427650397Sobrien	val1 = binding_for_name (name, TREE_PURPOSE (iter));
427750397Sobrien	/* Resolve ambiguities. */
427850397Sobrien	val = ambiguous_decl (name, val, val1, flags);
427950397Sobrien      }
428090075Sobrien  return BINDING_VALUE (val) != error_mark_node;
428118334Speter}
428218334Speter
428350397Sobrien/* [namespace.qual]
428490075Sobrien   Accepts the NAME to lookup and its qualifying SCOPE.
428590075Sobrien   Returns the name/type pair found into the CPLUS_BINDING RESULT,
428650397Sobrien   or 0 on error. */
428750397Sobrien
428850397Sobrienint
428950397Sobrienqualified_lookup_using_namespace (name, scope, result, flags)
429050397Sobrien     tree name;
429150397Sobrien     tree scope;
429250397Sobrien     tree result;
429350397Sobrien     int flags;
429450397Sobrien{
429550397Sobrien  /* Maintain a list of namespaces visited... */
429650397Sobrien  tree seen = NULL_TREE;
429750397Sobrien  /* ... and a list of namespace yet to see. */
429850397Sobrien  tree todo = NULL_TREE;
429950397Sobrien  tree usings;
430090075Sobrien  /* Look through namespace aliases.  */
430190075Sobrien  scope = ORIGINAL_NAMESPACE (scope);
430250397Sobrien  while (scope && (result != error_mark_node))
430350397Sobrien    {
430490075Sobrien      seen = tree_cons (scope, NULL_TREE, seen);
430550397Sobrien      result = ambiguous_decl (name, result,
430650397Sobrien                               binding_for_name (name, scope), flags);
430750397Sobrien      if (!BINDING_VALUE (result) && !BINDING_TYPE (result))
430850397Sobrien	/* Consider using directives. */
430950397Sobrien	for (usings = DECL_NAMESPACE_USING (scope); usings;
431050397Sobrien	     usings = TREE_CHAIN (usings))
431150397Sobrien	  /* If this was a real directive, and we have not seen it. */
431250397Sobrien	  if (!TREE_INDIRECT_USING (usings)
431350397Sobrien	      && !purpose_member (TREE_PURPOSE (usings), seen))
431490075Sobrien	    todo = tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo);
431550397Sobrien      if (todo)
431650397Sobrien	{
431750397Sobrien	  scope = TREE_PURPOSE (todo);
431850397Sobrien	  todo = TREE_CHAIN (todo);
431950397Sobrien	}
432050397Sobrien      else
432150397Sobrien	scope = NULL_TREE; /* If there never was a todo list. */
432250397Sobrien    }
432350397Sobrien  return result != error_mark_node;
432450397Sobrien}
432550397Sobrien
432650397Sobrien/* [namespace.memdef]/2 */
432750397Sobrien
432850397Sobrien/* Set the context of a declaration to scope. Complain if we are not
432950397Sobrien   outside scope. */
433050397Sobrien
433118334Spetervoid
433252284Sobrienset_decl_namespace (decl, scope, friendp)
433350397Sobrien     tree decl;
433450397Sobrien     tree scope;
433552284Sobrien     int friendp;
433650397Sobrien{
433750397Sobrien  tree old;
433890075Sobrien
433950397Sobrien  /* Get rid of namespace aliases. */
434050397Sobrien  scope = ORIGINAL_NAMESPACE (scope);
434150397Sobrien
434252284Sobrien  /* It is ok for friends to be qualified in parallel space.  */
434352284Sobrien  if (!friendp && !is_namespace_ancestor (current_namespace, scope))
434490075Sobrien    error ("declaration of `%D' not in a namespace surrounding `%D'",
434550397Sobrien	      decl, scope);
434650397Sobrien  DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
434750397Sobrien  if (scope != current_namespace)
434850397Sobrien    {
434950397Sobrien      /* See whether this has been declared in the namespace. */
435050397Sobrien      old = namespace_binding (DECL_NAME (decl), scope);
435150397Sobrien      if (!old)
435250397Sobrien	/* No old declaration at all. */
435350397Sobrien	goto complain;
435490075Sobrien      /* A template can be explicitly specialized in any namespace.  */
435590075Sobrien      if (processing_explicit_instantiation)
435690075Sobrien	return;
435750397Sobrien      if (!is_overloaded_fn (decl))
435850397Sobrien	/* Don't compare non-function decls with decls_match here,
435950397Sobrien	   since it can't check for the correct constness at this
436050397Sobrien	   point. pushdecl will find those errors later.  */
436150397Sobrien	return;
436250397Sobrien      /* Since decl is a function, old should contain a function decl. */
436350397Sobrien      if (!is_overloaded_fn (old))
436450397Sobrien	goto complain;
436552284Sobrien      if (processing_template_decl || processing_specialization)
436652284Sobrien	/* We have not yet called push_template_decl to turn the
436752284Sobrien	   FUNCTION_DECL into a TEMPLATE_DECL, so the declarations
436852284Sobrien	   won't match.  But, we'll check later, when we construct the
436952284Sobrien	   template.  */
437052284Sobrien	return;
437150397Sobrien      for (; old; old = OVL_NEXT (old))
437250397Sobrien	if (decls_match (decl, OVL_CURRENT (old)))
437350397Sobrien	  return;
437450397Sobrien    }
437550397Sobrien  else
437650397Sobrien    return;
437750397Sobrien complain:
437890075Sobrien  error ("`%D' should have been declared inside `%D'",
437950397Sobrien	    decl, scope);
438050397Sobrien}
438150397Sobrien
438250397Sobrien/* Compute the namespace where a declaration is defined. */
438350397Sobrien
438452284Sobrienstatic tree
438550397Sobriendecl_namespace (decl)
438650397Sobrien     tree decl;
438750397Sobrien{
438890075Sobrien  if (TYPE_P (decl))
438990075Sobrien    decl = TYPE_STUB_DECL (decl);
439050397Sobrien  while (DECL_CONTEXT (decl))
439150397Sobrien    {
439250397Sobrien      decl = DECL_CONTEXT (decl);
439350397Sobrien      if (TREE_CODE (decl) == NAMESPACE_DECL)
439450397Sobrien	return decl;
439590075Sobrien      if (TYPE_P (decl))
439650397Sobrien	decl = TYPE_STUB_DECL (decl);
439790075Sobrien      my_friendly_assert (DECL_P (decl), 390);
439850397Sobrien    }
439950397Sobrien
440050397Sobrien  return global_namespace;
440150397Sobrien}
440250397Sobrien
440350397Sobrien/* Return the namespace where the current declaration is declared. */
440450397Sobrien
440550397Sobrientree
440650397Sobriencurrent_decl_namespace ()
440750397Sobrien{
440850397Sobrien  tree result;
440950397Sobrien  /* If we have been pushed into a different namespace, use it. */
441050397Sobrien  if (decl_namespace_list)
441150397Sobrien    return TREE_PURPOSE (decl_namespace_list);
441250397Sobrien
441350397Sobrien  if (current_class_type)
441450397Sobrien    result = decl_namespace (TYPE_STUB_DECL (current_class_type));
441550397Sobrien  else if (current_function_decl)
441650397Sobrien    result = decl_namespace (current_function_decl);
441750397Sobrien  else
441850397Sobrien    result = current_namespace;
441950397Sobrien  return result;
442050397Sobrien}
442150397Sobrien
442250397Sobrien/* Temporarily set the namespace for the current declaration. */
442350397Sobrien
442450397Sobrienvoid
442550397Sobrienpush_decl_namespace (decl)
442650397Sobrien     tree decl;
442750397Sobrien{
442850397Sobrien  if (TREE_CODE (decl) != NAMESPACE_DECL)
442950397Sobrien    decl = decl_namespace (decl);
443090075Sobrien  decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl),
443190075Sobrien                                   NULL_TREE, decl_namespace_list);
443250397Sobrien}
443350397Sobrien
443450397Sobrienvoid
443550397Sobrienpop_decl_namespace ()
443650397Sobrien{
443750397Sobrien  decl_namespace_list = TREE_CHAIN (decl_namespace_list);
443850397Sobrien}
443950397Sobrien
444052284Sobrien/* Enter a class or namespace scope. */
444152284Sobrien
444252284Sobrienvoid
444352284Sobrienpush_scope (t)
444452284Sobrien     tree t;
444550397Sobrien{
444652284Sobrien  if (TREE_CODE (t) == NAMESPACE_DECL)
444752284Sobrien    push_decl_namespace (t);
444852284Sobrien  else
444952284Sobrien    pushclass (t, 2);
445050397Sobrien}
445150397Sobrien
445252284Sobrien/* Leave scope pushed by push_scope. */
445352284Sobrien
445452284Sobrienvoid
445552284Sobrienpop_scope (t)
445652284Sobrien     tree t;
445752284Sobrien{
445852284Sobrien  if (TREE_CODE (t) == NAMESPACE_DECL)
445952284Sobrien    pop_decl_namespace ();
446052284Sobrien  else
446152284Sobrien    popclass ();
446252284Sobrien}
446352284Sobrien
446450397Sobrien/* [basic.lookup.koenig] */
446550397Sobrien/* A non-zero return value in the functions below indicates an error.
446650397Sobrien   All nodes allocated in the procedure are on the scratch obstack. */
446750397Sobrien
446850397Sobrienstruct arg_lookup
446950397Sobrien{
447050397Sobrien  tree name;
447150397Sobrien  tree namespaces;
447250397Sobrien  tree classes;
447350397Sobrien  tree functions;
447450397Sobrien};
447550397Sobrien
447690075Sobrienstatic int arg_assoc         PARAMS ((struct arg_lookup*, tree));
447790075Sobrienstatic int arg_assoc_args    PARAMS ((struct arg_lookup*, tree));
447890075Sobrienstatic int arg_assoc_type    PARAMS ((struct arg_lookup*, tree));
447990075Sobrienstatic int add_function      PARAMS ((struct arg_lookup *, tree));
448090075Sobrienstatic int arg_assoc_namespace PARAMS ((struct arg_lookup *, tree));
448190075Sobrienstatic int arg_assoc_class   PARAMS ((struct arg_lookup *, tree));
448290075Sobrienstatic int arg_assoc_template_arg PARAMS ((struct arg_lookup*, tree));
448350397Sobrien
448450397Sobrien/* Add a function to the lookup structure.
448550397Sobrien   Returns 1 on error.  */
448650397Sobrien
448750397Sobrienstatic int
448850397Sobrienadd_function (k, fn)
448950397Sobrien     struct arg_lookup *k;
449050397Sobrien     tree fn;
449150397Sobrien{
449290075Sobrien  /* We used to check here to see if the function was already in the list,
449390075Sobrien     but that's O(n^2), which is just too expensive for function lookup.
449490075Sobrien     Now we deal with the occasional duplicate in joust.  In doing this, we
449590075Sobrien     assume that the number of duplicates will be small compared to the
449690075Sobrien     total number of functions being compared, which should usually be the
449790075Sobrien     case.  */
449890075Sobrien
449950397Sobrien  /* We must find only functions, or exactly one non-function. */
450090075Sobrien  if (!k->functions)
450190075Sobrien    k->functions = fn;
450290075Sobrien  else if (is_overloaded_fn (k->functions) && is_overloaded_fn (fn))
450350397Sobrien    k->functions = build_overload (fn, k->functions);
450490075Sobrien  else
450590075Sobrien    {
450690075Sobrien      tree f1 = OVL_CURRENT (k->functions);
450790075Sobrien      tree f2 = fn;
450890075Sobrien      if (is_overloaded_fn (f1))
450990075Sobrien	{
451090075Sobrien	  fn = f1; f1 = f2; f2 = fn;
451190075Sobrien	}
451290075Sobrien      cp_error_at ("`%D' is not a function,", f1);
451390075Sobrien      cp_error_at ("  conflict with `%D'", f2);
451490075Sobrien      error ("  in call to `%D'", k->name);
451590075Sobrien      return 1;
451690075Sobrien    }
451790075Sobrien
451850397Sobrien  return 0;
451950397Sobrien}
452050397Sobrien
452150397Sobrien/* Add functions of a namespace to the lookup structure.
452250397Sobrien   Returns 1 on error.  */
452350397Sobrien
452450397Sobrienstatic int
452550397Sobrienarg_assoc_namespace (k, scope)
452650397Sobrien     struct arg_lookup *k;
452750397Sobrien     tree scope;
452850397Sobrien{
452950397Sobrien  tree value;
453050397Sobrien
453150397Sobrien  if (purpose_member (scope, k->namespaces))
453250397Sobrien    return 0;
453350397Sobrien  k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces);
453450397Sobrien
453550397Sobrien  value = namespace_binding (k->name, scope);
453650397Sobrien  if (!value)
453750397Sobrien    return 0;
453890075Sobrien
453950397Sobrien  for (; value; value = OVL_NEXT (value))
454050397Sobrien    if (add_function (k, OVL_CURRENT (value)))
454150397Sobrien      return 1;
454250397Sobrien
454350397Sobrien  return 0;
454450397Sobrien}
454550397Sobrien
454690075Sobrien/* Adds everything associated with a template argument to the lookup
454790075Sobrien   structure.  Returns 1 on error.  */
454890075Sobrien
454990075Sobrienstatic int
455090075Sobrienarg_assoc_template_arg (k, arg)
455190075Sobrien     struct arg_lookup* k;
455290075Sobrien     tree arg;
455390075Sobrien{
455490075Sobrien  /* [basic.lookup.koenig]
455590075Sobrien
455690075Sobrien     If T is a template-id, its associated namespaces and classes are
455790075Sobrien     ... the namespaces and classes associated with the types of the
455890075Sobrien     template arguments provided for template type parameters
455990075Sobrien     (excluding template template parameters); the namespaces in which
456090075Sobrien     any template template arguments are defined; and the classes in
456190075Sobrien     which any member templates used as template template arguments
456290075Sobrien     are defined.  [Note: non-type template arguments do not
456390075Sobrien     contribute to the set of associated namespaces.  ]  */
456490075Sobrien
456590075Sobrien  /* Consider first template template arguments.  */
456690075Sobrien  if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
456790075Sobrien      || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)
456890075Sobrien    return 0;
456990075Sobrien  else if (TREE_CODE (arg) == TEMPLATE_DECL)
457090075Sobrien    {
457190075Sobrien      tree ctx = CP_DECL_CONTEXT (arg);
457290075Sobrien
457390075Sobrien      /* It's not a member template.  */
457490075Sobrien      if (TREE_CODE (ctx) == NAMESPACE_DECL)
457590075Sobrien        return arg_assoc_namespace (k, ctx);
457690075Sobrien      /* Otherwise, it must be member template.  */
457790075Sobrien      else
457890075Sobrien        return arg_assoc_class (k, ctx);
457990075Sobrien    }
458090075Sobrien  /* It's not a template template argument, but it is a type template
458190075Sobrien     argument.  */
458290075Sobrien  else if (TYPE_P (arg))
458390075Sobrien    return arg_assoc_type (k, arg);
458490075Sobrien  /* It's a non-type template argument.  */
458590075Sobrien  else
458690075Sobrien    return 0;
458790075Sobrien}
458890075Sobrien
458950397Sobrien/* Adds everything associated with class to the lookup structure.
459050397Sobrien   Returns 1 on error.  */
459150397Sobrien
459250397Sobrienstatic int
459350397Sobrienarg_assoc_class (k, type)
459450397Sobrien     struct arg_lookup* k;
459550397Sobrien     tree type;
459650397Sobrien{
459750397Sobrien  tree list, friends, context;
459850397Sobrien  int i;
459950397Sobrien
460090075Sobrien  /* Backend build structures, such as __builtin_va_list, aren't
460190075Sobrien     affected by all this.  */
460290075Sobrien  if (!CLASS_TYPE_P (type))
460390075Sobrien    return 0;
460490075Sobrien
460550397Sobrien  if (purpose_member (type, k->classes))
460650397Sobrien    return 0;
460750397Sobrien  k->classes = tree_cons (type, NULL_TREE, k->classes);
460850397Sobrien
460950397Sobrien  context = decl_namespace (TYPE_MAIN_DECL (type));
461050397Sobrien  if (arg_assoc_namespace (k, context))
461150397Sobrien    return 1;
461250397Sobrien
461350397Sobrien  /* Process baseclasses. */
461450397Sobrien  for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); i++)
461550397Sobrien    if (arg_assoc_class (k, TYPE_BINFO_BASETYPE (type, i)))
461650397Sobrien      return 1;
461750397Sobrien
461850397Sobrien  /* Process friends. */
461950397Sobrien  for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
462050397Sobrien       list = TREE_CHAIN (list))
462150397Sobrien    if (k->name == TREE_PURPOSE (list))
462250397Sobrien      for (friends = TREE_VALUE (list); friends;
462350397Sobrien	   friends = TREE_CHAIN (friends))
462450397Sobrien	/* Only interested in global functions with potentially hidden
462550397Sobrien           (i.e. unqualified) declarations. */
462690075Sobrien	if (TREE_PURPOSE (friends) == error_mark_node && TREE_VALUE (friends)
462790075Sobrien	    && decl_namespace (TREE_VALUE (friends)) == context)
462890075Sobrien	  if (add_function (k, TREE_VALUE (friends)))
462950397Sobrien	    return 1;
463050397Sobrien
463150397Sobrien  /* Process template arguments.  */
463250397Sobrien  if (CLASSTYPE_TEMPLATE_INFO (type))
463350397Sobrien    {
463490075Sobrien      list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
463590075Sobrien      for (i = 0; i < TREE_VEC_LENGTH (list); ++i)
463690075Sobrien        arg_assoc_template_arg (k, TREE_VEC_ELT (list, i));
463750397Sobrien    }
463850397Sobrien
463950397Sobrien  return 0;
464050397Sobrien}
464150397Sobrien
464250397Sobrien/* Adds everything associated with a given type.
464350397Sobrien   Returns 1 on error.  */
464450397Sobrien
464550397Sobrienstatic int
464650397Sobrienarg_assoc_type (k, type)
464750397Sobrien     struct arg_lookup *k;
464850397Sobrien     tree type;
464950397Sobrien{
465050397Sobrien  switch (TREE_CODE (type))
465150397Sobrien    {
465250397Sobrien    case VOID_TYPE:
465350397Sobrien    case INTEGER_TYPE:
465450397Sobrien    case REAL_TYPE:
465550397Sobrien    case COMPLEX_TYPE:
465690075Sobrien    case VECTOR_TYPE:
465750397Sobrien    case CHAR_TYPE:
465850397Sobrien    case BOOLEAN_TYPE:
465950397Sobrien      return 0;
466050397Sobrien    case RECORD_TYPE:
466150397Sobrien      if (TYPE_PTRMEMFUNC_P (type))
466250397Sobrien	return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type));
466350397Sobrien      return arg_assoc_class (k, type);
466450397Sobrien    case POINTER_TYPE:
466550397Sobrien    case REFERENCE_TYPE:
466650397Sobrien    case ARRAY_TYPE:
466750397Sobrien      return arg_assoc_type (k, TREE_TYPE (type));
466850397Sobrien    case UNION_TYPE:
466950397Sobrien    case ENUMERAL_TYPE:
467050397Sobrien      return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type)));
467150397Sobrien    case OFFSET_TYPE:
467250397Sobrien      /* Pointer to member: associate class type and value type. */
467350397Sobrien      if (arg_assoc_type (k, TYPE_OFFSET_BASETYPE (type)))
467450397Sobrien	return 1;
467550397Sobrien      return arg_assoc_type (k, TREE_TYPE (type));
467650397Sobrien    case METHOD_TYPE:
467750397Sobrien      /* The basetype is referenced in the first arg type, so just
467850397Sobrien	 fall through.  */
467950397Sobrien    case FUNCTION_TYPE:
468050397Sobrien      /* Associate the parameter types. */
468150397Sobrien      if (arg_assoc_args (k, TYPE_ARG_TYPES (type)))
468250397Sobrien	return 1;
468350397Sobrien      /* Associate the return type. */
468450397Sobrien      return arg_assoc_type (k, TREE_TYPE (type));
468550397Sobrien    case TEMPLATE_TYPE_PARM:
468690075Sobrien    case BOUND_TEMPLATE_TEMPLATE_PARM:
468750397Sobrien      return 0;
468890075Sobrien    case TYPENAME_TYPE:
468990075Sobrien      return 0;
469050397Sobrien    case LANG_TYPE:
469150397Sobrien      if (type == unknown_type_node)
469250397Sobrien	return 0;
469350397Sobrien      /* else fall through */
469450397Sobrien    default:
469590075Sobrien      abort ();
469650397Sobrien    }
469750397Sobrien  return 0;
469850397Sobrien}
469950397Sobrien
470050397Sobrien/* Adds everything associated with arguments.  Returns 1 on error.  */
470150397Sobrien
470250397Sobrienstatic int
470350397Sobrienarg_assoc_args (k, args)
470450397Sobrien     struct arg_lookup* k;
470550397Sobrien     tree args;
470650397Sobrien{
470750397Sobrien  for (; args; args = TREE_CHAIN (args))
470850397Sobrien    if (arg_assoc (k, TREE_VALUE (args)))
470950397Sobrien      return 1;
471050397Sobrien  return 0;
471150397Sobrien}
471250397Sobrien
471350397Sobrien/* Adds everything associated with a given tree_node.  Returns 1 on error.  */
471450397Sobrien
471550397Sobrienstatic int
471650397Sobrienarg_assoc (k, n)
471750397Sobrien     struct arg_lookup* k;
471850397Sobrien     tree n;
471950397Sobrien{
472050397Sobrien  if (n == error_mark_node)
472150397Sobrien    return 0;
472250397Sobrien
472390075Sobrien  if (TYPE_P (n))
472450397Sobrien    return arg_assoc_type (k, n);
472550397Sobrien
472650397Sobrien  if (! type_unknown_p (n))
472750397Sobrien    return arg_assoc_type (k, TREE_TYPE (n));
472850397Sobrien
472950397Sobrien  if (TREE_CODE (n) == ADDR_EXPR)
473050397Sobrien    n = TREE_OPERAND (n, 0);
473152284Sobrien  if (TREE_CODE (n) == COMPONENT_REF)
473252284Sobrien    n = TREE_OPERAND (n, 1);
473352284Sobrien  if (TREE_CODE (n) == OFFSET_REF)
473452284Sobrien    n = TREE_OPERAND (n, 1);
473550397Sobrien  while (TREE_CODE (n) == TREE_LIST)
473650397Sobrien    n = TREE_VALUE (n);
473750397Sobrien
473852284Sobrien  if (TREE_CODE (n) == FUNCTION_DECL)
473952284Sobrien    return arg_assoc_type (k, TREE_TYPE (n));
474052284Sobrien  if (TREE_CODE (n) == TEMPLATE_ID_EXPR)
474152284Sobrien    {
474252284Sobrien      /* [basic.lookup.koenig]
474350397Sobrien
474452284Sobrien	 If T is a template-id, its associated namespaces and classes
474552284Sobrien	 are the namespace in which the template is defined; for
474690075Sobrien	 member templates, the member template's class...  */
474752284Sobrien      tree template = TREE_OPERAND (n, 0);
474852284Sobrien      tree args = TREE_OPERAND (n, 1);
474952284Sobrien      tree ctx;
475052284Sobrien      tree arg;
475150397Sobrien
475290075Sobrien      if (TREE_CODE (template) == COMPONENT_REF)
475390075Sobrien        template = TREE_OPERAND (template, 1);
475490075Sobrien
475552284Sobrien      /* First, the template.  There may actually be more than one if
475652284Sobrien	 this is an overloaded function template.  But, in that case,
475752284Sobrien	 we only need the first; all the functions will be in the same
475852284Sobrien	 namespace.  */
475952284Sobrien      template = OVL_CURRENT (template);
476052284Sobrien
476152284Sobrien      ctx = CP_DECL_CONTEXT (template);
476252284Sobrien
476352284Sobrien      if (TREE_CODE (ctx) == NAMESPACE_DECL)
476452284Sobrien	{
476552284Sobrien	  if (arg_assoc_namespace (k, ctx) == 1)
476652284Sobrien	    return 1;
476752284Sobrien	}
476852284Sobrien      /* It must be a member template.  */
476952284Sobrien      else if (arg_assoc_class (k, ctx) == 1)
477052284Sobrien	return 1;
477152284Sobrien
477252284Sobrien      /* Now the arguments.  */
477352284Sobrien      for (arg = args; arg != NULL_TREE; arg = TREE_CHAIN (arg))
477490075Sobrien	if (arg_assoc_template_arg (k, TREE_VALUE (arg)) == 1)
477590075Sobrien	  return 1;
477652284Sobrien    }
477752284Sobrien  else
477852284Sobrien    {
477952284Sobrien      my_friendly_assert (TREE_CODE (n) == OVERLOAD, 980715);
478052284Sobrien
478152284Sobrien      for (; n; n = OVL_CHAIN (n))
478252284Sobrien	if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n))))
478352284Sobrien	  return 1;
478452284Sobrien    }
478552284Sobrien
478650397Sobrien  return 0;
478750397Sobrien}
478850397Sobrien
478950397Sobrien/* Performs Koenig lookup depending on arguments, where fns
479050397Sobrien   are the functions found in normal lookup. */
479150397Sobrien
479250397Sobrientree
479350397Sobrienlookup_arg_dependent (name, fns, args)
479450397Sobrien     tree name;
479550397Sobrien     tree fns;
479650397Sobrien     tree args;
479750397Sobrien{
479850397Sobrien  struct arg_lookup k;
479990075Sobrien  tree fn = NULL_TREE;
480052750Sobrien
480150397Sobrien  k.name = name;
480250397Sobrien  k.functions = fns;
480350397Sobrien  k.classes = NULL_TREE;
480452750Sobrien
480590075Sobrien  /* Note that we've already looked at some namespaces during normal
480652750Sobrien     unqualified lookup, unless we found a decl in function scope.  */
480790075Sobrien  if (fns)
480890075Sobrien    fn = OVL_CURRENT (fns);
480990075Sobrien  if (fn && TREE_CODE (fn) == FUNCTION_DECL && DECL_LOCAL_FUNCTION_P (fn))
481052750Sobrien    k.namespaces = NULL_TREE;
481152750Sobrien  else
481290075Sobrien    unqualified_namespace_lookup (name, 0, &k.namespaces);
481352750Sobrien
481450397Sobrien  arg_assoc_args (&k, args);
481550397Sobrien  return k.functions;
481650397Sobrien}
481750397Sobrien
481850397Sobrien/* Process a namespace-alias declaration. */
481950397Sobrien
482050397Sobrienvoid
482118334Speterdo_namespace_alias (alias, namespace)
482218334Speter     tree alias, namespace;
482318334Speter{
482450397Sobrien  if (TREE_CODE (namespace) != NAMESPACE_DECL)
482550397Sobrien    {
482650397Sobrien      /* The parser did not find it, so it's not there. */
482790075Sobrien      error ("unknown namespace `%D'", namespace);
482850397Sobrien      return;
482950397Sobrien    }
483050397Sobrien
483150397Sobrien  namespace = ORIGINAL_NAMESPACE (namespace);
483250397Sobrien
483350397Sobrien  /* Build the alias. */
483450397Sobrien  alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
483550397Sobrien  DECL_NAMESPACE_ALIAS (alias) = namespace;
483650397Sobrien  pushdecl (alias);
483718334Speter}
483818334Speter
483950397Sobrien/* Check a non-member using-declaration. Return the name and scope
484050397Sobrien   being used, and the USING_DECL, or NULL_TREE on failure. */
484150397Sobrien
484250397Sobrienstatic tree
484350397Sobrienvalidate_nonmember_using_decl (decl, scope, name)
484418334Speter     tree decl;
484550397Sobrien     tree *scope;
484650397Sobrien     tree *name;
484718334Speter{
484890075Sobrien  if (TREE_CODE (decl) == SCOPE_REF)
484950397Sobrien    {
485050397Sobrien      *scope = TREE_OPERAND (decl, 0);
485150397Sobrien      *name = TREE_OPERAND (decl, 1);
485252284Sobrien
485390075Sobrien      if (!processing_template_decl)
485490075Sobrien        {
485590075Sobrien          /* [namespace.udecl]
485690075Sobrien             A using-declaration for a class member shall be a
485790075Sobrien             member-declaration.  */
485890075Sobrien          if(TREE_CODE (*scope) != NAMESPACE_DECL)
485990075Sobrien            {
486090075Sobrien              if (TYPE_P (*scope))
486190075Sobrien                error ("`%T' is not a namespace", *scope);
486290075Sobrien              else
486390075Sobrien                error ("`%D' is not a namespace", *scope);
486490075Sobrien              return NULL_TREE;
486590075Sobrien            }
486690075Sobrien
486790075Sobrien          /* 7.3.3/5
486890075Sobrien             A using-declaration shall not name a template-id.  */
486990075Sobrien          if (TREE_CODE (*name) == TEMPLATE_ID_EXPR)
487090075Sobrien            {
487190075Sobrien              *name = TREE_OPERAND (*name, 0);
487290075Sobrien              error ("a using-declaration cannot specify a template-id.  Try `using %D'", *name);
487390075Sobrien              return NULL_TREE;
487490075Sobrien            }
487590075Sobrien        }
487650397Sobrien    }
487750397Sobrien  else if (TREE_CODE (decl) == IDENTIFIER_NODE
487852284Sobrien           || TREE_CODE (decl) == TYPE_DECL
487952284Sobrien	   || TREE_CODE (decl) == TEMPLATE_DECL)
488050397Sobrien    {
488150397Sobrien      *scope = global_namespace;
488250397Sobrien      *name = decl;
488350397Sobrien    }
488490075Sobrien  else if (TREE_CODE (decl) == NAMESPACE_DECL)
488590075Sobrien    {
488690075Sobrien      error ("namespace `%D' not allowed in using-declaration", decl);
488790075Sobrien      return NULL_TREE;
488890075Sobrien    }
488950397Sobrien  else
489090075Sobrien    abort ();
489190075Sobrien  if (DECL_P (*name))
489250397Sobrien    *name = DECL_NAME (*name);
489350397Sobrien  /* Make a USING_DECL. */
489450397Sobrien  return push_using_decl (*scope, *name);
489550397Sobrien}
489650397Sobrien
489750397Sobrien/* Process local and global using-declarations. */
489850397Sobrien
489950397Sobrienstatic void
490050397Sobriendo_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
490150397Sobrien     tree scope, name;
490250397Sobrien     tree oldval, oldtype;
490350397Sobrien     tree *newval, *newtype;
490450397Sobrien{
490550397Sobrien  tree decls;
490650397Sobrien
490750397Sobrien  *newval = *newtype = NULL_TREE;
490890075Sobrien  decls = make_node (CPLUS_BINDING);
490950397Sobrien  if (!qualified_lookup_using_namespace (name, scope, decls, 0))
491050397Sobrien    /* Lookup error */
491118334Speter    return;
491218334Speter
491350397Sobrien  if (!BINDING_VALUE (decls) && !BINDING_TYPE (decls))
491450397Sobrien    {
491590075Sobrien      error ("`%D' not declared", name);
491650397Sobrien      return;
491750397Sobrien    }
491818334Speter
491950397Sobrien  /* Check for using functions. */
492050397Sobrien  if (BINDING_VALUE (decls) && is_overloaded_fn (BINDING_VALUE (decls)))
492118334Speter    {
492250397Sobrien      tree tmp, tmp1;
492350397Sobrien
492450397Sobrien      if (oldval && !is_overloaded_fn (oldval))
492550397Sobrien	{
492650397Sobrien	  duplicate_decls (OVL_CURRENT (BINDING_VALUE (decls)), oldval);
492750397Sobrien	  oldval = NULL_TREE;
492850397Sobrien	}
492950397Sobrien
493050397Sobrien      *newval = oldval;
493150397Sobrien      for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp))
493250397Sobrien	{
493352284Sobrien	  tree new_fn = OVL_CURRENT (tmp);
493452284Sobrien
493552284Sobrien	  /* [namespace.udecl]
493652284Sobrien
493752284Sobrien	     If a function declaration in namespace scope or block
493852284Sobrien	     scope has the same name and the same parameter types as a
493952284Sobrien	     function introduced by a using declaration the program is
494052284Sobrien	     ill-formed.  */
494150397Sobrien	  for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
494252284Sobrien	    {
494352284Sobrien	      tree old_fn = OVL_CURRENT (tmp1);
494450397Sobrien
494590075Sobrien              if (new_fn == old_fn)
494690075Sobrien                /* The function already exists in the current namespace.  */
494790075Sobrien                break;
494890075Sobrien	      else if (OVL_USED (tmp1))
494990075Sobrien	        continue; /* this is a using decl */
495090075Sobrien	      else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
495190075Sobrien		  		  TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
495252284Sobrien		{
495390075Sobrien	          /* There was already a non-using declaration in
495490075Sobrien		     this scope with the same parameter types. If both
495590075Sobrien	             are the same extern "C" functions, that's ok.  */
495690075Sobrien                  if (!decls_match (new_fn, old_fn))
495790075Sobrien    	            error ("`%D' is already declared in this scope", name);
495852284Sobrien		  break;
495952284Sobrien		}
496052284Sobrien	    }
496152284Sobrien
496252284Sobrien	  /* If we broke out of the loop, there's no reason to add
496352284Sobrien	     this function to the using declarations for this
496452284Sobrien	     scope.  */
496550397Sobrien	  if (tmp1)
496650397Sobrien	    continue;
496750397Sobrien
496850397Sobrien	  *newval = build_overload (OVL_CURRENT (tmp), *newval);
496950397Sobrien	  if (TREE_CODE (*newval) != OVERLOAD)
497050397Sobrien	    *newval = ovl_cons (*newval, NULL_TREE);
497150397Sobrien	  OVL_USED (*newval) = 1;
497250397Sobrien	}
497318334Speter    }
497450397Sobrien  else
497550397Sobrien    {
497650397Sobrien      *newval = BINDING_VALUE (decls);
497750397Sobrien      if (oldval)
497850397Sobrien	duplicate_decls (*newval, oldval);
497950397Sobrien    }
498050397Sobrien
498150397Sobrien  *newtype = BINDING_TYPE (decls);
498250397Sobrien  if (oldtype && *newtype && oldtype != *newtype)
498350397Sobrien    {
498490075Sobrien      error ("using declaration `%D' introduced ambiguous type `%T'",
498550397Sobrien		name, oldtype);
498650397Sobrien      return;
498750397Sobrien    }
498818334Speter}
498918334Speter
499050397Sobrien/* Process a using-declaration not appearing in class or local scope. */
499150397Sobrien
499250397Sobrienvoid
499350397Sobriendo_toplevel_using_decl (decl)
499450397Sobrien     tree decl;
499550397Sobrien{
499650397Sobrien  tree scope, name, binding;
499750397Sobrien  tree oldval, oldtype, newval, newtype;
499850397Sobrien
499950397Sobrien  decl = validate_nonmember_using_decl (decl, &scope, &name);
500050397Sobrien  if (decl == NULL_TREE)
500150397Sobrien    return;
500250397Sobrien
500350397Sobrien  binding = binding_for_name (name, current_namespace);
500450397Sobrien
500550397Sobrien  oldval = BINDING_VALUE (binding);
500650397Sobrien  oldtype = BINDING_TYPE (binding);
500750397Sobrien
500850397Sobrien  do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
500950397Sobrien
501050397Sobrien  /* Copy declarations found. */
501150397Sobrien  if (newval)
501250397Sobrien    BINDING_VALUE (binding) = newval;
501350397Sobrien  if (newtype)
501450397Sobrien    BINDING_TYPE (binding) = newtype;
501550397Sobrien  return;
501650397Sobrien}
501750397Sobrien
501850397Sobrien/* Process a using-declaration at function scope.  */
501950397Sobrien
502050397Sobrienvoid
502150397Sobriendo_local_using_decl (decl)
502250397Sobrien     tree decl;
502350397Sobrien{
502450397Sobrien  tree scope, name;
502550397Sobrien  tree oldval, oldtype, newval, newtype;
502650397Sobrien
502750397Sobrien  decl = validate_nonmember_using_decl (decl, &scope, &name);
502850397Sobrien  if (decl == NULL_TREE)
502950397Sobrien    return;
503050397Sobrien
503190075Sobrien  if (building_stmt_tree ()
503290075Sobrien      && at_function_scope_p ())
503390075Sobrien    add_decl_stmt (decl);
503490075Sobrien
503550397Sobrien  oldval = lookup_name_current_level (name);
503650397Sobrien  oldtype = lookup_type_current_level (name);
503750397Sobrien
503850397Sobrien  do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
503950397Sobrien
504050397Sobrien  if (newval)
504152284Sobrien    {
504252284Sobrien      if (is_overloaded_fn (newval))
504352284Sobrien	{
504452284Sobrien	  tree fn, term;
504552284Sobrien
504652284Sobrien	  /* We only need to push declarations for those functions
504752284Sobrien	     that were not already bound in the current level.
504852284Sobrien	     The old value might be NULL_TREE, it might be a single
504952284Sobrien	     function, or an OVERLOAD.  */
505052284Sobrien	  if (oldval && TREE_CODE (oldval) == OVERLOAD)
505152284Sobrien	    term = OVL_FUNCTION (oldval);
505252284Sobrien	  else
505352284Sobrien	    term = oldval;
505452284Sobrien	  for (fn = newval; fn && OVL_CURRENT (fn) != term;
505552284Sobrien	       fn = OVL_NEXT (fn))
505652284Sobrien	    push_overloaded_decl (OVL_CURRENT (fn),
505752284Sobrien				  PUSH_LOCAL | PUSH_USING);
505852284Sobrien	}
505952284Sobrien      else
506052284Sobrien	push_local_binding (name, newval, PUSH_USING);
506152284Sobrien    }
506250397Sobrien  if (newtype)
506350397Sobrien    set_identifier_type_value (name, newtype);
506450397Sobrien}
506550397Sobrien
506618334Spetertree
506718334Speterdo_class_using_decl (decl)
506818334Speter     tree decl;
506918334Speter{
507050397Sobrien  tree name, value;
507118334Speter
507250397Sobrien  if (TREE_CODE (decl) != SCOPE_REF
507390075Sobrien      || !TYPE_P (TREE_OPERAND (decl, 0)))
507450397Sobrien    {
507590075Sobrien      error ("using-declaration for non-member at class scope");
507650397Sobrien      return NULL_TREE;
507750397Sobrien    }
507850397Sobrien  name = TREE_OPERAND (decl, 1);
507950397Sobrien  if (TREE_CODE (name) == BIT_NOT_EXPR)
508050397Sobrien    {
508190075Sobrien      error ("using-declaration for destructor");
508250397Sobrien      return NULL_TREE;
508350397Sobrien    }
508490075Sobrien  else if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
508590075Sobrien    {
508690075Sobrien      name = TREE_OPERAND (name, 0);
508790075Sobrien      error ("a using-declaration cannot specify a template-id.  Try  `using %T::%D'", TREE_OPERAND (decl, 0), name);
508890075Sobrien      return NULL_TREE;
508990075Sobrien    }
509090075Sobrien  if (TREE_CODE (name) == TYPE_DECL || TREE_CODE (name) == TEMPLATE_DECL)
509150397Sobrien    name = DECL_NAME (name);
509250397Sobrien
509350397Sobrien  my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716);
509450397Sobrien
509590075Sobrien  value = build_lang_decl (USING_DECL, name, void_type_node);
509650397Sobrien  DECL_INITIAL (value) = TREE_OPERAND (decl, 0);
509750397Sobrien  return value;
509818334Speter}
509918334Speter
510050397Sobrien/* Process a using-directive. */
510150397Sobrien
510218334Spetervoid
510318334Speterdo_using_directive (namespace)
510418334Speter     tree namespace;
510518334Speter{
510690075Sobrien  if (building_stmt_tree ())
510790075Sobrien    add_stmt (build_stmt (USING_STMT, namespace));
510890075Sobrien
510950397Sobrien  /* using namespace A::B::C; */
511050397Sobrien  if (TREE_CODE (namespace) == SCOPE_REF)
511150397Sobrien      namespace = TREE_OPERAND (namespace, 1);
511250397Sobrien  if (TREE_CODE (namespace) == IDENTIFIER_NODE)
511350397Sobrien    {
511450397Sobrien      /* Lookup in lexer did not find a namespace. */
511590075Sobrien      if (!processing_template_decl)
511690075Sobrien	error ("namespace `%T' undeclared", namespace);
511750397Sobrien      return;
511850397Sobrien    }
511950397Sobrien  if (TREE_CODE (namespace) != NAMESPACE_DECL)
512050397Sobrien    {
512190075Sobrien      if (!processing_template_decl)
512290075Sobrien	error ("`%T' is not a namespace", namespace);
512350397Sobrien      return;
512450397Sobrien    }
512550397Sobrien  namespace = ORIGINAL_NAMESPACE (namespace);
512650397Sobrien  if (!toplevel_bindings_p ())
512750397Sobrien    push_using_directive (namespace);
512850397Sobrien  else
512950397Sobrien    /* direct usage */
513050397Sobrien    add_using_namespace (current_namespace, namespace, 0);
513118334Speter}
513218334Speter
513318334Spetervoid
513418334Spetercheck_default_args (x)
513518334Speter     tree x;
513618334Speter{
513718334Speter  tree arg = TYPE_ARG_TYPES (TREE_TYPE (x));
513818334Speter  int saw_def = 0, i = 0 - (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE);
513918334Speter  for (; arg && arg != void_list_node; arg = TREE_CHAIN (arg), ++i)
514018334Speter    {
514118334Speter      if (TREE_PURPOSE (arg))
514218334Speter	saw_def = 1;
514318334Speter      else if (saw_def)
514418334Speter	{
514550397Sobrien	  cp_error_at ("default argument missing for parameter %P of `%+#D'",
514650397Sobrien		       i, x);
514718334Speter	  break;
514818334Speter	}
514918334Speter    }
515018334Speter}
515150397Sobrien
515250397Sobrienvoid
515350397Sobrienmark_used (decl)
515450397Sobrien     tree decl;
515550397Sobrien{
515650397Sobrien  TREE_USED (decl) = 1;
515750397Sobrien  if (processing_template_decl)
515850397Sobrien    return;
515950397Sobrien  assemble_external (decl);
516052284Sobrien
516150397Sobrien  /* Is it a synthesized method that needs to be synthesized?  */
516290075Sobrien  if (TREE_CODE (decl) == FUNCTION_DECL
516390075Sobrien      && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
516490075Sobrien      && DECL_ARTIFICIAL (decl)
516590075Sobrien      && ! DECL_INITIAL (decl)
516650397Sobrien      /* Kludge: don't synthesize for default args.  */
516750397Sobrien      && current_function_decl)
516890075Sobrien    {
516990075Sobrien      synthesize_method (decl);
517090075Sobrien      /* If we've already synthesized the method we don't need to
517190075Sobrien	 instantiate it, so we can return right away.  */
517290075Sobrien      return;
517390075Sobrien    }
517452284Sobrien
517552284Sobrien  /* If this is a function or variable that is an instance of some
517652284Sobrien     template, we now know that we will need to actually do the
517790075Sobrien     instantiation. We check that DECL is not an explicit
517852284Sobrien     instantiation because that is not checked in instantiate_decl.  */
517990075Sobrien  if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL)
518052284Sobrien      && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
518190075Sobrien      && (!DECL_EXPLICIT_INSTANTIATION (decl)
518290075Sobrien	  || (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))))
518390075Sobrien    instantiate_decl (decl, /*defer_ok=*/1);
518450397Sobrien}
518550397Sobrien
518690075Sobrien/* Helper function for class_head_decl and class_head_defn
518790075Sobrien   nonterminals. AGGR is the class, union or struct tag. SCOPE is the
518890075Sobrien   explicit scope used (NULL for no scope resolution). ID is the
518990075Sobrien   name. DEFN_P is true, if this is a definition of the class and
519090075Sobrien   NEW_TYPE_P is set to non-zero, if we push into the scope containing
519190075Sobrien   the to be defined aggregate.
519290075Sobrien
519390075Sobrien   Return a TYPE_DECL for the type declared by ID in SCOPE.  */
519450397Sobrien
519550397Sobrientree
519690075Sobrienhandle_class_head (aggr, scope, id, defn_p, new_type_p)
519750397Sobrien     tree aggr, scope, id;
519890075Sobrien     int defn_p;
519990075Sobrien     int *new_type_p;
520050397Sobrien{
520190075Sobrien  tree decl = NULL_TREE;
520290075Sobrien  tree current = current_scope ();
520390075Sobrien  bool xrefd_p = false;
520490075Sobrien
520590075Sobrien  if (current == NULL_TREE)
520690075Sobrien    current = current_namespace;
520752284Sobrien
520890075Sobrien  *new_type_p = 0;
520990075Sobrien
521090075Sobrien  if (scope)
521152284Sobrien    {
521290075Sobrien      if (TREE_CODE (id) == TYPE_DECL)
521390075Sobrien	/* We must bash typedefs back to the main decl of the
521490075Sobrien       	   type. Otherwise we become confused about scopes.  */
521590075Sobrien	decl = TYPE_MAIN_DECL (TREE_TYPE (id));
521690075Sobrien      else if (DECL_CLASS_TEMPLATE_P (id))
521790075Sobrien	decl = DECL_TEMPLATE_RESULT (id);
521852284Sobrien      else
521990075Sobrien	{
522090075Sobrien	  if (TYPE_P (scope))
522190075Sobrien	    {
522290075Sobrien	      /* According to the suggested resolution of core issue
522390075Sobrien	     	 180, 'typename' is assumed after a class-key.  */
522490075Sobrien	      decl = make_typename_type (scope, id, 1);
522590075Sobrien	      if (decl != error_mark_node)
522690075Sobrien		decl = TYPE_MAIN_DECL (decl);
522790075Sobrien	      else
522890075Sobrien		decl = NULL_TREE;
522990075Sobrien	    }
523090075Sobrien	  else if (scope == current)
523190075Sobrien	    {
523290075Sobrien	      /* We've been given AGGR SCOPE::ID, when we're already
523390075Sobrien             	 inside SCOPE.  Be nice about it.  */
523490075Sobrien	      if (pedantic)
523590075Sobrien		pedwarn ("extra qualification `%T::' on member `%D' ignored",
523690075Sobrien			 scope, id);
523790075Sobrien	    }
523890075Sobrien	  else
523990075Sobrien	    error ("`%T' does not have a class or union named `%D'",
524090075Sobrien		   scope, id);
524190075Sobrien	}
524252284Sobrien    }
524390075Sobrien
524490075Sobrien  if (!decl)
524590075Sobrien    {
524690075Sobrien      decl = TYPE_MAIN_DECL (xref_tag (aggr, id, !defn_p));
524790075Sobrien      xrefd_p = true;
524890075Sobrien    }
524950397Sobrien
525090075Sobrien  if (!TYPE_BINFO (TREE_TYPE (decl)))
525190075Sobrien    {
525290075Sobrien      error ("`%T' is not a class or union type", decl);
525390075Sobrien      return error_mark_node;
525490075Sobrien    }
525590075Sobrien
525690075Sobrien  if (defn_p)
525790075Sobrien    {
525890075Sobrien      /* For a definition, we want to enter the containing scope
525990075Sobrien	 before looking up any base classes etc. Only do so, if this
526090075Sobrien	 is different to the current scope.  */
526190075Sobrien      tree context = CP_DECL_CONTEXT (decl);
526250397Sobrien
526390075Sobrien      *new_type_p = current != context;
526490075Sobrien      if (*new_type_p)
526590075Sobrien	push_scope (context);
526690075Sobrien
526790075Sobrien      if (!xrefd_p && PROCESSING_REAL_TEMPLATE_DECL_P ())
526890075Sobrien	decl = push_template_decl (decl);
526990075Sobrien    }
527052284Sobrien
527152284Sobrien  return decl;
527250397Sobrien}
527390075Sobrien
527490075Sobrien/* Initialize decl2.c.  */
527590075Sobrien
527690075Sobrienvoid
527790075Sobrieninit_decl2 ()
527890075Sobrien{
527990075Sobrien  ggc_add_tree_varray_root (&deferred_fns, 1);
528090075Sobrien  ggc_add_tree_varray_root (&pending_statics, 1);
528190075Sobrien  ggc_add_tree_varray_root (&ssdf_decls, 1);
528290075Sobrien  ggc_add_tree_root (&ssdf_decl, 1);
528390075Sobrien  ggc_add_tree_root (&priority_decl, 1);
528490075Sobrien  ggc_add_tree_root (&initialize_p_decl, 1);
528590075Sobrien}
5286